Reputation: 421
I'm trying to input a string of characters to a pointer member of char type of an array of structure. The program is terminating after it receives the string for the member name of emp[0]. My code:
#include<stdio.h>
struct Employee
{
char *name;
int salary;
};
int main()
{
struct Employee emp[3];
int i;
for(i=0;i<3;i++)
{
scanf("%s%d",emp[i].name,&emp[i].salary);
}
printf("\nOutput:");
for(i=0;i<3;i++)
{
printf("\n%s%d",emp[i].name,emp[i].salary);
}
return 0;
}
When without array, the following code for some variable emp
is working fine:
scanf("%s%d",emp.name,&emp.salary);
Any suggestions? Thanks in advance.
Upvotes: 0
Views: 2271
Reputation: 2708
By little improvement on others good answers, I want to introduce this version.
malloc()
to ensure success or its failure on allocate some desired memory location(s) on the Heap.
If it fails, any try to access that unallocated memory cause Undefined Behavior.malloc()
in C Why not cast return of malloc() its dangerous, see first answer.#include <stdlib.h>
explicitly when using malloc()
.Code
#include <stdio.h>
#include <stdlib.h>
struct Employee
{
char *name;
int salary;
};
int main(){
struct Employee emp[3];
printf("Enter name, salary\n");
int i;
for(i=0;i<3;i++){
emp[i].name = malloc(40*sizeof(char));
if (emp[i].name != NULL){
scanf("%s %d", emp[i].name, &emp[i].salary);
}else{
///If this accur, try to access inside below for loop is UB
printf("Cant allocate Memory for name[%d]\n", i);
}
}
printf("\nOutput:\n");
for(i=0;i<3;i++)
{
printf("%s: %d\n", emp[i].name, emp[i].salary);
}
///Free allocated memory
printf("Free allocated memory\n");
for(i=0;i<3;i++)
{
free(emp[i].name);
}
return 0;
}
Compile and Run
gcc -Wall so.c -o so && ./so
[Hint]
You must insert an space or hit enter, between Name and salary integer.
Although this works but i recommend to separate scanf()
for each section to get user input for pair of name, salary with hit enter key after each, this is readable, i think.
scanf("%s", emp[i].name);
scanf("%d", &emp[i].salary);
[Notes]
Try to avoid using scanf()
. Thanks for @Jonathan Leffler for providing this link that i steal from
I recommend to take a look at scanf() leaves the new line char in the buffer, leaving a leading space when scan character " %c"
inside scanf()
[ToDo]
"%c"
, "%d"
in scanf()
behavior in scanning, remove buffer.Upvotes: 0
Reputation: 30936
Or you can allocate something to name
before passing it to scanf
.
emp[i].name = malloc(sizeof*emp[i].name*MAX_LEN);
if( !emp[i].name )
// error in malloc.
scanf
tries to write the characters read to the address contained by name
. The address contained by name
is indeterminate (some garbage value). Accessing it calls for undefined behavior.
It works but it is an undefined behavior. The very next time you run the same code it may throw error.
if
after malloc
?In case malloc
fails to provide with the requested memory it returns NULL
. You are checking that to be sure that memory is allocated otherwise you won't access it because it invokes undefined behavior.
yes there are couple of things apart from all this
malloc
. It's unnecessary.free()
).scanf
return value to be sure about whether the scanf
call succedes. Reply to user's comment:
If you have
name[4]
inside struct then you should writescanf("%3s",emp[i].name)
. This3s
limits the characters read byscanf
to3
avoiding buffer overflow. The thing is if you enter more than 3 characters you will read only 3 characters and rest of them will be in input stream.
Note: The question starts with an OR because the other way is what is answered by dbush. I didn't want to repeat it.
Upvotes: 1
Reputation: 29354
You need to initialize char
pointer name
before can point it to a String
entered by user.
#include<stdio.h>
struct Employee
{
char *name;
int salary;
};
int main()
{
struct Employee emp[3];
int i;
for(i=0;i<3;i++)
{
emp[i].name = (char*)malloc(3);
scanf("%s%d",emp[i].name,&emp[i].salary);
}
printf("\nOutput:");
for(i=0;i<3;i++)
{
printf("\n%s%d",emp[i].name,emp[i].salary);
}
return 0;
}
Upvotes: 2
Reputation: 225767
The name
field in struct Employee
is a pointer. You never give that pointer a value, but you pass it to scanf
which then attempts to dereference it. Dereferencing an uninitialized pointer invokes undefined behavior.
Instead of using a char *
for name
, make it an array large enough to hold whatever value you expect:
struct Employee
{
char name[50];
int salary;
};
Upvotes: 2