如何使用fread逐个读取文件值?

3

我使用fwrite函数存储了一些数据,现在想要使用fread函数从txt文件中读取这些数据进行处理。我希望能够逐个读取这些数值,但是我不知道如何做到。下面是我尝试过的代码:

#include <stdio.h>
#include <stdlib.h>

int main () 
{
  FILE * pFile;
  long lSize;
  unsigned short * buffer;
  size_t result;

  pFile = fopen ( "myfile.txt" , "rb" );

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

  // allocate memory to contain the whole file:
  buffer = (unsigned short *) malloc (sizeof(unsigned short)*lSize);

  // copy the file into the buffer:
  result = fread (buffer,1,lSize,pFile);

  printf("%uz\n", result);

  // terminate
  fclose (pFile);
  free (buffer);
  return 0;
}

上述程序编译无误,但是当我使用./a.out运行时出现了分段错误。当我使用sudo ./a.out运行时,没有分段错误,但是什么也没有输出。你有什么办法可以修复它吗?

在这里进行一些错误检查:pFile = fopen("myfile.txt", "rb"); - πάντα ῥεῖ
@πάνταῥεῖ 我需要检查什么?那只是打开文件。只要我把文件名写对了,就应该可以正常工作。 - Fortuna Iwasaki
你从未将返回值与“NULL”进行比较! - πάντα ῥεῖ
2
将结果作为字符串打印 - 这可能是您的段错误的原因。 - PiotrNycz
@PiotrNycz 我已经更新了,现在它只会打印 524z - Fortuna Iwasaki
1个回答

1

我看到的问题:

分配过多的内存

在之后

lSize = ftell (pFile);

lSize被设置为文件中字符的数量,而不是unsigned short的数量。因此,您需要

buffer = malloc(lSize);

请参考我是否需要强制转换malloc的返回值?。如果您正在使用C++编译器(如您的C++标签所示),则需要强制转换malloc的返回值。

格式说明符错误

printf("%s\n", result);

使用了错误的格式说明符来打印 result。您需要使用

printf("%zu\n", result);

那行代码很可能是导致你看到的分段错误的罪魁祸首。
逐个读取对象
您当然可以使用:

Reading objects one by one

您可以逐个读取:

size_t count = lSize/sizeof(short);
for ( size_t i = 0; i < count; ++i )
{
   unsigned short number;
   result = fread (&number, sizeof(unsigned short), 1, pFile);        
}

你也可以使用:

size_t count = lSize/sizeof(short);
for ( size_t i = 0; i < count; ++i )
{
   result = fread (buffer+i, sizeof(unsigned short), 1, pFile);        
}

但是写入文件的值是无符号短整型。当我按照你说的做时,屏幕上只会打印出一堆“1z”。 - Fortuna Iwasaki
fread 的返回值是读取的对象数量。如果你一次只读取一个对象,那么 result 的值将为 1。由于我建议的格式存在错误,所以你看到的输出是 1z。它应该是 "%zu" 而不是 "%uz"。我已经在答案中修正了这个错误。 - R Sahu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接