我目前正在学习读取C中的文件。 无论如何,切入追逐:
文字文件内容:
123456 James Doakes; 0
987987 Dexter Morgan; 0
010203 Masuka Perv; 0
int main()
{
char accountNr[ACCOUNTNRSIZE], ownerName[NAMESIZE], enter[3];
int accountBalance = 0;
char filename[] = "breg.txt";
FILE *file = fopen(filename, "r");
if (file != NULL) {
char line[128];
while (fgets(line, sizeof(line), file) != NULL) {
sscanf(line, "%s %[^;] %d ", accountNr, ownerName, &accountBalance);
printf("%s", ownerName);
//fflushstdin();
}
fclose(file);
} else {
perror(filename);
}
return 0;
}
我写这篇文章是为了检查James Doakes的名称是否正确注册:
printf("%s", ownerName);
但是当它打印出来时就像stdout仍然处于活动状态,我可以按Enter键,它会再次输入名称。我的目标当然是能够将数字,全名和最后一个数字作为单独的变量进行扫描。但它显然不起作用。我猜是一个\ n也被注册了。不知道,我只是在猜测。
我做错了什么?为什么?我该如何解决这个问题?
非常感谢, 米夫
答案 0 :(得分:3)
%s %[^;] %d
表示以空格,可选空格,不是;
的字符序列,可选空格,然后是数字终止的字符串。
您似乎没有扫描实际的;
字符本身,因此,当您尝试获取数字时,输入流中的;
将导致它失败。您可以通过以下方式看到:
#include <stdio.h>
#define ACCOUNTNRSIZE 100
#define NAMESIZE 100
int main (void) {
char accountNr[ACCOUNTNRSIZE], ownerName[NAMESIZE], enter[3];
int accountBalance = 0;
char filename[] = "breg.txt";
FILE *file = fopen(filename, "r");
if (file != NULL) {
char line[128];
while (fgets(line, sizeof(line), file) != NULL) {
int count = sscanf(line, "%s %[^;] %d ", accountNr, ownerName, &accountBalance);
printf ("%d [%s] [%s] [%d]\n", count, accountNr, ownerName, accountBalance);
}
fclose(file);
} else {
perror(filename);
}
return 0;
}
输出:
2 [123456] [James Doakes] [0]
2 [987987] [Dexter Morgan] [0]
2 [010203] [Masuka Perv] [0]
实际上,即使您将breg.txt
文件更改为:
123456 James Doakes; 314159
987987 Dexter Morgan; 271828
010203 Masuka Perv; 42
您仍然可以获得0
帐户余额,因为扫描只能成功读取两个项目。
每当使用其中一个scanf
- 系列函数时,您应该检查返回代码以确保它扫描正确数量的项目,如:
int count = sscanf (line, "%s %[^;] %d ", accountNr, ownerName, &accountBalance);
if (count != 3) {
fprintf (stderr, "Catostrophic failure, count is %d\n", count);
return 1;
}
此处的修复相对简单,只需使用%s %[^;]; %d
作为格式字符串。
通过该更改,您看到的输出是:
3 [123456] [James Doakes] [314159]
3 [987987] [Dexter Morgan] [271828]
3 [010203] [Masuka Perv] [42]
请记住,%d
之前实际上并没有需要空格(尽管它不会造成伤害)。在尝试扫描数字之前,该特定格式说明符会跳过空格。