在C中连接大字符串以写入文件

时间:2017-04-25 02:10:07

标签: c string concatenation

我是C的新手,所以我很难搞清楚这一点。我一次读取文件500个字节,计算文件中的行数,然后一旦我达到500行,我将其写入另一个文件。该文件根本没有正确出现,我认为这与我尝试连接长字符串然后将其写入文件有关。这是我现在的代码的主循环:

   while (lineCount != 500)
   {
    if (lineCount == 500)
      break;
    readbytes = read(infd, buf, 500);
    for (str = buf; *str; ++str)
    {
      lineCount += *str == '\n';
      char *newPtr = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
      forkBuf = newPtr;
      char* newFork = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
      sprintf(forkBuf, "%s%s", newFork, str);
      if (lineCount == 500)
        break;
    }
    if (lineCount < 500)
    {
      if(readbytes < 500){
        write(outfd, forkBuf, (strlen(forkBuf) + 2));
        break;
      }
      continue;
    }
    write(outfd, forkBuf, (strlen(forkBuf) + 2));
  }

1 个答案:

答案 0 :(得分:2)

您有两行代码:

char* newFork = realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));
sprintf(forkBuf, "%s%s", newFork, str);

这会导致未定义的行为;如果realloc重新分配到新地址,则forkBuf指向释放的内存;即使realloc有效,according to the standard

  

此示例中的原始指针ptr [ forkBuf ]无效,对它的任何访问都是未定义的行为(即使重新分配就位)。

我还要补充说,如果(可能会发生)forkBuf等于newFork,使用sprintf将字符串复制到自身也是未定义的行为。

此外,这里有一个for循环,其中str基本上被视为单个字符。我重写整个循环,但快速破解可能是:

// One byte extra for the `\0`, and one for the new character
char *newPtr = realloc(forkBuf, (strlen(forkBuf) + 2));
if (newPtr == NULL)
    panic(); // Or whatever error handling you might want
forkBuf = newPtr;
size_t len = strlen(forkBuf);
forkBuf[len] = *str;
forkBuf[len + 1] = '\0';

请注意,循环中只需要一个realloc(),或者更好,循环外只有一个realloc(forkBuf, (strlen(forkBuf) + strlen(str) + 2));