web-dev-qa-db-ja.com

`scanf("%* [^ \ n]%* c ")`はどういう意味ですか?

Cでループを作成したいのですが、プログラムが整数を要求し、ユーザーが数字以外の文字を入力すると、プログラムは再び整数を要求します。

以下のコードを見つけました。しかし、これがscanf("%*[^\n]%*c")の意味を理解できません。 ^\nの意味? *の前の^\ncはどういう意味ですか?

/*

 This program calculate the mean score of an user 4 individual scores,
 and outputs the mean and a final grade
 Input: score1, score2,score2, score3
 Output: Mean, FinalGrade

*/
#include <stdio.h>
//#include <stdlib.h>

int main(void){
  int userScore = 0; //Stores the scores that the user inputs
  float meanValue = 0.0f; //Stores the user mean of all the notes
  char testChar = 'f'; //Used to avoid that the code crashes
  char grade = 'E'; //Stores the final 
  int i = 0; //Auxiliar used in the for statement

  printf("\nWelcome to the program \n Tell me if Im clever enough! \n Designed for humans \n\n\n");
  printf("Enter your 4 notes between 0 and 100 to calculate your course grade\n\n");

  // Asks the 4 notes. 
  for ( ; i<=3 ; i++ ){
    printf("Please, enter your score number %d: ", i+1);

    //If the note is not valid, ask for it again

    //This is tests if the user input is a valid integer.
    if ( ( scanf("%d%c", &userScore, &testChar)!=2 || testChar!='\n')){
      i-=1;
      scanf("%*[^\n]%*c");

    }else{ //Enter here if the user input is an integer
      if ( userScore>=0 && userScore<=100 ){
    //Add the value to the mean
    meanValue += userScore;
      }else{ //Enter here if the user input a non valid integer
    i-=1;
    //scanf("%*[^\n]%*c");
      }    
    }
  }

  //Calculates the mean value of the 4 scores
  meanValue = meanValue/4;

  // Select your final grade according to the final mean
  if (meanValue>= 90 && meanValue <=100){
    grade = 'A';
  } else if(meanValue>= 80 && meanValue <90){
    grade = 'B';
  } else if (meanValue>= 70 && meanValue <80){
    grade = 'C';
  } else if(meanValue>= 60 && meanValue <70){
    grade = 'D';
  }
  printf("Your final score is: %2.2f --> %c \n\n" , meanValue, grade);

  return 0;
}

scanf("%*[^\n]%*c")の内訳:

  • %*[^\n]\nまですべてをスキャンしますが、\nはスキャンしません。アスタリスク(*)は、スキャンされたものをすべて破棄するように指示します。
  • %*cは単一の文字をスキャンします。この場合、\nが残した%*[^\n]になります。アスタリスクは、スキャンされた文字を破棄するようにscanfに指示します。

%[%cはどちらも形式指定子です。あなたは彼らが何をしているのか見ることができます ここ 。両方の指定子のアスタリスクは、scanfにこれらの形式指定子によって読み取られたデータを格納しないように指示します。

@ chuxは以下でコメント のように、改行文字までのstdin(標準入力ストリーム)の単一行をクリアします。あなたの場合、無効な入力のある行はstdinからクリアされます。


使う方がいい

scanf("%*[^\n]");
scanf("%*c");

stdinをクリアします。これは、前者の場合(単一のscanf)、スキャンされる最初の文字が%*[^\n]文字である場合に\nが失敗し、scanfの残りのフォーマット文字列がスキップされるためです。 %*cは機能しないため、入力からの\nは引き続き入力ストリームに存在します。この場合、最初のscanfが失敗しても2番目のscanfステートメントが別々であるため、2つ目が実行されるため、これは発生しません。

20
Spikatrix

scanf(“%s”, s)を使用すると、Cで文字列を入力として取得できます。ただし、最初のスペースが見つかるまで、文字列を受け入れます。

入力として行を取得するには、scanf("%[^\n]%*c", s);を使用できます。ここで、_char s[MAX_LEN]_は_MAX_LEN_はsの最大サイズです。ここで、_[]_はスキャンセット文字です。

  1. _^\n_は、改行が検出されなくなるまで入力を取ることを意味します。

  2. 次に、この_%*c_を使用して改行文字を読み取ります。ここで、使用された_*_は、この改行文字が破棄されることを示しています。

また、注意:文字と文字列を入力した後、上記のステートメントによる文の入力は機能しません。これは、各行の終わりに改行文字_\n_が存在するためです。したがって、最後のステートメントは前の行から改行文字を読み取るため、ステートメントscanf("%[^\n]%*c", s);は機能しません。これはさまざまな方法で処理でき、その1つは次のとおりです。最後のステートメントの前のscanf("\n");

2

scanf(“%s”, s)を使用すると、Cで文字列を入力として取得できます。ただし、最初のスペースが見つかるまで、文字列を受け入れます。

入力として行を取得するには、scanf("%[^\n]%*c", s);を使用できます。ここで、sは_char s[MAX_LEN]_として定義されます。ここで、_MAX_LEN_はsの最大サイズです。ここで、_[]_はスキャンセット文字です。 _^\n_は、改行が検出されなくなるまで入力を取ることを意味します。次に、この_%*c_を使用して改行文字を読み取ります。ここで、使用された_*_は、この改行文字が破棄されることを示しています。

0
Gagan Agarwal

Char sen [max_length]で、最大長がsen []の最大サイズであるとします。

this scanf(“%[^\n]%* c”、&sen []);は、次の行が検出されなくなるまで文全体を取得するのに役立ちます“\n ”または“%[^\n]”ここで[]を使用してEnterキーを押すと、スキャンセット文字になります。 ”%* c”は改行文字を読み取り、アスタリスク” *”は次の行文字が破棄されることを示すために使用されます。

0
Debanshu Datta

%[^\n]%*c

これは、改行まですべてを渡した文字列に読み込み、何も割り当てずに1文字(改行)を消費します(「*」は「割り当て抑制」です)。

それ以外の場合、改行は入力ストリームに残され、後続の%[^\n]形式ディレクティブ。

フォーマットディレクティブにスペース文字を追加する際の問題(%[^\n])は、スペースが任意の空白と一致することです。したがって、前の入力の最後から改行を使用しますが、他の空白(複数の改行を含む)も使用します。

0
Pranit Patil