-1

对于 getline() 函数,我尝试了两种方法为字符串分配内存空间,但第一种方法有效,第二种方法无效。谁能解释为什么第二个不起作用?

第一个

#include <stdio.h>

int main()
{
  int bytes_read;
  int nbytes = 100;
  char *my_string;

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  my_string = (char *) malloc (nbytes + 1);
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

第二个:

#include <stdio.h>
int main()
{
  int bytes_read;
  int nbytes = 100;
  char my_string[nbytes+1];

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

第二个可以编译,但是当我执行它时:

bash-3.2$ ./a.out 
Please enter a line of text.
lsdfa
Bus error: 10

它说总线错误:10

我不知道可能的原因是什么,有人可以帮助我吗?

4

5 回答 5

4

的签名getline需要一个指向 a 的指针,char*以便可以对其进行修改。这是因为如果您传递指向 0 的 a,则getline应该允许调用或分配 a :reallocchar*char*char*

getline()从流中读取整行,将包含文本的缓冲区的地址存储到*lineptr.

...

在任何一种情况下,在成功调用时,*lineptr都会*n更新以分别反映缓冲区地址和分配的大小

getline在第一种情况下,一切都很好,因为可以修改您传递给的指针。

在第二种情况下,您传递一个指向char数组的指针,该数组本身不能被修改。正如您所发现的,不幸&my_string的是最终看起来像char**,所以编译器不会抱怨(但它可能与-Wall)。

基本上,由于getline需要能够修改lineptr指向的内容,因此在第二种情况下这是无法完成的(因此出现总线错误)。

于 2012-05-03T02:32:00.567 回答
3

阅读手册页getline()

摘录:

或者,在调用 getline() 之前,*lineptr 可以包含一个指向 malloc(3) 分配的缓冲区 *n 字节大小的指针。

因此getline(),特别假设传递给它的缓冲区已被分配,malloc以便它可以在必要时将其调整为更大的大小。

你应该得到一个编译器警告,比如这个,提示你调用函数的方式有问题:

警告:从不兼容的指针类型传递“getline”的参数 1

于 2012-05-03T02:32:19.467 回答
2

我实际上无法理解这一点。你的两个例子都不应该从我所知道的编译出来......事实上离它还很远。这样做:

int main() {

  std::string line;

...
  std::getline(std::cin, line);

...
}

不必乱用 malloc、new 等...

包括iostream,不stdio.h

于 2012-05-03T02:36:03.077 回答
0

修正版:

http://linux.die.net/man/3/getline

#include <stdio.h>
#define BUFLEN 100

int main()
{
  int bytes_read;
  int nbytes = BUFLEN;
  char *my_string = NULL;

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  bytes_read = getline (&my_string, &nbytes, stdin);

  if (bytes_read == -1)
    {
      puts ("ERROR!");
    }
  else
    {
      puts ("You typed:");
      puts (my_string);
    }

  return 0;
}

坦率地说,我更喜欢“fgets()”而不是“getline()”:

#include <stdio.h>
#define BUFLEN 100

int main()
{
  char my_string[BUFLEN+1];

  puts ("Please enter a line of text.");

  /* These 2 lines are the heart of the program. */
  fgets (my_string, BUFLEN, stdin);
  ...

如果你在 C++ 领域,你可能最好使用 std::string。

于 2012-05-03T02:35:44.460 回答
0

使用 'new' 关键字进行动态初始化:

char* my_string = new char[nBytes + 1];
于 2012-05-03T02:31:29.427 回答