0

私は一生、c 文字列と入力/出力に満足することはできません。

私のプログラムでは、単純に文字列を入力すると、次のコードで処理されます: (tmpstring と ch は既に定義されています)

着信入力については、ターミナルに次のように書き込みます。。/プログラム

    int main(int argc, char *argv[]) {
    char tmpstring[2048];
    int ch;
    int r;
    int c;

    fgets(tmpstring, sizeof tmpstring, stdin);
    while((ch = fgetc(stdin))!= EOF && ch != '\n');
    tmpstring[strlen(tmpstring)-1]='\0';

    strncpy(opponent, tmpstring+1, strlen(tmpstring+1));

    move();

move() の内部;

    char buffer[2048]={0};
    int r, c;
    r=0; c=0;
    printf("Your move (row column):");
    if((fgets(buffer, sizeof buffer, stdin)==NULL) || ((sscanf(buffer,"%d %d", &r, &c))!=2)){
            printf("Invalid input. Please insert two numbers separated by whitespace.\n");
            exit(1);
    }
    //continues

これを実行すると、さらに入力を求めることなく、無効な入力に直接入ります。stdin をクリアしてはならない (そしてそれは不可能だ) ことについてはあちこちで読みましたが、どうすればよいか本当にわかりません。while ループの 2 番目の部分で stdin を「ダンプ」しようとしたことは明らかです。最初の条件の後の && を || に変更しました。while ループで。変化なし。全体として、すでに fgets を使用した後、さらに入力を求めるにはどうすればよいですか?

*編集: コードを追加し、元の while ループを分離しました

4

1 に答える 1

0

この種の問題は、他の場所で議論されています。
ここから、自分の投稿の一部をコピーします。

scanf を使用した文字列の最大長 -> ANSI C

  • と を組み合わせてライブラリmy_scanf()を呼び出すことにより、可変数のパラメータを持つ関数が定義されます。 stdarg.hfgets()vsscanf()
  • この関数は、fgets()andの組み合わせを正しい方法で処理するように設計されてsscanf()います (実際にはvsscanf()、引数のリストを適切に処理するために使用する必要があります)。
  • 入力は上限文字数まで読み込まれます。入力がこの制限を超える場合、切り捨てられます。「\n」は正しく処理されます。この関数は、返される値と同じ値をscanf()返します。したがって、代わりに使用できますmy_scanf()

ここにコードがあります:

#include <stdio.h>
#include <stdarg.h>

int my_scanf(const char* fmt, const unsigned int maxbuff, ...) {
    va_list ptr;
    int ret;

    if (maxbuff <= 0)
       return EOF; /* Bad size for buffer[] */

    char buffer[maxbuff+1];
    buffer[maxbuff-1] = '\0';  /* Quick buffer cleaning... */

    if (fgets(buffer, maxbuff+1, stdin) == NULL)
       return EOF; /* Error detected */
    else {
        if ((buffer[maxbuff-1] != '\n') && (buffer[maxbuff-1] != '\0'))
            /* Condition logically equivalent to:
                   fgets() has not reached an '\n'
            */
            while (getchar() != '\n')
               ; /* "Flushing" stdin... */

        va_start(ptr, maxbuff);
        ret = vsscanf(buffer, fmt, ptr);
        va_end(ptr);
        return ret;
    }    
}

#define MAXBUFF 20
int main(void) {
   int x; 
   float z;
   int scanf_ret = my_scanf("%d %g", MAXBUFF, &x, &z);
   printf("\nTest:\n x == %d\n z == %g\n scanfret == %d", x, z, scanf_ret);
   getchar();   
   return 0;   
}

関数 my_scanf() にはプロトタイプがあります

int my_scanf(const char* fmt, const int maxbuff, ...);
  • 他の-like fmtと同じように動作するフォーマット文字列を受け入れます。scanf()
  • 2 番目のパラメーターは、標準入力 (キーボード) から有効に受け入れられる 文字の最大数です。
  • 戻り値はintです。意味がないEOFmaxbuff、何らかの入力エラーが発生した場合です。負でない値が返された場合、標準関数sscanf()またはによって返される値と同じですvsscanf()

    1. 関数内では、'\0' 文字を追加するための余地ができる maxbuffため、1 ずつインクリメントされます。fgets()
    2. の正でない値maxbuffはすぐに破棄されます。
    3. fgets()stdin(keyboard)から文字列を読み取り、maxbuff'\n' を含む最大文字数の余地があります。
    4. ユーザーが非常に長い文字列を入力した場合、文字列は切り捨てられ、次の '\n' ( ENTER )までのすべての文字を破棄するために、ある種の「フラッシュ」メカニズムが必要になります。そうでない場合、次のキーボード読み取りで古い文字が使用される可能性があり、まったく望ましくありません。
      • 「フラッシュ」の条件はfgets()、読み取り後に '\n' に達していないことstdinです。
      • buffer[maxbuff - 1]これは、が '\0' にも '\n' にも等しくない場合にのみ真です。(チェックしてね!
    5. stdarg.h 最後に、マクロと関数の適切な (そして標準的な) 組み合わせをvsscanf()使用して、パラメーターの可変リストを処理します。
于 2013-08-27T05:31:47.077 に答える