0

各文字を個別に保持して、Cの配列に文字列を格納する方法に困惑しています。例として、ユーザーが を入力した場合、 、 、などを使用して、hellop特定の配列に格納したいと考えています。これは簡単なことだとわかっていますが、私はまだ初心者です。誰かが助けてくれれば、それは素晴らしいことです。ポインターを使用してこれを行う方法を説明してください。userTextuserText[0] = huserText[1] = euserText[2] = l

#include<stdio.h>
void main()
{
    char a[10],c;
    int i=0;
    while((c=getchar())!='\n')
    {
        scanf("%c",&a[i++]);
        c=getchar();
     }
     for(i=0;i<11;i++)
         printf("%c",a[i]);
}

と入力すると、プログラムはガベージ値 ( eoeoeoeo\363) を出力しhellopます。

4

3 に答える 3

10

入力を読み取るには、fgets関数を使用することをお勧めします。これは、 の優れた安全な代替手段scanfです。

まず、次のようにバッファを宣言しましょう。

char user_input[20];

次に、次の方法でコマンドラインからユーザー入力を取得できます。

fgets(user_input, 20, stdin);

これにより、最大 20 文字が標準入力から文字列に格納され、null で終了することが保証されます。入力を前に宣言した配列のサイズに制限したという事実により、バッファー オーバーランの可能性がなくなります。

次に、 strlenを使用して文字列に入力された厄介な改行をクリアしましょう。

user_input[strlen(user_input) -1] = '\0';

Asは null ターミネータまでstrlenの文字列のサイズを返しますが、それがなければ、その位置に改行文字 ( ) があることを確認できます。文字列がそこで終わるように、null-terminator( ) に置き換えます。\n\0

最後に、 printfを使用して印刷しましょう。

printf("The user has entered '%s'\n", user_input);

使用するには、次のヘッダーを宣言する必要がfgetsありprintfます。

#include <stdio.h>

別のヘッダーが必要です。strlenつまり、次のとおりです。

#include <string.h>

ジョブ完了。

PS質問に追加したコードに対処できる場合。

  1. mainは通常、何らかの種類の値を返すことも必要とするのでint mainはなく、として宣言されます。小さなアプリの場合、通常、閉じ中括弧の直前に配置されます。この戻り値は、プログラムが正常に実行されたかどうかを OS に示すために使用されます (0 はすべてが正常であることを意味し、ゼロ以外は問題があったことを意味します)。void mainmainreturn 0;

  2. 文字列を null で終了していません。つまり、注意深いループ以外の方法で読み取ると、問題が発生します。

  3. ユーザーからの入力を2getchar受け取りますscanf

コードを使用することを主張する場合は、少し変更しました。

#include<stdio.h>
int main()
{
    char a[10];
    int i=0;
    while( (a[i++]=getchar()) != '\n' && i < 10) /* take input from user until it's a newline or equal to 10 */
        ;
     a[i] = '\0'; /* null-terminate the string */
     i = 0;  
     while(a[i] != '\0') /* print until we've hit \0 */
         printf("%c",a[i++]);

     return 0;
}

これで動作するはずです。

于 2013-07-06T15:19:11.927 に答える
2

あなたのコードはこれです(読みやすくするためにたくさんのスペースを追加したことを除いて):

 1  #include <stdio.h>
 2  void main()
 3  {
 4      char a[10], c;
 5      int i = 0;
 6      while ((c = getchar()) != '\n')
 7      {
 8          scanf("%c", &a[i++]);
 9          c = getchar();
10      }
11      for (i = 0; i < 11; i++)
12          printf("%c", a[i]);
13   }

行ごとの分析:

  1. OK (これで、 と の間にスペースが追加されました#include) <stdio.h>
  2. main()関数は を返しますint
  3. わかりました(開き括弧を間違えるのは難しいです)。
  4. の戻り値は でgetchar()あるため、別途 としてint宣言する必要があります。cint
  5. わかった。
  6. EOF を考慮する必要があります。する必要がありますwhile ((c = getchar()) != EOF && c != '\n')。ただし、バッファオーバーフローに対してはまだ非常にオープンです。
  7. わかった。
  8. 良くないですよ。これは標準入力から別の文字を読み取り、EOF をチェックしません。
  9. 良くないですよ。これも標準入力から別の文字を読み取ります。しかし、ループの先頭に戻ると、別の文字が読み取られます。したがって、現状abcdefgでは、プログラムで入力すると、ループ コントロールでがc割り当てられ、次に is が割り当てられ、次にis が割り当てられ、ループは get で繰り返されます。6 文字と改行を入力すると、ループは正常に終了します。私は 7 文字を入力したと主張したので、3 回目の繰り返しでは改行ではない に割り当てられ、改行が取得され、プログラムはループの最後にあるステートメントでさらに入力を待ちます。'a'a[0]'b'c'c'a[1]'e''g'ca[2]c = getchar();
  10. OK (右中括弧も同様)。
  11. 良くないですよ。ループの早期終了を考慮せず、無条件a[10]に配列の存在しない要素にアクセスしますa(要素は 0..9 しかありません — C は BASIC ではありません!)。
  12. わかった。
  13. おそらく、forループの後に改行を出力する必要があります。return 0;の最後にする必要がありmain()ます。

入力バッファーが非常に短いため、長さチェックをコーディングするのが最善です。もしあなたが を使っていchar a[4096];たなら、私はおそらくあなたを悩ませることはなかったでしょう (それでも、バッファ オーバーフローの小さなリスクがあり、望ましくない結果を招く可能性があります)。これらはすべて、次のことにつながります。

#include <stdio.h>

int main(void)
{
    char a[10];
    int c;
    int i;
    int n;
    for (i = 0; i < sizeof(a) && ((c=getchar()) != EOF && c != '\n')
        a[i++] = c;
    n = i;
    for (i = 0; i < n; i++)
        printf("%c", a[i]);
    putchar('\n');
    return 0;
}

元のコードも改訂されたコードも null が文字列を終了しないことに注意してください。所定の使用法については、それで問題ありません。一般的な使用ではありません。

改訂されたコードの最後のforループと次の部分putchar()は、(安全に) 次のように置き換えることができます。

printf("%.*s\n", n, a);

これは長さが指定されているのでprintf()、初期化されたデータを超えることはないので安全です。null で終了する文字列を作成するには、入力コードに十分なスペースを残す必要があります。

    for (i = 0; i < sizeof(a)-1 && ((c=getchar()) != EOF && c != '\n')
        a[i++] = c;
    a[i] = '\0';

(注意してくださいsizeof(a)-1!)

于 2013-07-06T17:03:22.053 に答える