Scan a white space/whole line in c

2019-07-09 01:33发布

问题:

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.

回答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.



回答2:

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;
}