webentwicklung-frage-antwort-db.com.de

Was bedeutet "scanf ("% * [^\n]% * c ")"?

Ich möchte eine Schleife in C machen, die, wenn das Programm nach einer Ganzzahl fragt und der Benutzer ein nicht-stelliges Zeichen eingibt, das Programm erneut nach einer Ganzzahl fragt.

Ich habe gerade den folgenden Code gefunden. aber ich verstehe nicht was das bedeutet scanf("%*[^\n]%*c"). Was bedeutet ^\n? Was bedeuten der * vor ^\n und die c?

/*

 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;
}

Aufschlüsselung von scanf("%*[^\n]%*c"):

  • %*[^\n] scannt alles bis zu einem \n, scannt aber den \n nicht ein. Das Sternchen (*) weist es an, alles zu verwerfen, was gescannt wurde.
  • %*c scannt ein einzelnes Zeichen, das in diesem Fall der von \n verbleibende %*[^\n] ist. Das Sternchen weist scanf an, das gescannte Zeichen zu verwerfen.

Sowohl %[ als auch %c sind Formatspezifizierer. Sie können sehen, was sie tun hier . Die Sternchen in beiden Bezeichnern weisen scanf an, die von diesen Formatbezeichnern gelesenen Daten nicht zu speichern.

Wie unter @chux kommentiert , wird eine einzelne Zeile der stdin (Standard Input Stream) bis einschließlich des Newline-Zeichens gelöscht. In Ihrem Fall wird die Zeile mit ungültiger Eingabe aus der stdin gelöscht.


Es ist besser zu benutzen

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

um die stdin zu löschen. Dies liegt daran, dass im ersten Fall (einzelne scanf) der %*[^\n] fehlschlägt, wenn das erste zu durchsuchende Zeichen der \n ist und der Rest der Formatzeichenfolge der scanf übersprungen wird, was bedeutet, dass der %*c nicht funktioniert und somit Befindet sich der \n der Eingabe noch im Eingabestream? In diesem Fall tritt dies nicht auf, da selbst dann, wenn die erste scanf ausfällt, die zweite ausgeführt wird, da es sich um separate scanf-Anweisungen handelt.

15
Spikatrix

Sie können eine Zeichenfolge als Eingabe in C mit scanf(“%s”, s) übernehmen. Es akzeptiert jedoch nur Zeichenfolgen, bis das erste Leerzeichen gefunden wird.

Um eine Zeile als Eingabe zu verwenden, können Sie scanf("%[^\n]%*c", s); verwenden, wobei als char s[MAX_LEN] Definiert ist, wobei MAX_LEN Die maximale Größe von s ist. Hier ist [] Das gescannte Zeichen.

  1. ^\n Steht für die Eingabe, bis keine neue Zeile mehr gefunden wird.

  2. Dann liest es mit diesem %*c Das Zeilenumbruchzeichen und hier zeigt das verwendete * An, dass dieses Zeilenumbruchzeichen verworfen wird.

Beachten Sie außerdem Folgendes: Nach der Eingabe des Zeichens und der Zeichenfolge funktioniert die Eingabe des Satzes mit der oben genannten Anweisung nicht mehr. Dies liegt daran, dass am Ende jeder Zeile ein neues Zeilenzeichen \n Vorhanden ist. Daher funktioniert die Anweisung: scanf("%[^\n]%*c", s); nicht, da die letzte Anweisung ein Zeilenumbruchzeichen aus der vorherigen Zeile liest. Dies kann auf verschiedene Arten geschehen. Eine davon ist: scanf("\n"); vor der letzten Anweisung.

2

Sie können eine Zeichenfolge als Eingabe in C verwenden, indem Sie scanf(“%s”, s) verwenden. Es akzeptiert jedoch nur Zeichenfolgen, bis das erste Leerzeichen gefunden wird.

Um eine Zeile als Eingabe zu verwenden, können Sie scanf("%[^\n]%*c", s); verwenden, wobei s als char s[MAX_LEN] definiert ist, wobei MAX_LEN die maximale Größe von s ist. Hier ist [] das gescannte Zeichen. ^\n steht für die Eingabe, bis keine neue Zeile mehr gefunden wird. Dann liest es mit diesem %*c das Zeilenumbruchzeichen und hier zeigt der verwendete * an, dass dieses Zeilenumbruchzeichen verworfen wird.

0
Gagan Agarwal

Angenommen, char sen [max_length] wobei die maximale Länge die maximale Größe von sen [] ist.

dies scanf ("% [^\n]% * c", & sen []); hilft Ihnen dabei, einen ganzen Satz zu erhalten, bis die nächste Zeile nicht mehr angetroffen wird "\ n ” oder enter wird gedrückt, was mit Hilfe von “% [^\n] ” hier [] der gescannte Buchstabe erfolgt. das ”% * c” liest das Zeilenumbruchzeichen, das Sternchen ”*” zeigt an, dass das nächste Zeilenzeichen verworfen wird.

0
Debanshu Datta

%[^\n]%*c

Der liest alles bis zur neuen Zeile in die Zeichenfolge, die Sie übergeben, und verbraucht dann ein einzelnes Zeichen (die neue Zeile), ohne es irgendetwas zuzuweisen (das '*' ist 'Zuweisungsunterdrückung').

Andernfalls bleibt die neue Zeile im Eingabestream und wartet darauf, dass das nachfolgende %[^\n] Formatanweisungen.

Das Problem beim Hinzufügen eines Leerzeichens zur Formatanweisung (%[^\n]) ist, dass das Leerzeichen mit jedem Leerzeichen übereinstimmt. Daher wird die neue Zeile ab dem Ende der vorherigen Eingabe verwendet, es werden jedoch auch alle anderen Leerzeichen (einschließlich mehrerer neuer Zeilen) verwendet.

0
Pranit Patil