C 有没有一种方法可以动态设置从fgets()获取的字符串的大小?

C 有没有一种方法可以动态设置从fgets()获取的字符串的大小?,c,dynamic-memory-allocation,fgets,C,Dynamic Memory Allocation,Fgets,我有一个变量char*cmd,我想在其中存储一个来自fgets()的字符串。有没有一种方法可以使用malloc或类似的方法为这个变量动态分配内存?或者我必须预定义它的大小并在之后终止null吗? 以前,我将cmd的大小预定义为100,但我试图找到分段错误的位置 char *cmd; fgets(cmd,n,stdin) 然后,我尝试使用strtok()对cmd字符串进行标记,并使用空格作为分隔符。正如我在上面的评论中所说的,这不是标准C的内置功能,尽管有一个POSIX函数可以实现您想要的功能

我有一个变量char*cmd,我想在其中存储一个来自fgets()的字符串。有没有一种方法可以使用malloc或类似的方法为这个变量动态分配内存?或者我必须预定义它的大小并在之后终止null吗? 以前,我将cmd的大小预定义为100,但我试图找到分段错误的位置

char *cmd; 
fgets(cmd,n,stdin)


然后,我尝试使用strtok()对cmd字符串进行标记,并使用空格作为分隔符。

正如我在上面的评论中所说的,这不是标准C的内置功能,尽管有一个POSIX函数可以实现您想要的功能。如果您想自己滚动,方法是动态分配(并重新分配)内存,以存储从
fgets()
获得的结果。您可以判断
fgets()
何时到达行尾,因为它会突然到达文件的末尾(在这种情况下,它将返回
NULL
),或者因为它返回的最后一个字符将是换行符

下面是一个示例函数。注意,我使用
strrchr()
从缓冲区的末尾向后搜索换行符。如果我们得到了一个命中,我们确保在返回的字符串中抛出换行符,并确保打破
while()
循环,这样我们就不会再次调用
fgets()
并开始获取下一行

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

// NOTE:  dygetline() allocates memory!  Do not disregard the return and
// remember to free() it when you're done! 

#define BSZ 1024

char *dygetline(FILE * restrict stream) {
  char *ret = NULL;
  char *temp = NULL;
  size_t retalloc = 1;
  char buffer[BSZ];
  size_t buflen = 0;
  char *nlsrch;


  while (NULL != fgets(buffer, BSZ, stream)) {
    nlsrch = strrchr(buffer, '\n');

    if (nlsrch) *nlsrch = '\0';     // Remove newline if exists

    // Get the size of our read buffer and grow our return buffer
    buflen = strlen(buffer);
    temp = realloc(ret, retalloc + buflen);

    if (NULL == temp) {
      fprintf(stderr, "Memory allocation error in dygetline()!\n");
      free(ret);
      return NULL;
    }

    ret = temp;                     // Update return buffer pointer

    strcpy((ret+retalloc-1), buffer);  // Add read buffer to return buffer
    retalloc = retalloc + buflen;      // Housekeeping

    if (nlsrch) break;              // If we got a newline, stop
  }

  // If there was a file read error and fgets() never got anything, then
  // ret will still be NULL, as it was initialized.  If the file ended
  // without a trailing newline, then ret will contain all characters it
  // was able to get from the last line.  Otherwise, it should be well-
  // formed. 

  return ret;
}
#包括
#包括
#包括
//注意:dygetline()分配内存!不要忽视回报和回报
//完成后记得把它放出来!
#定义BSZ 1024
char*dygetline(文件*限制流){
char*ret=NULL;
char*temp=NULL;
尺寸=1;
字符缓冲区[BSZ];
尺寸_tbuflen=0;
char*nlsrch;
while(NULL!=fgets(缓冲区、BSZ、流)){
nlsrch=strrchr(缓冲区“\n”);
if(nlsrch)*nlsrch='\0';//如果存在,请删除换行符
//获取读取缓冲区的大小并增加返回缓冲区
buflen=strlen(缓冲区);
温度=realloc(ret、retalloc+buflen);
如果(NULL==temp){
fprintf(stderr,“dygetline()中的内存分配错误!”\n);
免费(ret);
返回NULL;
}
ret=temp;//更新返回缓冲区指针
strcpy((ret+retarloc-1),buffer);//将读取缓冲区添加到返回缓冲区
retarloc=retarloc+buflen;//内务管理
if(nlsrch)break;//如果有换行符,请停止
}
//如果出现文件读取错误,并且fgets()从未获得任何信息,则
//ret在初始化时仍然为空。如果文件结束
//如果没有尾随换行符,则ret将包含它所包含的所有字符
//能从最后一行得到。否则,它应该是好的-
//形成。
返回ret;
}

没有内置的语言功能,但是如果
fgets()
不能一次获得完整的行,就不能阻止动态分配缓冲区并根据需要增加缓冲区。您可以通过
fgets()
使用的缓冲区中的最后一个字符是否为换行符来判断。您可以将固定大小的字符串传递给
fgets()
。查找POSIX
getline()
,查找根据需要分配空间的行读取函数;然后是fgets(cmd,200,stdin);但是当使用strcopy()将cmd存储到char pointer*标记中时,我遇到了一个分段错误;他们指着琴弦。“但我一直在试图找出我在哪里遇到了分段错误。”-发布您的尝试,我们很乐意提供帮助,但现在,S.O.水晶球出问题了。。。您的问题中存在多个问题(1)是否有一种方法可以分配或我是否需要使用
fgets
的固定buf-您可以这样做,但您必须在调用
fgets
之前分配或声明固定buf;(2) 塞格断层;(3)在空白处使用strtok
标记(不要忘记行尾是空白)。请提供。注意:
strrchr()
strlen()
缓冲区的
n
字符进行两次传递。只有
strlen(缓冲区)
才能找到一个潜在的
'\n'
并知道长度。
retaloc+buflen
太小了。建议
realloc(ret、retalloc+buflen+1)
strcat(ret,buffer)随着每次连续的串联而逐渐变慢。如果(retalloc==0)ret[0]='\0',只需删除它并替换
带有
strcpy(ret+retarloc,缓冲区)
memcpy(ret+retarloc,buffer,buflen+1)我们只需要一个空终止符,无论我们经过多少次
fgets()
,因此在
1
处启动
retarloc
应该可以做到这一点,而不是每次调用
fgets()
时都增加一个字节。不过捕获效果不错。
if(retalloc==1)ret[0]='\0'是不需要的。(和
realloc(ret,retarloc+buflen+1)
不会“每次增加一个额外字节”)。还是很好的升级。