0

我正在尝试将文本文件复制到缓冲区以便通过套接字发送它。只要文本文件没有任何换行符(或 \n),文件就会成功复制到缓冲区中。但是,每当文本文件中有多行时,我都会收到错误消息"Unable to copy file into buffer"

下面是代码片段:

//=====================Sending a File at Socket=========================
   FILE *fp = fopen("File.txt", "r+");
   char file_buffer[1000];

   fseek(fp, 0, SEEK_END);
   size_t file_size = ftell(fp); //calculating File Size

   fseek(fp, 0, SEEK_SET);
   int bytes_read=0;
   if((bytes_read=fread(file_buffer, 1, file_size, fp))<=0)
     {
       MessageBox( NULL,
               "Unable to copy file into buffer",
               "Error!",
               MB_ICONEXCLAMATION | 
               MB_OK);
      exit(1);
     }
     MessageBox( NULL,
             file_buffer,
            "File copied in Buffer",
            MB_ICONEXCLAMATION | 
            MB_OK);

注意: 如果文本文件不包含新行,则代码可以正常工作。

4

1 回答 1

3

简短的回答

使用“rb+”模式而不是“r+”打开文件,


长答案

您正在使用“r+”模式打开文件。在该模式下,所有“\r\n”序列(即 Windows 行尾”)都被转换为“\n”(即 Unix 行尾)。

但是 ftell 返回的文件大小会为您提供未经翻译的真实文件大小。

例子

File.txt 的内容

12\r\n34

这个文件的大小是 6 个字节

使用“r+”模式读取后file_buffer的内容:

12\n34

在这种情况下,fread 的返回值为 5。

使用“rb+”模式读取后file_buffer的内容:

12\r\n34

在这种情况下,fread 的返回值为 6。您可以使用调试器检查这一点。阅读fopen的文档。

代码中的更多问题

您对 MessageBox 的调用将显示文件内容,可能后跟垃圾,因为您没有放置零终止符。

在调用fread后将此添加到您的程序中

file_buffer[bytes_read] = 0 ;

用 fread 测试一个错误条件,如果它的返回值 < 0 是不正确的;无论如何,fread 的返回值类型是 size_t(无符号)而不是 int,写size_t bytes_read=0;而不是int bytes_read=0;

摘自fread文档:

fread 返回实际读取的完整项目数,如果发生错误或在达到 count 之前遇到文件末尾,则可能小于 count。使用 feof 或 ferror 函数将读取错误与文件结束条件区分开来。如果 size 或 count 为 0,则 fread 返回 0 并且缓冲区内容不变。如果流或缓冲区是空指针,则 fread 调用无效参数处理程序,如参数验证中所述。如果允许继续执行,此函数将 errno 设置为 EINVAL 并返回 0。

于 2013-05-08T07:05:51.193 回答