stdio.h fscanf 格式说明符
stdio.h fscanf format specifiers
我的文件将包含两个数字,中间有可变空格,或者只包含一个空行。我需要知道什么时候输入只是一个空行,然后不使用 fscanf.
分配给那些变量
正在做:
FILE *pFile = fopen (my_file, "r");
if (pFile == NULL) perror ("Error opening file");
int succ = 1, num1 = 0, num2 = 0;
while (succ != EOF)
{
succ = fscanf(pFile, "%d %d", &num1, &num2);
}
非常适合正确检测所有数字,但不能检测换行符。
我试过了:
fscanf(pFile, "%d %d %*[^\n]", &num1, &num2);
但它总是正确地分配给两个数字。我希望能够根据 succ 是 2(表示也分配了两个数字)还是 0(表示空行)来创建 switch 语句来执行其他逻辑。
如果可能,我宁愿避免使用 getline;似乎将 iostream 的东西与 stdio 函数混合使用效率很低。
我尝试了 this guys suggestion,没有成功,虽然从逻辑上我认为它会成功,但没有成功。
老实说,我什至不明白为什么
"%d %d \n"
不行。很简单...扫描文件直到换行,return 返回完成了多少作业,就是这样!
"%d %d \n"
将无法实现 OP 目标,因为任何 white-space 指令都会消耗任何 white-space。使用 ' '
或 '\n'
没有区别,它们都消耗 0 个或更多的 white-spaces。 (预计在 '[]'
说明符中)
OP 想要检测 '\n'
和 fscanf()
不是一个好的选择。 fgets()
更好。
#define N (100 /* longest line */)
char buf[N];
while (fgets(buf, sizeof buf, pFile) != NULL) {
int cnt = sscanf("%d%d",&num1, &num2);
switch (cnt) {
case 0: Handle_NoNumbers(); break;
case 1: Handle_1Number(); break;
case 2: Handle_Success(); break;
}
}
fscanf(stream, "%d", &num)
中的'%d'
指定在数字前消耗所有前导白色-space而不考虑'\n'
或' '
等
如果代码必须使用fscanf()
,那么代码需要在调用fscanf(... "%d")
之前消耗前导白色-space以区分'\n'
来自 ' '
.
// Consume white space except \n and EOF
int consume_ws(FILE *pFile) {
do {
int c = fgetc(pFile); // could use fscanf(...%c...) here
if (c == '\n' || c == EOF) return c;
} while (isspace(c));
ungetc(c, pFile); // put the char back
return 0;
}
...
while(1) {
int num[2];
int i;
for (i = 0; i < 2; i++) {
if (consume_ws(pFile)) {
Handle_ScantData(); // Not enough data
return;
}
if (1 != fscanf(pFile, "%d", &num[i]) {
Handle_NonnumericData();
return;
}
}
int ch = consume_ws(pFile);
if (ch == 0) Handle_ExtraData();
// Else do something with the 2 numbers
if (ch == EOF) return;
}
我的文件将包含两个数字,中间有可变空格,或者只包含一个空行。我需要知道什么时候输入只是一个空行,然后不使用 fscanf.
分配给那些变量正在做:
FILE *pFile = fopen (my_file, "r");
if (pFile == NULL) perror ("Error opening file");
int succ = 1, num1 = 0, num2 = 0;
while (succ != EOF)
{
succ = fscanf(pFile, "%d %d", &num1, &num2);
}
非常适合正确检测所有数字,但不能检测换行符。 我试过了:
fscanf(pFile, "%d %d %*[^\n]", &num1, &num2);
但它总是正确地分配给两个数字。我希望能够根据 succ 是 2(表示也分配了两个数字)还是 0(表示空行)来创建 switch 语句来执行其他逻辑。
如果可能,我宁愿避免使用 getline;似乎将 iostream 的东西与 stdio 函数混合使用效率很低。
我尝试了 this guys suggestion,没有成功,虽然从逻辑上我认为它会成功,但没有成功。
老实说,我什至不明白为什么
"%d %d \n"
不行。很简单...扫描文件直到换行,return 返回完成了多少作业,就是这样!
"%d %d \n"
将无法实现 OP 目标,因为任何 white-space 指令都会消耗任何 white-space。使用 ' '
或 '\n'
没有区别,它们都消耗 0 个或更多的 white-spaces。 (预计在 '[]'
说明符中)
OP 想要检测 '\n'
和 fscanf()
不是一个好的选择。 fgets()
更好。
#define N (100 /* longest line */)
char buf[N];
while (fgets(buf, sizeof buf, pFile) != NULL) {
int cnt = sscanf("%d%d",&num1, &num2);
switch (cnt) {
case 0: Handle_NoNumbers(); break;
case 1: Handle_1Number(); break;
case 2: Handle_Success(); break;
}
}
fscanf(stream, "%d", &num)
中的'%d'
指定在数字前消耗所有前导白色-space而不考虑'\n'
或' '
等
如果代码必须使用fscanf()
,那么代码需要在调用fscanf(... "%d")
之前消耗前导白色-space以区分'\n'
来自 ' '
.
// Consume white space except \n and EOF
int consume_ws(FILE *pFile) {
do {
int c = fgetc(pFile); // could use fscanf(...%c...) here
if (c == '\n' || c == EOF) return c;
} while (isspace(c));
ungetc(c, pFile); // put the char back
return 0;
}
...
while(1) {
int num[2];
int i;
for (i = 0; i < 2; i++) {
if (consume_ws(pFile)) {
Handle_ScantData(); // Not enough data
return;
}
if (1 != fscanf(pFile, "%d", &num[i]) {
Handle_NonnumericData();
return;
}
}
int ch = consume_ws(pFile);
if (ch == 0) Handle_ExtraData();
// Else do something with the 2 numbers
if (ch == EOF) return;
}