c - 如何使用C计算文件中存在的行数

标签 c file

我用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/

相关文章:

javascript - 如何在 nativescript 中使用多部分表单数据上传文件?

java - 关于使用 wav 文件进行编程以便对其应用 dpcm

c - 如何使用 getline(s, lc) 函数更新 int 变量而不使用 "pointers"? (C)

java - 更改与整数对应的输出文件的名称

C 或 '|' 运算符

c - 在C中将字符串常量读取为非常量变量

android - 如何将内容 Uri 转换为文件

c++ - 使用通配符 C++ 从当前目录打开文件

c - 如何编译 Michael Kerrisk 所著《 "The Linux Programming Interface"》一书中的示例

C - 需要帮助调试国际象棋功能