2

I'm trying to read some strings from keyboard and save them to the arrays. I specified maximum number of characters to be read and clear buffer after middle initials to discard all character and exceed limit. Everything seems fine as soons as I type more than maximum characters. But what if I type less than maximum? I get and additional empty line. It seems like program is waiting for input, and I don't know why. Can somebody shed the light on this shadow of my knowledge?

Here is my code snippet

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


int main(void)
{
    char name[35];
    char middlename[7];
    char lastname[35];

    printf("Please enter name: ");
    scanf("%34[^\n]%*c", name);

    printf("Please enter middle name: ");
    scanf("%6[^\n]%*c", middlename);
    while (getchar() != '\n');

    printf("Please enter last name: ");
    scanf("%34[^\n]%*c", lastname);
}

This is my output :

Please enter name: Antony
Please enter middle name: Jr.
_ // here it waits for input
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
Gipsy King
  • 186
  • 2
  • 2
  • 14
  • 1
    What is the purpose of `while (getchar() != '\n');` in the code? – Thomas Jager Jul 26 '21 at 13:15
  • @ThomasJager if I dont clear buffer and enter more then 6 character it shows me incorrect output skipping last name section – Gipsy King Jul 26 '21 at 13:18
  • Remove the second %*c specifier and forget about it forever. Before each subsequent input, clear the buffer with the help of - while (getchar ()! = '\n' ); – Генс Jul 26 '21 at 13:29

3 Answers3

3

In each call of scanf like this

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

remove the second conversion specifier

scanf("%34[^\n]", name);

and instead of it use the loop

while (getchar() != '\n');

Otherwise for example in this code snippet

scanf("%6[^\n]%*c", middlename);
while (getchar() != '\n');

you are trying to read the new line character '\n' two times.

Another approach is the following

printf("Please enter name: ");
scanf("%34[^\n]%*[^\n]", name);

printf("Please enter middle name: ");
scanf(" %6[^\n]%*[^\n]", middlename);

printf("Please enter last name: ");
scanf(" %34[^\n]*[^\n]", lastname);

Pay attention to the blank in the second and the third calls of scanf that precedes the first format specifier.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • @WeatherVane He wants to clear the buffer if the user entered more characters than expected. – Vlad from Moscow Jul 26 '21 at 13:23
  • I saw that after: it was because the input was truncated - not for whitespace. If there is only the newline, then the original code will be waiting on non-existant input. – Weather Vane Jul 26 '21 at 13:28
2

Another function could be use to take input using fgetc.
Fill the array as long as there is room.
Read and discard extra characters. This reports that to the user. It is possible to discard the entire input as ask the user to try again.

#include <stdio.h>
#include <string.h>

int fgetcstr ( char *input, size_t size, FILE *fin) {
    int c = 0;
    int used = 0;
    int extra = 0;

    while( EOF != ( c = fgetc ( fin))) {//read until end of file
        if ( c == '\n') {
            break;//stop on newline
        }
        if ( used < size - ( size > 1)) {
            input[used] = c;//store character
            used++;//increment for next character
            if ( size > 1) {
                input[used] = 0;//zero terminate
            }
        }
        else {
            ++extra;
        }
    }
    if ( EOF == c && 0 == used) {//end of file and no characters read
        return EOF;
    }
    if ( extra) {
        printf ( "entered %d characters. only %zu allowed.\n\tExtra DISCARDED\n"
        , extra + used, size - ( size > 1));
        extra = 0;
        used = 0;
    }
    return 1;
}

int main ( void) {
    char name[35] = "";
    char middlename[7] = "";
    char lastname[35] = "";

    printf("Please enter name: ");
    fflush ( stdout);
    if ( EOF == fgetcstr ( name, sizeof name, stdin)) {
        fprintf ( stderr, "EOF\n");
        return 0;
    }
    printf("Please enter middle name: ");
    fflush ( stdout);
    if ( EOF == fgetcstr ( middlename, sizeof middlename, stdin)) {
        fprintf ( stderr, "EOF\n");
        return 0;
    }
    printf("Please enter last name: ");
    fflush ( stdout);
    if ( EOF == fgetcstr ( lastname, sizeof lastname, stdin)) {
        fprintf ( stderr, "EOF\n");
        return 0;
    }
    printf ( "name: %s\n", name);
    printf ( "middlename: %s\n", middlename);
    printf ( "lastname: %s\n", lastname);

    return 0;
}
user3121023
  • 8,181
  • 5
  • 18
  • 16
0

A colleague explained everything correctly higher on the page. The fact that modifier ( * ) - suppresses the input of the next specifier is a good idea, but not for this case. Your code is slightly conflicting with itself. Do this and the program will work well.

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main(void)
{
char name[35];
char middlename[7]; 
char lastname[35];
printf("Please enter name: "); 
scanf(" %34[^\n]", name); 
printf("Please enter middle name: "); 
while (getchar() != '\n');
scanf(" %6[^\n]", middlename);
printf("Please enter last name: "); 
while (getchar() != '\n');
scanf(" %34[^\n]", lastname);
while (getchar() != '\n');
 //Development of events
    return 0;
}
Генс
  • 93
  • 5