【问题标题】:How to read in a character array in C of indeterminate size?如何在 C 中读取不确定大小的字符数组?
【发布时间】:2013-02-06 01:26:33
【问题描述】:

我已经尝试了递归和迭代方法,但我一直遇到存储不确定长度的字符串的问题。如果它们是某种库或 Api 调用,它会一直读取到下一个空格,这将证明非常有帮助。

但本质上,我需要创建一个包含字符数组的结构数组。

【问题讨论】:

  • C++ 流更智能(或愚蠢,取决于你的尝试)。在 C 语言中,您需要使用 get(或 fgets)或 getc(或 fgetc)。你到底在挣扎什么?你能为我们提供你的问题的代码吗?
  • 考虑标准 C 中的 malloc()realloc(),或 POSIX 中的 getline()getdelim(),或 POSIX 中的 stat()mmap()。或者使用getc() 和亲戚,以及malloc() 等。换句话说,有很多方法可以做到这一点。
  • 我可能不够清楚。我将原始文本存储到字符数组中。但是我不知道在达到分米之前我会读入多少个字符。我相信我必须使用标准 C。我对如何使用 malloc() 感到有点困惑,因为我还没有确定大小的东西。我想我无法编写自己的动态数组之类的行为,但我认为这超出了我应该做的范围。
  • 是的,您需要为此使用mallocmalloc 需要您要分配的 RAM 大小,它返回 void *。您可以将其转换为您想要的任何数据类型:char *my_array = (char *)malloc( 10 ); 该示例在堆上分配 10 个字节(字符)。您可以分配固定数量的 RAM,读取直到它已满,然后分配一个更大的数组。然后将旧数组复制到新数组并释放旧缓冲区。您可以重复此操作,直到获得所需的大小。你需要一个更清楚的例子吗?

标签: c arrays file io character


【解决方案1】:

使用 malloc 和 realloc 为您的输入腾出空间。选择一个合理的起始大小(您必须对预期有多少字符有所了解)。每次重新分配时,大小翻倍。

【讨论】:

  • 好的,realloc 看起来可能是解决这个问题的重新分配部分的最优雅的方法。我有点困惑如何使用它,因为您将现有的块指针传递给它,该指针现在是否指向新块?我正在阅读返回类型为 void,但它也表示它返回指向您的 realloc'd 块的指针。也许措辞是关闭的,它意味着通过函数隐式返回或修改。
  • 没关系。我想念阅读。返回类型不是 void,而是 *void 的指针。我现在了解 realloc。
【解决方案2】:

我想这个例子显示了你在寻找什么。我建议使用mallocfree 来发现它的行为。另请阅读 goto 处的评论,除非您真的知道自己在做什么,否则不要使用 goto。使用它,您可能会非常容易失败。带有 if 的 while 循环来检查缓冲区是否溢出下一个字符会更好,但我很懒所以我就让它保持原样。如果您还有任何问题,请随时提出。

#include <malloc.h>
#include <string.h>

int main( ) {
  unsigned bufferSize = 0; // our array size
  int i = 0; // current position in buffer
  // we allocate memory for our buffer
  char *buffer = (char *)malloc( bufferSize += 10 );

  int ch = EOF; // set to eof, we will use this to buffer input

  // read input until buffer is full
repeat_input:
  for( ; i < bufferSize; i++ ) { // a while loop would be better for this job...
    ch = fgetc( stdin );
    if( ch == ' ' ) {
      // if there is a space we can break here
      goto done; // this is bad coding practice, i am just a bit lazy now
    }
    buffer[ i ] = ch;
  }

  // keep our old buffer pointer to not create a memleak
  char *old_buffer = buffer;
  buffer = (char *)malloc( bufferSize += 10 );

  // copy content of old buffer to new one
  int k = 0;
  for( k = 0; k <= i; k++ ) {
    buffer[ k ] = old_buffer[ k ];
  }

  // free RAM, else we have a memleak
  free( old_buffer );
  goto repeat_input;

done:
  fputs( buffer, stderr );
  free( buffer );
  return 1;
}

【讨论】:

  • 好的,我开始了解发生了什么。但是使用 malloc 你仍然必须指定一个有限空间对吗?或者 += 10 是否允许它动态增长到 10 以上?我看到您将所有内容从 old_buffer 复制到新定义的缓冲区。这应该是处理缓冲区大小增长的需要吗?
  • @Aerlusch 这正是它的作用。在 bufferSize 作为 malloc 调用的参数传递之前,您将其增加 10。这有点滥用 += 运算符。
  • 哇哦,我终于明白了。非常巧妙的处理方式。我也看到 realloc 是一种可能性,我没听说过。
  • realloc 可能是一个选项,是的。我想演示复制和释放缓冲区。只是玩它并找到最好的方法。
  • 好的,非常感谢,这一下子就解决了我对文件 io 和 malloc/calloc 的困惑。我想暂时就这些了,除非我遇到其他麻烦。
猜你喜欢
  • 1970-01-01
  • 2020-09-10
  • 2011-01-12
  • 2018-08-06
  • 2020-07-29
  • 2019-01-26
  • 2021-03-16
  • 2015-11-27
  • 1970-01-01
相关资源
最近更新 更多