Text looks full of trash after typing

0

I started creating a data collection and usage application with the following code:

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

int main() {
    int idade = 0;
    char nome[20];

    printf("Hello! How old are you? ");
    scanf("%d", &idade);
    while (idade == 0) {
        printf("\nAge cannot be 0 nor be decimal. Re-enter your age: ");
        scanf("%d", &idade);
    }
    printf("And what's your name? (write up to 20 characters, only 1st name) ");
    scanf("%[^\n]s", nome);
    printf("\nHello %s, aged %d!\n", nome, idade);

    return 0;
}

But after compiling with GCC, the output is:

Hello! How old are you? 123
And what's your name? (write up to 20 characters, only 1st name) 
Hello �����dU��m�, aged 123!

What do I have to change?

    
asked by anonymous 06.08.2018 / 00:50

3 answers

4

The code has some problems. I will solve some, but it is not yet a robust code because it does not test other problems, I will not go into these issues.

One problem is that to read text with white space you need to use fgets() , and need to handle the change of line that must be changed to a terminator. Which leads to another problem: if you want 20 characters you need to reserve 21 bytes of buffer . And scanf() needs to get a pattern with the new line so it does not leave dirt in buffer .

At least this is a solution:

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

int main() {
    int idade = 0;
    printf("Hello! How old are you? ");
    scanf("%d\n", &idade);
    while (idade == 0) {
        printf("\nAge cannot be 0 nor be decimal. Re-enter your age: ");
        scanf("%d", &idade);
    }
    char nome[21];
    fgets(nome, 20, stdin);
    nome[strcspn(nome, "\n")] = 0;
    printf("\nHello %s, aged %d!\n", nome, idade);
}

See running on ideone . Also put it in GitHub for future reference .

You can use a trick with scanf() , but understand that in real codes this function is rarely used for free data entry:

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

int main() {
    int idade = 0;
    printf("Hello! How old are you? ");
    scanf("%d\n", &idade);
    while (idade == 0) {
        printf("\nAge cannot be 0 nor be decimal. Re-enter your age: ");
        scanf("%d", &idade);
    }
    char nome[21];
    scanf(" %[^\n]s", nome);
    printf("\nHello %s, aged %d!\n", nome, idade);
}

See running on ideone . Also put it on GitHub for future reference .

    
06.08.2018 / 02:06
3

Problem

This problem is very common for those who are starting or not very much in the subject, and it is related to the way that scanf with %d works.

If you repair scanf with %d does not consume the line break , and so lets do something like:

int x, y, z;
scanf("%d", &x);
scanf("%d", &y);
scanf("%d", &z);

And then enter the values separated by space, like this:

10 20 30

It's important to note that you just pressed Enter once but you were able to do 3 reads, for the simple reason that they do not consume your line break.

See this example in Ideone

So in your code, first read the age:

scanf("%d", &idade);

But Enter is in the input buffer and when it will read nome with:

scanf("%[^\n]s", nome);

The first and only thing to catch is Enter , because reading with %[^\n] is until you get \n .

Solution

The solution is to consume the line break. You have at least two simple ways to do this:

06.08.2018 / 01:59
1

Hello, just add this line before the scanf of the name setbuf(stdin, NULL);

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

int main() {

int idade = 0;
char nome[20];

printf("Hello! How old are you? ");
scanf("%d", &idade);
while (idade == 0) {
    printf("\nAge cannot be 0 nor be decimal. Re-enter your age: ");
    scanf("%d", &idade);
}
printf("And what's your name? (write up to 20 characters, only 1st name) ");
setbuf(stdin, NULL);    
scanf("%[^\n]s", nome);
printf("\nHello %s, aged %d!\n", nome, idade);

return 0;

}

    
06.08.2018 / 01:03