使用 fread 和 fseek 逐行读取

Reading line by line using fread and fseek

我正在尝试逐行读取 .txt 文件,其中每行长 19 个字符,这是我的代码(我只想使用 fseek 和 fread 来正确理解指针):

int main(int argc, char *argv[]){
    FILE *file = fopen(argv[1], "r");
    if(file == NULL){
        perror("fopen");
        return 0;
    }
    int i = 0;
    int j = 0;
    char L[20];
    while(1){
        if(feof(file)){
            break;
        }
        fseek(file, i*20, SEEK_SET);
        fread(L,19,sizeof(char),file);
        printf("%s\n", L);
        i++;
        }
    fclose(file);
    return 0;   
 }

我认为应该发生的是我将指向文件的指针移动到循环中每一行的开头,然后移动一行等等。源 .txt 文件是:

123456789:123456789
perro:guau         
gato:miau          
                   
vaca:muuu          
                   
lobo:auuu          
                   

而我的程序得到的输出是:

123456789:123456789�V
perro:guau         �V
gato:miau          �V
                   �V
vaca:muuu          �V
                   �V
lobo:auuu          �V
                   �V
                   �V

我尝试更改 20s 和 19s,因为我不知道我是否以正确的方式包括字符串字符的结尾,但得到的结果更糟,任何帮助都将不胜感激。

  • OP 的代码具有 未定义的行为 ,(UB)因为 "%s" 需要一个 字符串 。然而 L[] 缺少 空字符 。要打印字符数组,请使用 "%.*s"

  • 检查 fread() return 值,而不是 feof().

  • 使用 fread() 的 return 值可以知道读取了多少。

  • 检查 fread(void * restrict ptr, size_t size, size_t nmemb, FILE * restrict stream);

    的参数顺序

样本:

size_t sz = sizeof L / sizeof L[0];
size_t n;
while((n = fread(L,sizeof L[0], sz, file)) > 0) {
  printf("<%.*s>\n", (int) n, L);
  i++;
  fseek(file, i*20, SEEK_SET);
}

fread() 不是阅读 的最佳工具。改为研究 fgets()

"每行有 19 个字符长," --> C 将 定义为"每行由零个或多个字符加上终止的 new-line 字符组成”从 C-point-of-view 开始,您的 包括一个 new-line,因此总共有 20 个字符。