2

So, I know this question has been asked before, but I can't seem to make anything work. What I have right now is this:

#include<stdio.h>

struct ClothingCustomer{
  char name[20];
  int age;
  double inseam;
};

struct ClothingCustomer createACustomer(){
  struct ClothingCustomer aCustomer;

  printf("Enter Customer Name: ");
  scanf("%s",aCustomer.name);

  printf("Age: ");
  scanf("%d",&aCustomer.age);

  printf("Inseam: ");
  scanf("%lf",&aCustomer.inseam);
  return aCustomer;
};

int main(){
  FILE* customersFile = fopen("customers.txt","w");
  for (int i = 0; i < 5; i++){
    struct ClothingCustomer aCustomer = createACustomer();
    fprintf(customersFile, "%s %d %lf\n", aCustomer.name, aCustomer.age,     aCustomer.inseam);
  }

  fclose(customersFile);
  return 0;
}

No matter what I do to try to make it scan more than one word, like a first/last name or something, it works, but here's what I get in the console while running this(with the scan options to try to get past a white space listed below; the above code functions correctly, but doesn't allow white space):

Enter Customer Name:
Age:
Inseam:
Enter Customer Name: Age:
Inseam: Enter Customer Name: Age:
Inseam:
Enter Customer Name: Age:
Inseam:
Enter Customer Name: Age:
Inseam:

How can I make it not do this? I've tried using:

[^\n]
fgets(name, sizeof(name), stdin);

and the same thing happens every time.

DYZ
  • 55,249
  • 10
  • 64
  • 93
hego64
  • 345
  • 1
  • 5
  • 17
  • Where is the user input in your interaction example? Do you enter anything at all? – DYZ Jan 25 '17 at 20:48
  • 3
    You need consume a newline after `scanf("%lf",&aCustomer.inseam);`. – BLUEPIXY Jan 25 '17 at 20:51
  • 3
    Always a bug: not testing the return value from scanf() and fopen(). – Jens Jan 25 '17 at 20:51
  • try `scanf(" %19[^\n]", aCustomer.name);` – BLUEPIXY Jan 25 '17 at 21:04
  • Why does code not check the return value of `scanf("%d",&aCustomer.age);`? – chux - Reinstate Monica Jan 25 '17 at 21:34
  • The example at the end I left out the input because whatever after would be just what I had put in; I was only trying to show that it displays everything all wrong. Using scanf(" %19[^\n]", aCustomer.name); had the same problem. Still not sure what to do. – hego64 Jan 27 '17 at 00:31
  • @chux If the scanf consumes the word before space , and not the whole first name + last name that the OP wanted to , would still be scanf return output be 1 , i mean if it is 1 , what else can we find from it then? – Suraj Jain Jan 27 '17 at 13:59
  • unclear how you input values, are you writing all values on one line or are you entering values pressing enter after each value? – AndersK Jan 27 '17 at 17:50
  • so it worked for you ? – Suraj Jain Jan 31 '17 at 04:42

2 Answers2

1

This Will Work

  #include<stdio.h>
  #include<string.h>
  struct ClothingCustomer createACustomer(void);
  struct ClothingCustomer{
       char name[20];
             int age;
       double inseam;
                    };

       struct ClothingCustomer createACustomer(void){
       struct ClothingCustomer aCustomer;
       {                 //From Here Starts The Part in Which You Are Having Problems.
       char c;
        int i;
       printf("Enter Customer Name: ");
       scanf("%s",aCustomer.name);
       i = strlen(aCustomer.name);      // length of user input till first space
       do{
       scanf("%c", &c);
       aCustomer.name[i++] = c;  // reading characters after first space (including it)
       }while (c != '\n');     // until user hits Enter

       aCustomer.name[i - 1] = 0;       // string terminating
       }
       printf("Age: ");
       scanf("%d",&aCustomer.age);

       printf("Inseam: ");
       scanf("%lf",&aCustomer.inseam);
       return aCustomer;
       };

       int main(){
             FILE* customersFile = fopen("customers.txt","w");
             int i = 0;

             for (i = 0; i < 5; i++){
             struct ClothingCustomer aCustomer = createACustomer();
             fprintf(customersFile, "%s %d %lf\n", aCustomer.name, aCustomer.age,aCustomer.inseam);
             }
             fclose(customersFile);
             return 0;
             }

I Highly Recommend You To Take A Look on this answer , it will help you a lot , the method I used in here is mentioned in the above answer.Please Give That answer Credit If this method works for you. Here is the explanation for the part which you were having problem in , how is it working now.

How this works? When user inputs characters from standard input, they will be stored in string variable until first blank space. After that, rest of entry will remain in input stream, and wait for next scanf. Next, we have a for loop that takes char by char from input stream (till \n) and appends them to end of string variable, thus forming a complete string same as user input from keyboard.

Community
  • 1
  • 1
Suraj Jain
  • 4,463
  • 28
  • 39
0

Unclear why scanf(" %19[^\n], aCustomer.name) failed for OP.

Rather than use scanf() for complex input, separate user input from parsing. Drop use of scanf() completely and use fgets() to fetch user input. Use sscanf(), strtod(), strtol(), strtok() etc. for parsing.

Be sure to check the result of user input and success of parsing functions.

OP has not indicated how to handle troublesome input. The below returns a zero-ed ClothingCustomer in that case. Additional error codes or error messages may be useful.

struct ClothingCustomer createACustomer(void) {
  // Suggest initializing
  struct ClothingCustomer zero = { 0 };
  struct ClothingCustomer aCustomer = { 0 };
  char buffer[100];

  printf("Enter Customer Name: ");
  fflush(stdout);  // insure prompt is seen before asking for input
  if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
  buffer[strcspn(buffer, "\r\n")] = '\0';  // lop off potential line ending
  if (strlen(buffer) >= sizeof aCustomer.name) return zero;  // too long
  strcpy(aCustomer.name, buffer);

  printf("Age: ");
  fflush(stdout);
  if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
  if (sscanf(buffer, "%d", &aCustomer.age) != 1) return zero;
  // Let us do some range checking
  // https://en.wikipedia.org/wiki/List_of_the_verified_oldest_people
  if (aCustomer.age < 0 || aCustomer.age > 122) return zero;


  printf("Inseam: ");
  fflush(stdout);
  if (fgets(buffer, sizeof buffer, stdin) == NULL) return zero;
  if (sscanf(buffer, "%lf", &aCustomer.inseam) != 1) return zero;

  return aCustomer;
}
Community
  • 1
  • 1
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256