The below code runs perfectly with scanf()
, but i want to input characters along with white space. I have tried gets()
and fgets()
(commented below), but its not working (its skipping to next iteration in the loop & displaying blank(NULL) during output for Name input used by fgets()
). Any idea how to do it?
PS: I've tried fputs()
with sample programs, its working fine. But i am little confused while using structure pointer.
#include <stdio.h>
#include <stdlib.h>
struct details {
uint Id;
char Name[20];
};
int main() {
int tot, i;
struct details *info;
printf("Enter no. of details to be stored = ");
scanf("%d", &tot);
info = (struct details *)malloc(tot*sizeof(struct details));
for(i=0; i<tot; i++) {
printf("%d)Id = ", i+1);
scanf("%d", &info->Id);
printf("%d)Name = ", i+1);
fgets(info->Name, 20, stdin); //How to make fgets() work??
//scanf("%s", &info->Name); //works fine with scanf()
info++;
}
for(i=0; i<tot; i++) {
--info;
}
printf("\nDisplaying details:\n");
for(i=0; i<tot; i++) {
printf("%d)Id = %d\n%d)Name = %s\n", i+1, info->Id, i+1, info->Name);
info++;
}
return 0;
}
output:
[xyz@xyz:Temp] $ ./fgets_Struct
Enter no. of details to be stored = 2
1)Id = 111
1)Name = 2)Id = 222
2)Name =
Displaying details:
1)Id = 111
1)Name =
2)Id = 222
2)Name =
[xyz@xyz:Temp] $
The problem comes from the "%d" scanf. It does not consume the line terminator, so the next read will interpret it as an empty line.
Your
info
allocation is wrong too. What you should use to allocate the size is not the size ofinfo
, but the size of an element pointed to byinfo
.Also, tinkering with your
info
pointer is unnecessary and dangerous.Something like that would be simpler and safer
As for scanf / fgets, in your case (with "%s" format given to scanf),
they should both read the input until a new line is entered, spaces included.EDIT: I said something wrong here, sorry and thanks to chux for correcting me.
scanf ("%s")
will indeed stop at the first white space. If you want the whole line, the easiest way is to use fgets. If you really want to use scanf, you'll need a syntax like"%[^\n]%*c"
.To make sure your buffer does not overflow if the user types more than 20 characters, you can either
"%19[^\n]%*c"
asscanf
format (20th character is needed for the '\0' terminator), orfgets
with 20 passed as buffer size (fgets
takes care of the terminator, it will read at most 19 characters to be able to add the '\0' without overflowing).Of course you should use
sizeof
to compute max buffer size, like for instance:Thus you won't have to modify the value if you decide, for instance, to have your buffer size changed to 50 characters.
First, you have a serious bug in your code.
sizeof(info)
returns either 4 or 8 (depending on the platform, 32 or 64 bit), but has nothing to do with your struct size. So you are allocating memory for pointers, but are using that space for your struct. Writing your data into this will overwrite other data in memory (although probably not in that simple example), because you allocate way too few bytes. What you want to use issizeof(struct details)
which would return 24.Now to your input problem. Basically, scanf and gets should not be used together like that. The problem is that scanf reads what you type until you press return, which is not included. When you call gets after that, it sees this return and returns immediately with an empty string. If you change all your input calls to gets, it works perfectly. Example:
I had the same problem! Actually, I came to this page to get the solution and then I remembered the buffer!! So this is the way I solved it:
Cheers!! P.S. cin and cout are from C++ but work like scanf and printf
between the line
scanf()
for ID andfgets()
put the linegetchar()
like this