1

I tried to do a small Worker Register, but it skips completely the second scanf, which gets address value. I am a beginner, so I do not know what I am doing wrong. Here is the code:

#include <stdio.h>

int main()
{
    // var
    char n[256], ad[256]; // n - Name, ad - Address
    int i, ag; // i - Income, ag - Age
    // code
    printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
    scanf("%255[^\n]", n);
    printf("Address: ");
    scanf("%255[^\n]", ad);
    printf("Age: ");
    scanf("%d", &ag);
    printf("Income: R$");
    scanf("%d", &i);
    printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
    return 0;
}

I really appreciate any help you can provide!

MD XF
  • 7,860
  • 7
  • 40
  • 71
Gibas
  • 55
  • 1
  • 7

3 Answers3

1

Just simply add a getchar(); To be honest, I don't know why but this has happened to me plenty of times in school. It seemed to fix it :)

code:

#include <stdio.h>
int main()
{
    // var
    char n[256], ad[256]; // n - Name, ad - Address
    int i, ag; // i - Income, ag - Age
               // code
    printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
    scanf("%255[^\n]", n);
    printf("Address: ");
    getchar();
    scanf("%255[^\n]", ad);
    printf("Age: ");
    scanf("%d", &ag);
    printf("Income: R$");
    scanf("%d", &i);
    printf("Worker %s\nAddress: %s\nAge: %d\nIncome: R$%d", n, ad, ag, i);
    return 0;
}
Nad
  • 11
  • 2
  • What getchar() really do? @Edit: What library I need to put to use it? – Gibas Nov 03 '16 at 03:05
  • 1
    It might be kind to explain why you don't need a `getchar()` after reading `ad` — you're right, you don't absolutely need it, but it isn't immediately obvious why not. Were it my code, it would be there for reasons of symmetry. You should probably also check that `scanf()` works rather than just assuming that it does. – Jonathan Leffler Nov 03 '16 at 03:12
  • Not sure but you can read more [link](http://stackoverflow.com/questions/3676796/what-does-getchar-exactly-do)**Here** – Nad Nov 03 '16 at 03:14
  • I read that thread already but I think it speaks of a special case. – Gibas Nov 03 '16 at 03:32
  • If the first character is `'\n'` for `scanf("%255[^\n]", n);` leads to trouble - UB. Checking the return value of `scanf()` is good programming. – chux - Reinstate Monica Nov 03 '16 at 15:30
1

Nad's hack of adding a getchar() seems to fix it, but I wouldn't use scanf for reading strings if I were you.

It's nicer to use fgets() reading strings instead. scanf on a string is problematic. See: Reading a string with scanf

e.g.

 #include <stdlib.h>
 ...
 printf("Welcome to the Worker Register\n\nWorker Data\n\nName: ");
 fgets(n, 256, stdin);
 ...

Regarding the size parameter in fgets(). The man page states:

fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte ('\0') is stored after the last character in the buffer.

Therefore you enter the size of the buffer and ignore the null byte as fgets will do that work for you.

Community
  • 1
  • 1
hookenz
  • 36,432
  • 45
  • 177
  • 286
  • Yes, I read that thread and some threads like it, but I am in the beginning of my C course, so I do not even know what is a pointer. I tried learning it, but I couldn't understand it very well, so I will put aside for now and when I study it I will come back. Thank you! @Edit: fgets is from what library? – Gibas Nov 03 '16 at 03:26
  • `fgets()` is in the same library as `scanf()`. – chux - Reinstate Monica Nov 03 '16 at 15:31
  • Regarding about buffer overflow, shouldn't I put "fgets(n, 255, stdin);" instead of "fgets(n, 256, stdin);"? – Gibas Nov 03 '16 at 16:49
0

"%255[^\n]" meant input up to newline(accepts inputs other than newline).(The newline isn't included.)
So, there is a newline in the input buffer(of stdin),
second scanf (scanf("%255[^\n]", ad); ) also accepts inputs other than newline,
So, It will not be entered.

Therefore you need to consume the newline in first scanf.
E.g scanf("%255[^\n]%*c", n); %*c ignores one character(That is the newline).

Since %d of 3rd scanf skips the previous white-spaces, %*c isn't necessary for 2nd scanf.

BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70