0

So i've done some googling and found that using the code:

#include <stdio.h>

void main()
{
    char ch;

    ch = fgetc(stdin);
    if (ch == '\n')
    {
        printf("\n");
    }
    else
    {
        printf("\n");
    }
}

does exactly what I want to however pasting this code lines in my other project that has scanf_s seems to not prompt for the user input at 'ch = fgetc(stdin)'. I was wondering if there is a way i can change ch = fgetc(stdin) to a scanf code such that it can read ENTER and exit the program.

tadman
  • 208,517
  • 23
  • 234
  • 262
qinder
  • 1
  • 1
  • Are you asking how to use scanf to read a character? Does https://stackoverflow.com/questions/13542055/how-to-do-scanf-for-single-char-in-c answer your question? – Ryan Zhang Jul 17 '22 at 13:48
  • 1
    Note that you should assign the result of `fgetc()`, `getchar()` et al to an `int`, not a `char`. By definition, the functions return more values than can be stored in a `char`. – Jonathan Leffler Jul 17 '22 at 15:01
  • In your question, you wrote: "however pasting this code lines in my other project that has scanf_s seems to not prompt for the user input at 'ch = fgetc(stdin)'" -- Please provide a [mre] which demonstrates the problem with `scanf_s`. – Andreas Wenzel Jul 17 '22 at 15:21
  • 1
    In your question, you wrote: "I was wondering if there is a way i can change `ch = fgetc(stdin)` to a scanf code" -- I suspect that you are asking about an [XY problem](https://xyproblem.info/). I guess that the best solution to your problem would be to stop using `scanf` or `scanf_s` and to use [`fgets`](https://en.cppreference.com/w/c/io/fgets) instead, so that you always read exactly one line of input at once. However, in order to determine with certainty whether this is the problem, we need more information from you. We need a [mre] of your actual problem. – Andreas Wenzel Jul 17 '22 at 15:29
  • You may want to read this: [What can I use for input conversion instead of scanf?](https://stackoverflow.com/q/58403537/12149471). – Andreas Wenzel Jul 17 '22 at 15:32
  • My guess is that your actual problem is similar to the problem in this question: [scanf() leaves the newline character in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-newline-character-in-the-buffer) However, without a [mre] of your actual problem, I can only speculate. – Andreas Wenzel Jul 17 '22 at 15:34

2 Answers2

1

Most scanf specifiers will leave a newline pending in the input stream.
Thus immediately following a scanf, fgetc will consume a newline.

The best I can come up with is to use the scanset %1[\n] to scan a single newline. Scan for the newline afterwards to consume the pending newline and scan before the desired input to get the leading newline that indicates input is complete and exit the loop.

The second loop accomplishes the same effect using fgets.

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

#define LINE 99
//stringify to use in format string
#define SFS(x) #x
#define FS(x) SFS(x)

int main ( void) {
    char text[LINE + 1] = "";
    char newline[2] = "";
    int result = 0;

    while ( 1) {
        printf ( "enter text for scanf\n");
        scanf ( "%*[ \t\r]"); // scan and discard spaces, tabs, carriage return
        if ( 1 == ( result = scanf ( "%1[\n]", newline))) {
            printf ( "\tscanned leading newline\n");
            break;
        }
        if ( 1 == ( result = scanf ( "%"FS(LINE)"[^\n]", text))) {
            //as needed parse with sscanf, strtol, strtod, strcspn, strspn, strchr, strstr...
            printf ( "\tscanned text: %s\n", text);
            scanf ( "%*[ \t\r]"); // scan and discard spaces, tabs, carriage return
            if ( 1 == scanf ( "%1[\n]", newline)) {
                printf ( "\tscanned trailing newline\n");
            }
        }
        if ( EOF == result) {
            fprintf ( stderr, "EOF\n");
            return 1;
        }
    }

    while ( 1) {
        printf ( "enter text for fgets\n");
        if ( fgets ( text, sizeof text, stdin)) {
            if ( '\n' == text[0]) {
                printf ( "----newline only\n");
                break;
            }
            printf ( "----text is:%s\n", text);
            //as needed parse with sscanf, strtol, strtod, strcspn, strspn, strchr, strstr...
        }
        else {
            fprintf ( stderr, "EOF\n");
            return 2;
        }
    }

    return 0;
}
xing
  • 2,125
  • 2
  • 14
  • 10
0

scanf doesn't read the trailing \n for strings but you can read a character with %c:

#include <stdio.h>

int main() {
        char c ; 
        scanf("%c", &c);
        if(c == '\n') {
           // ...
        }
        return 0;
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Allan Wind
  • 23,068
  • 5
  • 28
  • 38