我用C语言设计了一个程序来计算行数,但它显示了垃圾值。 我的文件包含的数据如下
2,8,10
3,5,7
4,5,1
3,6,8
3,7,8
3,8,4
用于计算我编写的程序的行数
int count_lines =0;
char sample_char;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}
printf("\n\n\n The number of lines are %d",count_lines);
但是这里正在打印垃圾值。我哪里出错了???
当我编写下面的代码时,它完美运行
typedef struct ratings {
int userId;
int movieId;
int rating;
}Ratings;
int i, n=65;
FILE *fptr;
fptr = fopen("demo3.txt", "r");
/* *//counting the number of lines present in the above file
sample_chr = getc(fptr);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_lines = count_lines +1;
sample_chr = getc(fptr);
}* */
printf("\n\n\n The number of lines are %d",count_lines);
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
现在,如果我打印内容,我就会得到输出。如果我删除注释行,则会出现垃圾值
最佳答案
您忘记检查文件是否打开。
fptr = fopen("demo3.txt", "r");
每个文件操作,特别是打开文件,都应该进行错误检查。这是一个例子。
#include <stdio.h>
#include <string.h>
#inculde <errno.h>
...
char filename[] = "demo3.txt";
FILE *fptr = fopen(filename, "r");
if( fptr == NULL ) {
fprintf( stderr, "Could not open %s for reading: %s\n",
filename, strerror(errno)
);
exit(1);
}
<小时/>
//storing the values in array of structures
for(i=0;i<n;i++)
fscanf(fptr, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating);
这就是产生垃圾的原因。因为它是在 getc
完成读取文件之后发生的,所以对 fscanf
的调用将尝试读取文件末尾并失败(同样,检查每个文件操作)。任何内容都不会被放入 REC1
中,它将包含声明时所具有的垃圾。
将fptr
想象成编辑器中的光标。每次阅读时,光标都会向前移动。每次调用 getc
都会将光标向前移动一个字符。当您调用 fscanf
时,它已到达文件末尾。
您可以使用fseek
移动光标。使用它将 fptr
移回到文件的开头。并且,是的,检查以确保它有效。
if( fseek(fptr, 0, SEEK_SET) != 0 ) {
fprintf( stderr, "Could not rewind %s: %s\n", filename, strerror(errno) );
}
请注意,您仍然会得到垃圾,因为您正在阅读 n
次,而不是 count_lines
次。
请注意,您无法显示有问题的行。 This, and many other reasons, is why it's best to avoid fscanf
而是使用 fgets
读取该行并使用 sscanf
解析该行。这也消除了读取n
次的需要,只需读取直到所有行都读完。
// A line buffer
char line[1024];
int i = 0;
// Read a line
while( fgets( line, sizeof(line), fptr) != NULL ) {
// Parse the line
if( sscanf(line, "%d,%d,%d", &REC1[i].userId, &REC1[i].movieId, &REC1[i].rating) < 3 ) {
fprintf( stderr, "Could not understand '%s' from %s\n", line, filename );
continue;
}
// Print what we got
printf("uid: %d, mid: %d, rating: %d\n", REC1[i].userId, REC1[i].movieId, REC1[i].rating);
i++;
}
至于确保REC1
足够大以容纳所有行,请查看realloc
。
关于c - 如何使用C计算文件中存在的行数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46920887/