【问题标题】:How to adjust the memory size in a char array which is created by a function?如何调整由函数创建的 char 数组中的内存大小?
【发布时间】:2019-09-17 14:04:54
【问题描述】:

我调用一个方法:

char * buffer = read_string_from_file();

方法如下:

char * read_string_from_file() {
    char * filename = "C:/Users/xxxxx/Dropbox/c-programming-test-file.txt";  // later I will give this as a parameter
    char * buffer = 0;
    long file_length;
    FILE * file = fopen (filename, "r");

    if (file)
    {
        fseek (file, 0, SEEK_END);
        file_length = ftell (file);
        fseek (file, 0, SEEK_SET);
        buffer = malloc (file_length);
        if (buffer)
        {
            fread (buffer, 1, file_length, file);
        }
        fclose (file);
        return buffer;
    }
}

文件包含:

2461866 -3134537

当用printf("buffer: %s\n\n", buffer); 打印buffer 时,我得到buffer: 2461866 -3134537Files\Jey┘·å¬。相反,我期望:buffer: 2461866 -3134537。如何调整char数组buffer的大小?

【问题讨论】:

  • 您没有正确终止字符串,甚至没有检查fread() 是否有效。您还以文本模式打开文件,因此ftell() 不会告诉您将读取多少字节。
  • @AndrewHenle 我还是个初学者。 :|如何不以文本模式打开它?用“b”?

标签: c arrays memory-management


【解决方案1】:

对于printf("buffer: %s\n\n", buffer);"%s" 需要buffer 指向一个字符串。在 OP 的情况下,它不是,因此是 UB(额外的垃圾打印)。


如果可以知道长度,只需打印fwrite()

fwrite(buffer, 1, file_length, stdout);

,因为buffer 不一定是字符串,如果file_length < INTMAX,代码可以使用以下内容。

printf("%.*s", (int) file_length, buffer);

改变read_string_from_file()形成一个字符串。添加一个空字符

// buffer = malloc (file_length);
buffer = malloc (file_length + 1);
if (buffer) {
  fread (buffer, 1, file_length, file);
  // add
  buffer[file_length] = '\0';
  ...
  printf("buffer: %s\n", buffer);

如果没有空字符buffer 就不是字符串


另外:健壮的代码也会检查ftell(), fread() 的结果。

【讨论】:

  • 好的,我重复这句话。没有空字符,缓冲区不是字符串。没有空字符,缓冲区不是字符串。没有空字符,缓冲区不是字符串。没有空字符,缓冲区不是字符串。 :) 初学者最大的错误之一,对吧?
  • @kane 详细信息:文件的数据内容很少是字符串(文本最多包含一个空字符)。一个文本文件通常有很多 (直到并包括 '\n' 的文本,可能最后一行除外)。要确定打印所有文件(可能包含空字符,请使用fwrite() 方法。
  • kane,是的,不介意 stringnull 字符 要求是常见的 oops。
  • 感谢您对文件中许多空字符的良好提示。 (顺便说一句。卡姆,不是凯恩):)
  • 哎呀,意思是“可能un预期包含空字符”
【解决方案2】:

C 中的字符串必须以 NUL 结尾。

例如,您可以这样做:

...
buffer = malloc (file_length + 1);  // + 1 for the NUL terminator
buffer[file_length] = 0;            // put NUL terminator
...

【讨论】:

  • 当我使用您的代码时,它只使用 6 个数字。当我在文件中有 60 个数字时,问题再次出现。你能检查一下吗?
  • @kame 显示产生问题的最小文件。否则你可能想看看fgets
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
相关资源
最近更新 更多