[英]fscanf printing unknown values
我正在尝试使用 fscanf 获取一个文本文件并以相同的格式简单地打印它(最终它将用于填充结构数组)。
当我使用 fscanf 时,它会打印一些不属于文本的值,我不确定它们来自哪里。 我已将一小部分输入文本文件和 output 放在代码部分下方。
我想在页面上水平打印的值都在 output 的第一列,这让我觉得这与我如何定义我的 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
Output:
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
返回 EOF 或成功扫描的值的数量。 您可以并且应该使用该返回值来检查错误,这样做会指出您代码中的问题。
fscanf
格式字符串中的逗号告诉fscanf
期望文件中有逗号,如果找不到它们就停止。
您的文件中没有逗号,因此fscanf
在读取%s
转换的“字符串”后停止。
从格式字符串中删除逗号。
测试fscanf
的返回值是否等于您希望分配的项目数,而不仅仅是它不等于EOF
。
可避免的编码弱点导致 OP 的困难
如果代码根据 5 的期望结果而不是许多不正确的结果之一(如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) {
空白
除了样式之外,在"%ld"
之前放置一个" "
没有任何价值,因为"%ld"
已经消耗了可选的前导空白。
然而,在","
之前放置一个空格以允许在','
之前输入可选的前导空格是有价值的。
while (fscanf(f, "%s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
缓冲区溢出
切勿在(f)scanf()
function 中使用"%s"
。 使用宽度限制,否则有缓冲区溢出的风险。
// width --------vv
while (fscanf(f, "%19s ,%ld ,%ld ,%ld ,%ld", temp1, &temp2, &temp3, &temp4, &temp5) == 5) {
fgetc()
返回一个int
fgetc(f)
返回 257 个不同的值。 使用int
正确区分。
// char x;
int x;
...
while ((x = fgetc(f)) != EOF) {
行数可能会失败
行数仅计算'\n'
的数量。 如果文件仅包含"abc 1 2 3 4"
,没有'\n'
,则行数将报告为 0。
而是计算行首的数量。
count = 0;
int prior = '\n';
while ((x = fgetc(f)) != EOF) {
if (prior == '\n') {
count++;
}
prior = x;
...
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.