[英]C - how to get fscanf() to determine whether what it read is only digits, and no characters
假設我有一個csv,每個值都是一個整數。 所以第一個值是INTEGER 100
。
我想讓fscanf()讀取這一行,並告訴我它僅是整數,還是不是。 因此,它將超過100
但在100t
失敗。 我一直在努力工作的是“%d”,其中逗號是我的CSV的分隔符。 所以整個功能是
fscanf(fp, "%d,", &count)
不幸的是,這不能在'100t'上失敗,在'100'上有效,在't'上有效。 因此,它只是不能區分100
100t
和100
100t
(當然,所有這些數字后面都帶有逗號
請改用strtol
。
你不知道
問題是fscanf()
不太有用。 處理它的最佳方法是讀入整行(或該行的重要部分),然后分析字符串。 這是一個例子:
int value;
char *extra;
char buffer[100];
// read in some data from the buffer
fgets(buffer, sizeof buffer, stdin);
// parse out a digit, if we can
i = strtol(buffer, &extra, 0);
在這一點上,你可以檢查extra
,看看是否有任何額外的字符,這意味着該行不單純是一個數字,或者如果extra
點的開始buffer
,這意味着沒有號碼解析。
fscanf實際上比其他答案暗示的要有用得多-但是大多數人並不十分了解它,也不知道如何行使其全部功能。
有用的要點:首先,使用fscanf的返回值-它告訴您轉換了多少個項目。 其次,“掃描集”轉換可能非常有用。 請考慮以下內容(我使用sscanf
來避免需要外部文件,但fscanf
僅在其讀取源方面有所不同):
#include <stdio.h>
int main() {
int i;
char *test[] = {
"100,", // should succeed.
"100t,", // should fail.
"t" // should also fail.
};
for (i=0; i<3; i++) {
int count;
char ch[2];
if (2 == sscanf(test[i], "%d%[,]", &count, &ch))
fprintf(stderr, "Conversion of \"%s\" succeeded.\n", test[i]);
else
fprintf(stderr, "Conversion of \"%s\" failed.\n", test[i]);
}
return 0;
}
關於什么
fscanf(fp, "%d%c", &count, &aChar)
如果aChar!=','&&!='\\ n'那么您就沒有整數
不受100%控制的輸入上的scanf-functions可能很難獲得無錯誤,最好使用fgets()讀取行,然后使用strtok()將行拆分為令牌,然后可以將其轉換。
在一個像“ 100t”這樣的令牌上使用atoi將產生0,而“ 100”將產生100
scanf()
系列函數不太善於檢測這種錯誤。 這不是不可能的(請參閱傑里·科芬的答案,該方法雖然有效,但IMO難以一概而論),但IMO並不是那么強大。 更好的選擇是使用fgets()
以文本形式讀取輸入,使用strtok()
或類似符號進行標記化,然后使用strtol()
或strtod()
將標記轉換為數值:
char buffer[LINE_SIZE];
while (fgets(buffer, sizeof buffer, inFile))
{
char *token;
char *newline = strchr(buffer, '\n');
if (newline)
*newline = 0;
token = strtok(buffer, ",");
while (token)
{
char *chk;
int value = (int) strtol(token, &chk, 10);
if (!isspace(*chk) && *chk != 0)
{
printf("%s is not a valid integer\n", token);
}
else
{
printf("successfully read integer value %d\n", val);
}
token = strtok(NULL, ",");
}
}
if (feof(inFile))
{
printf("Hit end-of-file\n");
}
else
{
printf("Error during read\n");
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.