0

文字列を別の文字ポインタにコピーしようとしていますか?

以下のコードを試してみましたが、正常にコンパイルされましたが、出力が空白(出力なし)です。

a)どこが間違っていたのか、プログラミングロジックが失敗したのか。

b)このコードを改善して目的の出力を得るにはどうすればよいですか?

    void main()
    {
     char *p="krishna";
     char *q;

      while(*p!='\0')
      {
       *q++=*p++;
      }
      printf("%s",q);
      getch();
    }
4

10 に答える 10

3
void main()
{
  char *p="krishna";
  char *q;

  /* When copying, you modify your pointers, so you need another one
  ** to store where your string is starting. */
  char *r;

  /* Until now, q points to nowhere.
  ** You need to allocate the place it should point: */
  r = q = malloc(strlen(p) + 1);
  /* Plus 1 because C string uses one extra character in the end,
  ** the NULL ('\0') character. */

  while(*p!='\0')
  {
   *q++=*p++;
  }

  /* Until now, you've copied every character, except the NULL char at the end.
  ** you must set it in order for it to be a valid string. */
  *q = '\0';

  /* Now q points to the last (NULL) character of the string.
  ** In order to print it, you will need a pointer to the start of the string,
  ** that is why we need r: */
  printf("%s",r);

  /* When you are done using a memory buffer you allocated yourself,
  ** you must free it so it can be reused elsewhere. */
  free(r);

  getch();
}
于 2012-08-27T17:43:43.620 に答える
2

a)どこが間違っていたのか、プログラミングロジックが失敗したのか。

さて、あなたはいくつかのことを間違ってしました。1つvoid mainは、非標準です。の戻りタイプは。でmainある必要がありますint

そうは言っても、あなたが探している本当のq問題は、初期化されていないという事実に関係していますが、それでもそれを介してメモリにコピーしようとします(これは未定義の動作です)。これを修正するにはq、たとえば、

char *q = malloc(8);

freeその後、ここで割り当てられたメモリにも注意を払う必要があることに注意してください。

それとは別に、NULターミネーターをコピーするのも忘れています。

*q = 0;

...コピーループの後。また、ポインタをインクリメントした後に印刷qしているため、呼び出しの時点でポインタが文字列の先頭に表示されなくなりますprintf。ヘッドのコピーを別の変数に格納する必要があります。さらに、ストリームがバッファリングされてフラッシュされないままになる可能性があるため、新しい行のないプレーンを使用する場合は注意が必要printfです。明示的に使用してください。fflush(stdout);


b)このコードを改善して目的の出力を得るにはどうすればよいですか?

さて、私が考えることができる最初の最も簡単な改善は、を使用することstrcpyです。

#include <stdio.h>

main() {
  const char p[] = "krishna";
  char q[sizeof p];
  strcpy(q, p);
  puts(q);
  getchar();
  return 0;
}
于 2012-08-27T17:51:23.523 に答える
1

コピーされた文字列を保持するには、「q」にメモリを割り当てる必要があります。

于 2012-08-27T17:31:53.287 に答える
1

qに必要なメモリの量を言っているのではないので、他の何かのメモリを使い果たしようとしています。したがって、mallocまたは配列を使用します。

于 2012-08-27T17:33:05.410 に答える
1

'\0'qの最後に文字を付ける必要があります。また、それに十分なメモリを割り当てる必要があります。

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

int main()
{
  char *p="krishna";
  int size = strlen(p) + 1;
  char *q = (char *) malloc(size);
  char *qi = q;

  do
  {
   *q++=*p;
  } while(*p++!='\0');

  q = qi; //reset q to the beginning of the string

  printf("%s",q);
  getch();
  return 0;
}

これでうまくいくと思います

于 2012-08-27T17:33:48.103 に答える
1

最後にforループでポインタを移動しています。また、メモリも割り当てる必要がありますq

これを試して:

void main()
{
 char *p="krishna";
 char *q = malloc(sizeof(char) * 20);
 char *temp = NULL;

 /* save q */
 temp = q;
  while(*p!='\0')
  {
   *q++=*p++;
  }
  /* reset saved q */
  q=temp;
  printf("%s",q);
  getch();
}
于 2012-08-27T17:34:27.317 に答える
1

a)移動しますqが、文字列の先頭にリセットしないでください。

他の多くの人が指摘しているように、コピー操作の宛先は、メモリが割り当てられている場所、ヒープ上、char *buf = malloc(BUF_SIZE)またはスタック上にある必要がありますchar buf[BUF_SIZE]

最後に、宛先はゼロで終了する必要があります。

b)専用のAPIを使用すると、通常、自家製のループよりも読みやすく、パフォーマンスが向上します。

于 2012-08-27T17:34:30.513 に答える
1

提供したこの例では、新しい文字配列にメモリを割り当てているのではなく、文字を不明なバッファにコピーしているだけです。これにより、あらゆる種類の問題が発生する可能性があります(バッファオーバーフローと攻撃について読んでください)。さらに、文字を不明なバッファにコピーし終えると、このバッファは文字列の先頭ではなく、文字列の末尾を指します。文字配列をCの文字列としてコピーするというアイデアの場合は、次のコードを使用してコピーできます。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
  char *p="krishna";
  char *q = (char*) malloc(sizeof(char) * (strlen(p) + 1));

  strcpy(q, p);

  printf("%s", q);
  getchar();
  free(q);
  return 0;
}

ほとんどのシナリオでは、NULL文字('\ 0')の配列の最後にある余分なバイトは不要ですが、文字配列はNULL文字で終了する必要があるため、正確を期すために含まれています。

mallocを使用して、文字列のコピー先のバッファに(動的)メモリを割り当てます。メモリが動的に割り当てられるときはいつでも、後で解放する必要があります。そうしないと、不必要に使用され続けます。このmallocの使用を解放するために、アプリケーションが戻る前に、最後に「free」コマンドが使用されます。

于 2012-08-27T17:40:58.627 に答える
0

まだ欠落している1つの重要な改善提案(他の人はすでに文字列関連の問題を指摘しています)

Your declaration of main is not correct. 
The return value should  not be  void  but int
于 2012-08-27T17:46:24.357 に答える
0

多くの人がqの値をメモリアドレスに初期化するように私に言いました。これを行う必要はないと思います。このコードは未定義の動作にもかかわらず正しく機能しているためです。

 int main()
 {
 char *p="krishna";
 char *q,*r;
 r=q;

  while(*p!='\0')
  {
   *q++=*p++;
  }
   *q='\0';
    q=r;
  printf("%s",q);
  getch();
  return 0;
 }
于 2012-08-27T18:39:12.537 に答える