使用 fscanf 和 fgetc 读取文本行
Reading text lines with fscanf and fgetc
就这么一个小问题就犯了难。我正在尝试从文件中读取文本。该文件的格式为:
Jim 3 X Y Z
James 2 A B
Alley 5 D E F G H
其中整数表示后面的变量个数。
我正在使用 fscanf 读取名称和编号,然后使用 fgetc 读取 char 变量,这样我就可以将它们放入一个数组中。 fscanf 部分工作正常,但我在 fgetc 中遗漏了一些东西。
do {
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
while (c!= '\n') {
c = fgetc(inputFile);
printf("char is:%c ", c);
}
}while (c != EOF);
这将进入无限循环。所以我试着告诉 fgetc 什么时候停止。
while (c != EOF){
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
printf("%d ", inputSize);
printf("\n");
for (i =0;i<(inputSize*2);i++) {
c = fgetc(inputFile) ;
if (c== ' ') {
}
else {
printf("char is :%c ", c);
printf("\n");
}
}
输出变为:
Jim 3
char is :X
char is :Y
char is :Z
James 2
char is :A
char is :B
Alley 5
char is :D
char is :E
char is :F
char is :G
char is :H
Alley 5
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
我搞砸了 fgetc 的哪一部分?另外,为什么 fgetc 在我的第一个例子中没有看到 '\n',而是无限循环?
谢谢
在原始代码中,你有:
char c; // Per comments
do {
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
while (c!= '\n') {
c = fgetc(inputFile);
printf("char is:%c ", c);
}
} while (c != EOF);
在您阅读 Alley
数据后的换行符之前,此代码可以正常工作。然后你回到循环的顶部,用 fscanf()
读取一些数据。由于没有数据,fscanf()
returns EOF,但是你继续打印之前在 word
和 inputSize
中的内容。然后你进入一个无限循环,因为 fgetc()
returns EOF,它不是 \n
,所以你一次又一次地尝试,然后......
修复:
fgetc()
return 是 int
,而不是 char
。在普通 char
是有符号类型的系统上,这意味着您将有效字符(通常是 ÿ、U+00FF、带分音符的拉丁文小写字母 Y)误认为是 EOF。在普通 char
是无符号类型的系统上,没有任何内容与 EOF 匹配。这两种行为都不正确。
- 测试 EOF 或换行符;一直想着。
- 测试
fscanf()
中的 return;如果不是 2,则说明出错了。
而且我会使用顶部检查 while
循环而不是底部检查 do … while
循环。有时会出现 do … while
循环;在我看来,这不是其中之一。
修改后的代码分析类似。您的代码是:
char c = 0;
while (c != EOF){
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
printf("%d ", inputSize);
printf("\n");
for (i =0;i<(inputSize*2);i++) {
c = fgetc(inputFile) ;
if (c== ' ') {
}
else {
printf("char is :%c ", c);
printf("\n");
}
}
}
同样,您需要检查由 fscanf()
编辑的值 return,如果它不是 2,则退出循环。前三个 printf()
调用可以组合成一。
在你第一次读取Alley
的数据后,fscanf()
returns EOF,但你忽略了它并再次打印数据。然后你进入 fgetc()
循环,它将 EOF 映射到 ÿ (0xFF) 但这不是空白,所以你打印它(就其本身而言,0xFF 不是 UTF-8 中的有效字节,这可能占打印的问号)。当您完成 10 次迭代后,c
包含一个扩展到 EOF 的代码,因此循环终止。
修复:
- 与之前大致相同。
- 使用
int char;
- 在继续之前检查
fscanf()
中的 return。
- 检查
fgetc()
循环中的所需字符或 EOF。
原始代码的可能修复:
int c;
while (fscanf(inputFile, "%s%d", word, &inputSize) == 2)
{
printf("%s (%d)\n", word, inputSize);
while ((c = getc(inputFile)) != EOF && c != '\n')
{
if (c != ' ')
printf("char is: %c\n", c);
}
}
就这么一个小问题就犯了难。我正在尝试从文件中读取文本。该文件的格式为:
Jim 3 X Y Z
James 2 A B
Alley 5 D E F G H
其中整数表示后面的变量个数。 我正在使用 fscanf 读取名称和编号,然后使用 fgetc 读取 char 变量,这样我就可以将它们放入一个数组中。 fscanf 部分工作正常,但我在 fgetc 中遗漏了一些东西。
do {
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
while (c!= '\n') {
c = fgetc(inputFile);
printf("char is:%c ", c);
}
}while (c != EOF);
这将进入无限循环。所以我试着告诉 fgetc 什么时候停止。
while (c != EOF){
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
printf("%d ", inputSize);
printf("\n");
for (i =0;i<(inputSize*2);i++) {
c = fgetc(inputFile) ;
if (c== ' ') {
}
else {
printf("char is :%c ", c);
printf("\n");
}
}
输出变为:
Jim 3
char is :X
char is :Y
char is :Z
James 2
char is :A
char is :B
Alley 5
char is :D
char is :E
char is :F
char is :G
char is :H
Alley 5
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
char is :?
我搞砸了 fgetc 的哪一部分?另外,为什么 fgetc 在我的第一个例子中没有看到 '\n',而是无限循环?
谢谢
在原始代码中,你有:
char c; // Per comments
do {
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
while (c!= '\n') {
c = fgetc(inputFile);
printf("char is:%c ", c);
}
} while (c != EOF);
在您阅读 Alley
数据后的换行符之前,此代码可以正常工作。然后你回到循环的顶部,用 fscanf()
读取一些数据。由于没有数据,fscanf()
returns EOF,但是你继续打印之前在 word
和 inputSize
中的内容。然后你进入一个无限循环,因为 fgetc()
returns EOF,它不是 \n
,所以你一次又一次地尝试,然后......
修复:
fgetc()
return 是int
,而不是char
。在普通char
是有符号类型的系统上,这意味着您将有效字符(通常是 ÿ、U+00FF、带分音符的拉丁文小写字母 Y)误认为是 EOF。在普通char
是无符号类型的系统上,没有任何内容与 EOF 匹配。这两种行为都不正确。- 测试 EOF 或换行符;一直想着。
- 测试
fscanf()
中的 return;如果不是 2,则说明出错了。
而且我会使用顶部检查 while
循环而不是底部检查 do … while
循环。有时会出现 do … while
循环;在我看来,这不是其中之一。
修改后的代码分析类似。您的代码是:
char c = 0;
while (c != EOF){
c = fscanf(inputFile, "%s" "%d", word, &inputSize);
printf("%s ", word);
printf("%d ", inputSize);
printf("\n");
for (i =0;i<(inputSize*2);i++) {
c = fgetc(inputFile) ;
if (c== ' ') {
}
else {
printf("char is :%c ", c);
printf("\n");
}
}
}
同样,您需要检查由 fscanf()
编辑的值 return,如果它不是 2,则退出循环。前三个 printf()
调用可以组合成一。
在你第一次读取Alley
的数据后,fscanf()
returns EOF,但你忽略了它并再次打印数据。然后你进入 fgetc()
循环,它将 EOF 映射到 ÿ (0xFF) 但这不是空白,所以你打印它(就其本身而言,0xFF 不是 UTF-8 中的有效字节,这可能占打印的问号)。当您完成 10 次迭代后,c
包含一个扩展到 EOF 的代码,因此循环终止。
修复:
- 与之前大致相同。
- 使用
int char;
- 在继续之前检查
fscanf()
中的 return。 - 检查
fgetc()
循环中的所需字符或 EOF。
原始代码的可能修复:
int c;
while (fscanf(inputFile, "%s%d", word, &inputSize) == 2)
{
printf("%s (%d)\n", word, inputSize);
while ((c = getc(inputFile)) != EOF && c != '\n')
{
if (c != ' ')
printf("char is: %c\n", c);
}
}