0

The instruction wanted me to read and store the C string value the user enters into the appropriate Name member.

Code

struct Name {
    char firstName[31];
    char middleInitial[7];
    char lastName[36];
};



struct Name coolname={{0}};

printf("Please enter the contact's first name: ");
scanf("%31s[^\n]", coolname.firstName); 

Two questions:

  • Did i read and store the c string value correctly?
  • Are there any other ways of doing it and cons pros?
EsmaeelE
  • 2,331
  • 6
  • 22
  • 31
whatever
  • 11
  • 2

1 Answers1

1

's' not needed: scanf("%31s[^\n]", coolname.firstName); attempts to read input without spaces up to 31 characters and then read a [, ^, any white spaces, ].

Certainly a no-'s' is one step better: scanf("%31[^\n]"... as that will attempt to read up to 31 non-'\n' chracters.

Yet this will not consume the trailing '\n'.


Recommend to read all user input with fgets(). Perhaps as a helper function.

int read_line(const char *prompt, char *dest, size_t n) {
  fputs(prompt, stdout);
  fflush(stdout);

  dest[0] = '\0';
  char buf[n*2 + 2];
  if (fgets(buf, sizeof buf, stdin) == NULL) return EOF;

  size_t len = strlen(buf);
  if (len > 0 && buf[len - 1] == '\n') { // lop off potential \n
    buf[--len] = '\0';  
  }

  if (len >= n) { //  maybe add a `len == 0` test
    return 0; // indicate invalid input, 
  }

  strcpy(dest, buf);
  return 1; 
}

Now use the helper function

if (read_line("Please enter the contact's first name: ", coolname.firstName, sizeof coolname.firstName) == 1) {
  // Oh happy day, got first name
}
if (read_line("Please enter the contact's middle name: ", coolname.middleInitial, sizeof coolname.middleInitial) != 1)) {
  // Oh happy day, got middle name
}
if (read_line("Please enter the contact's last name: ", coolname.lastName, sizeof coolname.lastName) != 1)) {
  // Oh happy day, got last name
}
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • Excellent answer! – EsmaeelE Mar 09 '19 at 21:41
  • Is `scanf("%31s[^\n]", coolname.firstName);` version consume `\n` in string that stored? – EsmaeelE Mar 09 '19 at 21:44
  • @EsmaeelE No. Think of `"%31s[^\n]"` as `"%31s"`followed by an attmept to scan 4 things `"["`, `"^"`, `"\n"`, `"]"`. It is **not** what you want. Who or what text suggested putting an `s` in `"%31s[^\n]"`? – chux - Reinstate Monica Mar 09 '19 at 22:03
  • simply i think we put s at first `scanf()` argument because of scanning a string. somthings like `scanf("%s", string)` – EsmaeelE Mar 09 '19 at 22:05
  • is there any soulotion with using `getline()` in this case, i cant implement a working example. – EsmaeelE Mar 09 '19 at 22:08
  • @EsmaeelE `scanf("%s", string)` will stop at the first whitespace and has no length constraint. So for my name it would only read "Weather". – Weather Vane Mar 09 '19 at 22:22
  • @EsmaeelE I am unsure of who [we](https://stackoverflow.com/questions/55081766/read-and-store-the-c-string-value/55082145?noredirect=1#comment96910548_55082145) is. Re: [is there any soulotion with using getline()](https://stackoverflow.com/questions/55081766/read-and-store-the-c-string-value/55082145?noredirect=1#comment96910548_55082145),suggest posting that question. – chux - Reinstate Monica Mar 09 '19 at 22:39