【问题标题】:How come my fread returns an empty string?为什么我的 fread 返回一个空字符串?
【发布时间】:2017-09-04 06:09:53
【问题描述】:

当我将字符串写入文件时,我首先将字符串的长度写为 int,然后是字符串本身。这是我的代码:

int wordLength = strlen(words);
fwrite(&wordLength,sizeof(int),1, outputFile);
fwrite(&words,sizeof(char),strlen(words), outputFile);

但是,当我将其返回时,我得到一个空字符串。这是我的阅读代码:

int strLength;
fread(&strLength, sizeof(int), 1, f);
char* word = (char*) malloc(strLength*sizeof(char));
fread(&word, sizeof(char), strLength, f);

为什么会这样?

【问题讨论】:

  • 您的strLength 是否按预期正确输入?
  • 第二个 fwrite 可疑。如果words 是一个指针,那么您正在编写指针而不是它指向的内容。如果它是一个数组,你可以,但如果没有&,你也可以。发布不完整的程序片段使回答问题变得困难!第二个 fread 肯定是错误的; &word 是指针的地址。它指向的缓冲区是您想要进入的缓冲区。
  • @MichaelDautermann 是的。
  • 在调用任何堆分配函数时:(malloc, calloc, realloc),不要强制转换返回值。返回的类型是void*,因此可以分配给任何其他指针。强制转换只会使代码混乱,使其更难以理解、调试等。注意:sizeof(char) 在标准中定义为 1,因此只需使用 1。此外,将任何内容乘以 1 除了使代码混乱之外绝对没有任何作用。
  • @user3629249 关于您的第一条评论,我怀疑标识符words 可能已被选择它是单个字符串中的一组单词,而不是一组每个字符串都包含一个单词.

标签: c file io fread


【解决方案1】:

当我把它吓回来时,我得到一个空字符串。这是我的阅读代码:
为什么会这样?

fread(&strLength, sizeof(int), 1, f);
char* word = (char*) malloc(strLength*sizeof(char));
fread(&word, sizeof(char), strLength, f);
  1. 代码分配的内存不足。 strLength*sizeof(char) 足以让文本而不是终止 null 字符 来制作 string

    // char* word = (char*) malloc(strLength*sizeof(char));
    char* word = malloc(strLength + 1u); // add 1
    
  2. fread(&word, ...); 正在尝试将数据读入word 的地址,而不是读入刚刚分配的内存。

    // fread(&word, sizeof(char), strLength, f);
    fread(word, sizeof *word, strLength, f);  // drop &
    
  3. 空字符永远不会被附加。

    size_t count = fread(word, sizeof *word, strLength, f);
    if (count != strLength) puts("Error");
    else {
      word[strLength] = '\0';
      puts(word);
    }
    

注意事项: 最好使用size_t wordLength

检查malloc() 的返回值是好的代码。

size_t wordLength = strlen(words);
...
char* word = malloc(strLength + 1);
if (word == NULL) Hanlde_OutOfMemory();

发布不显示文件打开/关闭详细信息。代码可能需要rewind(f)才能读取写入的数据。

【讨论】:

  • 我很喜欢在i 上打点和穿越t,但strLength + 1u 令人印象深刻。我从来没有考虑过由+ 1-pendantic 导致的签名扩展 的可能性不会抱怨additionsignedunsigned i> 输入:)
  • @DavidC.Rankin 更多的是intint wordLength ... strLength + 1 溢出,并提请注意分配应使用无符号数学。考虑int strLength = -99; fread(&strLength, sizeof(int), 1, inputFile); char* buff = (char*) malloc(strLength*sizeof(char)); 的影响应该fread() 失败。
  • 我知道了。那将是一个长字符串:),但写得很好。
【解决方案2】:

这适用于 Ubuntu:

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

int main(int argc, char **argv)
{

    FILE *outputFile;
    FILE *inputFile;
    char words[] = "This is a series of words";

    int wordLength = strlen(words);

    outputFile = fopen("outputFile", "w");
    if ( outputFile == NULL )
    {
        perror("fopen failed: ");
    exit(1);
    }


    fwrite(&wordLength,sizeof(int),1, outputFile);
    fwrite(words,sizeof(char),strlen(words), outputFile);

    fclose(outputFile);

    inputFile = fopen("outputFile", "r");
    if ( inputFile == NULL )
    {
        perror("fopen(2) failed: ");
    exit(1);
    }

    int strLength = -99;
    fread(&strLength, sizeof(int), 1, inputFile);

    char* buff = (char*) malloc(strLength*sizeof(char));
    fread(buff, sizeof(char), strLength, inputFile);

    buff[strLength] = 0x00;

    printf("Input Str: -->%s<--\n", buff);

}

【讨论】:

  • 虽然此代码可能会回答问题,但提供有关它如何和/或为什么解决问题的额外上下文将提高​​答案的长期价值。
  • 另外,strlen returns size_twordLength 应该被声明为,你的第一个 fwritefread 应该是写和读)、sizeof(char) is guaranteed to be 1 和 @987654323 @.
  • @Seb 我同意你所有的 cmets,但我的目标是对他的来源进行最小的修改以展示一个工作模型......他应该能够比较和确定差异。跨度>
  • 很好。 cmets应该是针对问题的,然后...我的错。
  • @chux 很好,是的……我的错。应该是char* buff = (char*) malloc(1+strLength*sizeof(char));
猜你喜欢
  • 2012-03-19
  • 1970-01-01
  • 2013-05-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-12
  • 2013-10-22
  • 2021-10-09
相关资源
最近更新 更多