Let's go step by step. In your BillingAddress
struct definition, you intend to store the street, city, and state. It seems logical that you could represent all of those parameters as strings (which are character arrays in C). I believe that is what you tried to do, but the declaration:
char *street[50];
represents give you an array of 50 char *
(i.e., char
pointers) NOT 50 chars
, which is what you actually want. So, the struct definition should instead be:
typedef struct BillingAddress {
char street[50];
char city[25];
char state[3];
int zip;
} address;
You also intend to store the zip. Note how I changed the type of zip
to an int
array rather than an int
array. You could do an int
array, but you would have to do more work to properly accept the user's input (simply using scan("%d", &addr.zip)
will not work).
Now, let's take a looked at a different way to define your definition for ContactInfo
struct:
typedef struct ContactInfo {
char name[30];
int age;
char phone[15];
address addr;
} personaldata;
You can see that I've removed the *
's and changed age
to be a single int
for the similar reasoning as what I mentioned above. I've also replaced struct BillingAddress
with the simpler address
. Why? Because you created a typedef
linking the keyword address
to struct BillingAddress
. So, by using address
alone, the code looks a bit cleaner and you are putting that typedef
to good use :D (Note that there's nothing incorrect about using struct BillingAddress
, I just think it looks cleaner to utilize the typedef
).
Also, you'll see that I renamed the variable of type address
(i.e., of type struct BillingAddress
-- remember the typedef
means these two are the same) to addr
. This makes more sense than naming it PersonalData
as you did, because well, it's an address, not arbitrary personal data.
Now moving onto your main()
method. You should be aware of some of the pitfalls of using scanf()
. Since it reads from the default input stream stdin
(i.e., most likely your terminal), any characters not gulped up by scanf()
will be left in the input stream. So, any subsequent calls to scanf()
will also read in those unwanted characters. See this post for more info. You might not have run into this if you supplied the less than the max number of desired characters, but it is important to take care of this error case. So, after each scanf()
, you should clear the input stream, which can be done using a method like:
void clear_input_stream()
{
int c;
while ((c = fgetc(stdin)) != '\n' && c != EOF);
}
You can call this method after each one of your scanf()
calls.
You want to make sure that if you are writing into a char
array you should not add the &
in front of the variable you are writing to -- check this answer for an explanation (your compiler should warn you about that).
The last thing I want to mention is that you could also add a length to the %d
specifier to limit reading an integer of a certain length. Your main()
could look something like this:
int main()
{
printf("Enter your full name: ");
scanf(" %49[^\n]", data.name);
clear_input_stream();
printf("Enter your age: ");
scanf(" %3d", &data.age);
clear_input_stream();
printf("Enter your Phone Number (xxx) xxx-xxxx: ");
scanf(" %14[^\n]", data.phone);
clear_input_stream();
printf("Enter your street address: ");
scanf(" %49[^\n]", addr.street);
clear_input_stream();
printf("Enter your city: ");
scanf(" %24[^\n]", addr.city);
clear_input_stream();
printf("Enter your state abbreviation: ");
scanf(" %2[^\n]", addr.state);
clear_input_stream();
printf("Enter your zip code: ");
scanf(" %5d", &addr.zip);
clear_input_stream();
printf("Personal Data: \n %s\n %d\n %s\n %s\n %s\n %s\n %d\n", data.name, data.age, data.phone, addr.street, addr.city, addr.state, addr.zip);
return 0;
}