¿Qué significa `scanf(“%*[^\n]%*c”)` significa?

5 minutos de lectura

avatar de usuario
Gustavo Alejandro Castellanos

Quiero hacer un bucle en C que, cuando el programa solicite un número entero y el usuario escriba un carácter que no sea un dígito, el programa vuelva a solicitar un número entero.

Acabo de encontrar el siguiente código. pero no entiendo que significa esto scanf("%*[^\n]%*c"). Que hace ^\n ¿significar? Lo que hace el * antes de ^\n y c ¿significar?

/*

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

avatar de usuario
Spikatrix

Desglose de scanf("%*[^\n]%*c"):

  • %*[^\n] escanea todo hasta que \npero no escanea en el \n. el asterisco(*) le dice que descarte lo que haya escaneado.
  • %*c escanea un solo carácter, que será el \n dejado por %*[^\n] en este caso. El asterisco instruye scanf para descartar el carácter escaneado.

Ambas cosas %[ and %c are format specifiers. You can see what they do here. The asterisks in both the specifiers tell scanf, not to store the data read by these format specifiers.

As @chux commented below, it will clear a single line of the stdin (Standard Input Stream) up to and including the newline character. In your case, the line with invalid input gets cleared from the stdin.


It is better to use

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

para borrar el stdin. Esto se debe a que, en el primer caso (single scanf), %*[^\n] fallará cuando el primer carácter a escanear sea el \n carácter y el resto de la cadena de formato del scanf se omitirá, lo que significa que el %*c no funcionará y, por lo tanto, el \n de la entrada seguirá estando en el flujo de entrada. En este caso, esto no sucederá ya que incluso cuando el primer scanf falla, el segundo se ejecutará ya que están separados scanf declaraciones.

  • Detalle: Esto ciertamente no “despeja el stdin” cuando hay varias líneas de entrada en stdin, pero consumirá entrada hasta el siguiente final de línea inclusive. Por lo general, lo suficientemente bueno para aplicaciones básicas.

    – chux – Reincorporar a Monica

    31 de diciembre de 2018 a las 13:46

avatar de usuario
Gagan Agarval

Puede tomar una cadena como entrada en C usando scanf(“%s”, s). Pero acepta cadenas solo hasta que encuentra el primer espacio.

Para tomar una línea como entrada, puede usar scanf("%[^\n]%*c", s); donde s Se define como char s[MAX_LEN] donde MAX_LEN es el tamaño máximo de s. Aquí, [] es el carácter scanset. ^\n significa tomar entrada hasta que no se encuentre una nueva línea. Entonces, con esto %*clee el carácter de nueva línea y aquí, el usado * indica que este carácter de nueva línea se descarta.

  • Si una línea de entrada sólo consta de "\n", scanf("%[^\n]%*c", s); no lee nada y se va "\n" en stdin. Recomiendo contra este código leer una línea por ese motivo y que no tiene límite de ancho,

    – chux – Reincorporar a Monica

    31 de diciembre de 2018 a las 13:55

avatar de usuario
Debanshu Datta

Supongamos que char sen[max_length] donde la longitud máxima es el tamaño máximo de sen[].

esta escaneo(“%[^\n]%*c”,&sen[]); lo ayudará a obtener una oración completa hasta que no se encuentre la siguiente línea “\norte” o enter se presiona que se hace con la ayuda de “%[^\n]” aquí [ ] es el carácter del conjunto de exploración. los “%*C” leerá el carácter de nueva línea, asterisco ” * ” se utiliza para indicar que se descarta el carácter de la siguiente línea.

avatar de usuario
Pranit Patil

%[^\n]%*c

Lo que leerá todo hasta la nueva línea en la cadena que pase, luego consumirá un solo carácter (la nueva línea) sin asignarlo a nada (ese ‘*’ es ‘supresión de asignación’).

De lo contrario, la nueva línea se deja en el flujo de entrada esperando para terminar inmediatamente el siguiente %[^\n] directivas de formato.

El problema de agregar un carácter de espacio a la directiva de formato (%[^\n]) es que el espacio coincidirá con cualquier espacio en blanco. Por lo tanto, comerá la nueva línea desde el final de la entrada anterior, pero también comerá cualquier otro espacio en blanco (incluidas varias líneas nuevas).

Esencialmente, se trata de dos lecturas usando scanf. La primera parte “%[^\n]” significa ‘leer todo lo que no sea una nueva línea’ y esto se asigna al búfer de caracteres str.

La segunda parte “%*c” significa ‘leer el siguiente carácter pero no guardarlo en ningún lado’; esto elimina la nueva línea que no leímos en la primera parte.

https://www.sololearn.com/Discuss/2249429/cuál-s-el-uso-de-scanf-nc-in-c-programming

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad