fscanf 打印未知值
fscanf printing unknown values
我正在尝试使用 fscanf 获取文本文件并以相同的格式简单地打印它(最终它将用于填充结构数组)。
当我使用 fscanf 时,它会打印一些不属于文本的值,我不确定它们来自哪里。我在代码部分下面放了一小部分输入文本文件和输出。
我想在页面上水平打印的值都在输出的第一列中,这让我觉得这与我定义 fprint 语句的方式有关?第一列中的每个正确值后面都有我不知道从哪里来的值。
如有任何帮助,我们将不胜感激。
#include <stdlib.h>
int count_lines(char file[]) {
FILE* f = fopen(file, "r"); /* declaration of file pointer */
char x;
int c = 0; /* declaration of variable */
f = fopen(file, "r");
if (f == NULL) {
printf("Cannot open file for reading");
return -1;
}
while ((x = fgetc(f)) != EOF) {
if (x == '\n') {
c = c + 1;
}
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
return -1;
}
printf("Number of lines = %d\n", c);
return c;
}
struct votes {
char state[100]; /* state name */
long dempv; /* democrats popular votes */
long demev; /* democrats electoral votes */
long reppv; /* republicans popular votes */
long repev; /* republicans electoral votes */
};
void initialise_votes(char file[], struct votes* arr, int nlines) {
FILE* f = fopen(file, "r");
char temp1[20];
long temp2;
long temp3;
long temp4;
long temp5;
if (f == NULL) {
printf("Cannot open file for reading\n");
}
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
printf("%s\t%ld\t%ld\t%ld\t%ld\n", temp1, temp2, temp3, temp4, temp5);
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
}
}
int main(void) {
char s_in[] = "uselection2012.txt"; /* input data file */
int nlines;
struct votes* arr;
nlines = count_lines(s_in);
arr = (struct votes*)malloc(sizeof(struct votes) * nlines);
initialise_votes(s_in, arr, nlines);
return 0;
}
输入文件:
Alabama 795696 0 1255925 9
Alaska 122640 0 164676 3
Arizona 1025232 0 1233654 11
Arkansas 394409 0 647744 6
California 7854285 55 4839958 0
输出:
Alabama 6356696 -37862896 6380 0
795696 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1255925 6356696 -37862896 6380 0
9 6356696 -37862896 6380 0
Alaska 6356696 -37862896 6380 0
122640 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
164676 6356696 -37862896 6380 0
3 6356696 -37862896 6380 0
Arizona 6356696 -37862896 6380 0
1025232 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1233654 6356696 -37862896 6380 0
11 6356696 -37862896 6380 0
Arkansas 6356696 -37862896 6380 0
394409 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
647744 6356696 -37862896 6380 0
6 6356696 -37862896 6380 0
California 6356696 -37862896 6380 0
7854285 6356696 -37862896 6380 0
55 6356696 -37862896 6380 0
4839958 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
您的 scanf 格式字符串包含逗号,但您的输入数据不包含逗号。
请注意,fscanf
returns 要么是 EOF,要么是成功扫描的值的数量。您可以而且应该使用该 return 值来检查错误,这样做会指出您代码中的问题。
fscanf
格式字符串中的逗号告诉 fscanf
期待文件中有逗号,如果找不到则停止。
您的文件中没有逗号,因此 fscanf
在读取用于 %s
转换的“字符串”后停止。
从格式字符串中删除逗号。
测试 fscanf
的 return 值是否等于您期望分配的项目数,而不仅仅是它不等于 EOF
.
可避免的编码弱点导致 OP 的难度
如果代码根据预期结果 5 检查 return 值,而不是检查 EOF, 0, 1, 2, 3, 4
等众多不正确结果之一,问题将很快缩小为 scanf 失败。
// while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
其他问题
白-space
没有价值,除了可能的风格,在 "%ld"
之前放置 " "
因为 "%ld"
已经消耗了可选的前导白色-space.
然而,在 ","
之前放置一个 space 是有价值的,以允许在 ','
.
之前输入可选的前导白色-space
while (fscanf(f, "%s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
缓冲区溢出
切勿在 (f)scanf()
函数中使用 "%s"
。使用 宽度 限制,否则有缓冲区溢出的风险。
// width --------vv
while (fscanf(f, "%19s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
fgetc()
return一个int
fgetc(f)
returns 257 个不同的值。使用一个int
来正确区分。
// char x;
int x;
...
while ((x = fgetc(f)) != EOF) {
行数可能会失败
Count of lines 只计算了 '\n'
的行数。如果文件只包含 "abc 1 2 3 4"
,没有 '\n'
,行数将报告为 0.
而是计算行首的数量。
count = 0;
int prior = '\n';
while ((x = fgetc(f)) != EOF) {
if (prior == '\n') {
count++;
}
prior = x;
...
}
我正在尝试使用 fscanf 获取文本文件并以相同的格式简单地打印它(最终它将用于填充结构数组)。
当我使用 fscanf 时,它会打印一些不属于文本的值,我不确定它们来自哪里。我在代码部分下面放了一小部分输入文本文件和输出。
我想在页面上水平打印的值都在输出的第一列中,这让我觉得这与我定义 fprint 语句的方式有关?第一列中的每个正确值后面都有我不知道从哪里来的值。
如有任何帮助,我们将不胜感激。
#include <stdlib.h>
int count_lines(char file[]) {
FILE* f = fopen(file, "r"); /* declaration of file pointer */
char x;
int c = 0; /* declaration of variable */
f = fopen(file, "r");
if (f == NULL) {
printf("Cannot open file for reading");
return -1;
}
while ((x = fgetc(f)) != EOF) {
if (x == '\n') {
c = c + 1;
}
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
return -1;
}
printf("Number of lines = %d\n", c);
return c;
}
struct votes {
char state[100]; /* state name */
long dempv; /* democrats popular votes */
long demev; /* democrats electoral votes */
long reppv; /* republicans popular votes */
long repev; /* republicans electoral votes */
};
void initialise_votes(char file[], struct votes* arr, int nlines) {
FILE* f = fopen(file, "r");
char temp1[20];
long temp2;
long temp3;
long temp4;
long temp5;
if (f == NULL) {
printf("Cannot open file for reading\n");
}
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
printf("%s\t%ld\t%ld\t%ld\t%ld\n", temp1, temp2, temp3, temp4, temp5);
}
if (fclose(f) != 0) {
printf("File could not be closed.\n");
}
}
int main(void) {
char s_in[] = "uselection2012.txt"; /* input data file */
int nlines;
struct votes* arr;
nlines = count_lines(s_in);
arr = (struct votes*)malloc(sizeof(struct votes) * nlines);
initialise_votes(s_in, arr, nlines);
return 0;
}
输入文件:
Alabama 795696 0 1255925 9
Alaska 122640 0 164676 3
Arizona 1025232 0 1233654 11
Arkansas 394409 0 647744 6
California 7854285 55 4839958 0
输出:
Alabama 6356696 -37862896 6380 0
795696 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1255925 6356696 -37862896 6380 0
9 6356696 -37862896 6380 0
Alaska 6356696 -37862896 6380 0
122640 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
164676 6356696 -37862896 6380 0
3 6356696 -37862896 6380 0
Arizona 6356696 -37862896 6380 0
1025232 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
1233654 6356696 -37862896 6380 0
11 6356696 -37862896 6380 0
Arkansas 6356696 -37862896 6380 0
394409 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
647744 6356696 -37862896 6380 0
6 6356696 -37862896 6380 0
California 6356696 -37862896 6380 0
7854285 6356696 -37862896 6380 0
55 6356696 -37862896 6380 0
4839958 6356696 -37862896 6380 0
0 6356696 -37862896 6380 0
您的 scanf 格式字符串包含逗号,但您的输入数据不包含逗号。
请注意,fscanf
returns 要么是 EOF,要么是成功扫描的值的数量。您可以而且应该使用该 return 值来检查错误,这样做会指出您代码中的问题。
fscanf
格式字符串中的逗号告诉 fscanf
期待文件中有逗号,如果找不到则停止。
您的文件中没有逗号,因此 fscanf
在读取用于 %s
转换的“字符串”后停止。
从格式字符串中删除逗号。
测试 fscanf
的 return 值是否等于您期望分配的项目数,而不仅仅是它不等于 EOF
.
可避免的编码弱点导致 OP 的难度
如果代码根据预期结果 5 检查 return 值,而不是检查 EOF, 0, 1, 2, 3, 4
等众多不正确结果之一,问题将很快缩小为 scanf 失败。
// while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) != EOF) {
while (fscanf(f, "%s, %ld, %ld, %ld, %ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
其他问题
白-space
没有价值,除了可能的风格,在 "%ld"
之前放置 " "
因为 "%ld"
已经消耗了可选的前导白色-space.
然而,在 ","
之前放置一个 space 是有价值的,以允许在 ','
.
while (fscanf(f, "%s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
缓冲区溢出
切勿在 (f)scanf()
函数中使用 "%s"
。使用 宽度 限制,否则有缓冲区溢出的风险。
// width --------vv
while (fscanf(f, "%19s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
fgetc()
return一个int
fgetc(f)
returns 257 个不同的值。使用一个int
来正确区分。
// char x;
int x;
...
while ((x = fgetc(f)) != EOF) {
行数可能会失败
Count of lines 只计算了 '\n'
的行数。如果文件只包含 "abc 1 2 3 4"
,没有 '\n'
,行数将报告为 0.
而是计算行首的数量。
count = 0;
int prior = '\n';
while ((x = fgetc(f)) != EOF) {
if (prior == '\n') {
count++;
}
prior = x;
...
}