0

下面是返回一个字符指针的函数,该指针指向一个使用getc(stdin)- 逐个字符初始化的字符串。

  1. 内存分配方法有什么缺陷吗?当我们不知道要输入的字符串的大小时,这是一种有效的方法吗?如果不知道,请解释一下。

  2. 使用getc(stdin)--会不会导致缓冲区溢出???()

  3. 如果我不能使用getc(stdin),什么可以帮助我以更有效的方式实现我的目标?

到目前为止的代码:

char *getstring()
{
  char *str = NULL, *tmp = NULL;
  int size = 0, index = 0;
  int ch = -1;
  int length=0;
  while (ch!=0) 
  {
    ch = getc(stdin);

    if (ch == '\n')
    {   
        ch = 0;
    }

    if (size <= index) 
    {
        size += 15;
        tmp = (char*)realloc(str, size);
        if (!tmp) 
        {
            free(str);
            str = NULL;    
        }
        str = tmp;
    }
    str[index++] = ch;
  }

  if(size==index)
  {
    return str;
  }
  else if(index<size)
  {
    length=strlen(str);
    tmp = (char*)realloc(str,(length+1));
    str[index]='\0';
    //cout<<"length:"<<length;
    str=tmp;
  }

  return str;
}
4

2 回答 2

1

不要重新发明轮子:使用getline(3).

示例(来自相同的 URL):

   #define _GNU_SOURCE
   #include <stdio.h>
   #include <stdlib.h>

   int
   main(void)
   {
       FILE *stream;
       char *line = NULL;
       size_t len = 0;
       ssize_t read;

       stream = fopen("/etc/motd", "r");
       if (stream == NULL)
           exit(EXIT_FAILURE);

       while ((read = getline(&line, &len, stream)) != -1) {
           printf("Retrieved line of length %zu :\n", read);
           printf("%s", line);
       }

       free(line);
       fclose(stream);
       exit(EXIT_SUCCESS);
   }
于 2015-05-26T15:46:41.497 回答
0

“内存分配方法有什么缺陷吗?” 是的,当重新分配失败时,您释放前一个内存指针,分配给它,然后用具有值的NULL覆盖它,然后使用指针继续耕作。tmpNULLNULL

if (size <= index) 
{
    size += 15;
    tmp = (char*)realloc(str, size);
    if (!tmp)                   // <--- NULL!
    {
        free(str);
        str = NULL;    
    }
    str = tmp;                  // <--- NULL!
}
str[index++] = ch;              // <--- NULL!

但如果realloc失败了,你别无选择,只能优雅地放弃手头的任务。

此外,如果您同时允许使用 0 终止符,您将节省几行凌乱的代码和另一个重新分配。而且您并不总是插入'\0'.

if (size <= index+1)            // allow room for string terminator
于 2015-05-26T16:22:48.930 回答