-1

getline()関数については、文字列にメモリスペースを割り当てるために2つの方法を試しましたが、最初の方法は機能し、2番目の方法は機能しません。2番目が機能しない理由を誰かが説明できますか?

最初の1つ

#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;
}

2つ目:

#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;
}

2つ目はコンパイルできますが、実行すると次のようになります。

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

バスエラー:10

考えられる理由はわかりませんが、誰か助けてもらえますか?

4

5 に答える 5

4

の署名には、変更できるようにgetlineへのポインタが必要char*です。これは、0を指すaを渡すと、をgetline呼び出すか、を割り当てることができるようになっているためです。reallocchar*char*char*

getline()ストリームから行全体を読み取り、テキストを含むバッファのアドレスをに格納します*lineptr

..。

いずれの場合も、呼び出しが成功する*lineptr*n、バッファアドレスと割り当てられたサイズをそれぞれ反映するように更新されます

最初のケースでは、渡したポインタをgetline変更できるため、すべて問題ありません。

2番目のケースでは、配列へのポインターを渡しますがchar、それ自体は変更できません。&my_stringお気づきのように、残念ながら、のようchar**に見えるので、コンパイラは文句を言いません(ただし、で文句を言う場合があり-Wallます)。

基本的に、ポイントgetlineを変更できる必要があるためlineptr、2番目のケースでは、これを実行できません(したがってバスエラー)。

于 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をいじる必要はありません、新しい、そのいずれか...

そして、含まiostreamないでstdio.hください!

于 2012-05-03T02:36:03.077 に答える
0

動的初期化には「new」キーワードを使用します。

char* my_string = new char[nBytes + 1];
于 2012-05-03T02:31:29.427 に答える
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;
}

率直に言って、私は「getline()」ではなく「fgets()」を好みます。

#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 に答える