Home > Net >  What is the C equivalent of C language's scanf("%*c")?
What is the C equivalent of C language's scanf("%*c")?

Time:01-27

Objective :

  • Simplest and similar way to discard any unwanted (which in my case is every non numeric characters but I'd like a solution for a more general case) and remove them from buffer. Example,
#include<stdio.h>
void main(void){
    int num1, num2;
    
    printf("Enter num1 here : ");
    scanf("%d%*[^\n]%*c", &num);//First scanf statement.
    
    printf("Enter num2 here : ");
    scanf("%d", &num2);//Second scanf statement.
    
    printf("num1  is : %d\n
            num2 is : %d", num, num2);
}

    /* OUTPUT */
    1st number : 25 asdfasfasfasf
    2nd number : 30
    Input 1 : 25
    Input 2 : 30
    /* This will work by discarding any non */
    /* In the program above I didn't write a printf statment to display the text "1st num, 2nd num". This is just so the output is a bit more clear. I am aware of it.  */

Now if you change the first scanf from scanf("%d%[^\n]%*c"); to scanf("%d"); and give the same input, you'd get the following output :

#include<stdio.h>

void main(void){
    int num1, num2;

    printf("Enter num1 here : ");
    scanf("%d", &num1);
    
    printf("Enter num2 here : ");
    scanf("%d", &num2);

    printf("num1 : %d\nnum2 : %d", num1, num2);
}
    //OUTPUT//
    Enter num1 here : 11 awerwe 
    Enter num2 here : num1 : 11
    num2 : 32764
   /*As you might see, I am not prompted for 2nd input. Instead the already present characters in the buffer are used.*/

Briefing :

  • In C scanf("%d%[^\n]%*c"); would remove all the redundant characters like spaces, newline, alphanumeric that come after the number form the buffer before/ after taking another input. How can I achieve the same in C where after my cin >> var; would take the remaining characters in the buffer and then discard them. This only works for numbers from 0-9. But what I am interested in is the *[\n] and *c because it helps me read the characters from buffer without saving them anywhere which technically means that they get discarded.

Exclusions :

  • cin >> ws;
  • cin.ignore(numeric_limits::max(),’\n’);

I've found the aforementioned ways but unless there is no other more viable option available I'd rather not use these since it involves including external libraries #limits and #vector receptively.

CodePudding user response:

In C scanf("%[^\n]%*c"); would remove all the redundant characters like spaces, newline, alphaNumerics form the buffer before/ after taking another input.

This is amiss in so many ways.

  1. "%[^\n]%*c" scans 1 or more non-'\n' (Attempting to save them) and then 1 '\n'. There must exist a leading non-'\n' else the scanning stops. There is nothing special about spaces and alphanumeric - just '\n' and non-'\n'.

  2. Undefined behavior: "%[^\n]" lacks a matching pointer to save the input. Even with a matching char *, it lacks a width and is prone to buffer overflow. It is worse than gets().

  3. With an input of only "\n", nothing is consumed, nothing is saved. scanf("%[^\n]%*c"); fails to consume anything if the first character is a '\n'. Without checking the return value, the calling code does not know if anything was read. The matching char *, if it was there, is unchanged or potentially indeterminate.

Do not use scanf("%[^\n]%*c"); or its C equivalent std::scanf("%[^\n]%*c");

CodePudding user response:

Using C 20 onwards, you might want to use std::format. This is basically an implementation of FMT into the standard C .

For more complex scenarios regular expressions should help.

  •  Tags:  
  • Related