6

StackOverflow でそれに関する多くの質問を見てきましたが、おそらく私が C プログラミングの初心者であるため、回答を読んでもわかりませんでした。コードは次のとおりです。

#include <stdio.h>

char* squeeze(char s[], char c);

main()
{
  printf("%s", squeeze("hello", 'o'));
}

char* squeeze(char s[], char c)
{
  int i, j;

  for(i = j = 0; s[i] != '\0'; i++)
    if(s[i] != c)
      s[j++] = s[i];
    s[j] = '\0';

  return s;
}

コンパイルされ、実行するとセグメンテーション違反が発生します。配列を返すことについてこのよくある質問を読み、そこで提案されている「静的」手法を試しましたが、それでもプログラムを機能させることができませんでした。何が問題なのか、今後何に注意する必要があるのか​​ を誰かが正確に指摘できますか?

4

3 に答える 3

6

スクイーズ関数に渡される最初の引数は、変更しようとしているread-only文字列リテラルです。"hello"

代わりに、変更可能な char 配列を渡します。

char str[] = "hello";
printf("%s", squeeze(str, 'o'));
于 2010-04-13T02:11:53.920 に答える
3

問題は、定数char 配列"hello"が渡された関数によって正しく変更されない可能性があることです。そのため、定数でない配列を渡していることを確認してください (たとえば、squeezeの呼び出し元の外部で結果が必要ない限り、ローカル配列を渡すようにします)。

int main()
{
  char xxx[] = "hello";
  printf("%s", squeeze(xxx, 'o'));

  return 0;
}

そのような定数は引数にのみ渡すことができると予想されますがconst(コンパイラ自体が何が間違っているかを教えてくれるため)、残念ながら、それはC標準で義務付けられているものではありません(おそらく後方互換性の理由から)歴史的なコードで)。

于 2010-04-13T02:11:22.337 に答える
3

これは、変更不可能なデータを変更しようとしています。

「hello」は一定の文字列で、メモリのどこかに格納されています。あなたがやろうとしているのは、それを変更することであり、それは一般的に許可されていません. 「静的」の意味がわかりませんが、必要なものは次のようになります...

int main()
{
  char hello_str[16];
  strcpy(hello_str, "hello");
  printf("%s", squeeze(hello_str, 'o'));
}
于 2010-04-13T02:13:09.070 に答える