1

So i have a struct named person with all their information and i want the user to be able to input them and then display it all back to the user. Here is what I have:

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

struct person{
    char name[30];
    char address[30];
    int phoneNumber[30];
    char creditRating[30];
};

int main(){
    struct person p;
    printf("What is the person's name?\n");
    scanf(" %s", p.name);
    printf("What is the person's address?\n");
    scanf(" %s", p.address);
    printf("What is the person's phone number?\n");
    scanf("%d", &p.phoneNumber);
    printf("What is the person's credit rating?\n");
    scanf(" %s", p.creditRating);

    printf("The person's name is %s\n", p.name);
    printf("The person's address is %s\n", p.address);
    printf("The person's phone number is %d\n", p.phoneNumber);
    printf("The person's credit rating is %s\n", p.creditRating);
    return 0;
}

My issue is that it won't properly take in an address that has spaces and numbers. Also, when i input a phone number, it doesn't properly display. All the numbers are random. How do I fix this?

  • 2
    http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf – OldProgrammer Apr 11 '16 at 22:20
  • 2
    `int phoneNumber[30];` is incorrect. Subject does not have 30 phone numbers. And `scanf` with a string type stops at the first whitespace. I suggest having a good read about format specifiers. Ir's quite complicated. – Weather Vane Apr 11 '16 at 22:21
  • I would use `unsigned long long phoneNumber;`, and print it using `%llu`. Weather is right, you don't need an array. – vestlen Apr 11 '16 at 22:45
  • "when i input a phone number, it doesn't properly display" --> Rather than weakly _describe_ the output, post the input, the true output and the expected output. Much more useful. – chux - Reinstate Monica Apr 11 '16 at 22:52
  • Since phone numbers can 1) begin with 0, 2) contain "#*" and 3) sometimes "-" is useful, suggest simply reading the phone number like any other text. Also, robust code avoids `scanf()`. Better to use `fgets()`. – chux - Reinstate Monica Apr 11 '16 at 22:55

2 Answers2

4

One's phone number usually have 11 digits or so, and it's not guaranteed that an int or unsigned long long is large enough to hold it. So I think your struct person should be defined as

struct person {
    char name[30];
    char address[30];
    char phoneNumber[20];
    char creditRating[10];
};

And scanf("%s", str) stops when a whitespace is encountered, can this can be a bug, because people usually have one or more spaces in their names. To input a string containing ' ' , use fgets(str, sizeof str, stdin).

Also, scanf() is buffer-overflow vulnerable, so your program may crash if user input is too long to be hold in the designated array. fgets() gives you buffer overflow protection. Don't forget to remove the tailing '\n' by str[strcspn(str, "\n")] = '\0'; if you're using fgets().


Here is a demo code:

printf("What is the person's name?\n");
fgets(p.name, sizeof p.name, stdin);
p.name[strcspn(p.name, "\n")] = '\0';

printf("The person's name is %s\n", p.name);
nalzok
  • 14,965
  • 21
  • 72
  • 139
1

Writing a helper function allows code to nicely encapsulate user I/O and handle a number of issues.

Recommend use a string for the phone number too. So instead of an array of int, use char phoneNumber[30]. The code can post-process things like - and deal with leading zeros, etc.

// Candidate improvements: cope with long lines, 
// remove need for user buffer to temporarily store the \n
int GetString(char *dest, size_t size, const char *prompt) {
  fputs(prompt, stdout);
  fflush(stdout);
  if (fgets(dest, size, stdin) == NULL) {
    dest[0] = '\0';
    return EOF;
  }
  dest[strcspn(dest, "\n")] = '\0';
  return 0;
}

int main(void) {
  struct person p;
  GetString(p.name,        sizeof p.name,        "What is the person's name?\n");
  GetString(p.address,     sizeof p.address,     "What is the address?\n");
  GetString(p.phoneNumber, sizeof p.phoneNumber, "What is the person's phone number?\n");
  GetString(p.creditRating,sizeof p.creditRating,"What is the person's credit rating?\n");

  printf("The person's name is %s\n", p.name);
  printf("The person's address is %s\n", p.address);
  printf("The person's phone number is %s\n", p.phoneNumber);
  printf("The person's credit rating is %s\n", p.creditRating);
  return 0;
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • I really have to forget scanf... +1 for the helper function, BTW. – Bob__ Apr 11 '16 at 23:23
  • @Bob__ I've been there. I was ready to up-vote you given the comment about `fgets()`, but the `scanf()` implementation has its holes with evil user input. About all production code I use now involves some wrapper to cope with the various weaknesses of C I/O functions. – chux - Reinstate Monica Apr 11 '16 at 23:27