Reading optional white spaces in sscanf()

891 views Asked by At

So i have been working on an C project and im stuck on this problem, basically Im making a program where the user can enter their name and I later print it out to a file, the first and last name of the user is split with a comma however, optional whitespace in around the comma is allowed. This is what i have been using the read the user names:

    char lastName[20]; 
    char firstName[20]; 
    char line[LINESIZE]; 
    while(fgets(line,LINESIZE,stdin)) { 
       if((sscanf(line," %s , %s ",lastName,firstName)) == 2)  { 
             /*process name */
       } 
    }

However, the only time it reads input successfully is when the user inputs:

john , doe 

which matches the %s , %s I have, how can i make it such that something like:

john, doe 
john ,doe 

Can all work?

I have also tried

sscanf(line,"%s%[],%[]%s"); 

This doesnt cause compilation error, but it doesnt process input meaning it doesnt match the %s , %s

2

There are 2 answers

4
Weather Vane On BEST ANSWER

This will isolate the names so that any permutation of "Doe , John" filters out the whitespace

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

#define LINESIZE 100

int main(void) {
    char lastName[20] = {0}; 
    char firstName[20] = {0}; 
    char line[LINESIZE]; 
    char *first = NULL, *last = NULL;
    if (NULL == fgets(line,LINESIZE,stdin))
        return 1;
    last = strtok (line, ", \t\r\n");
    if (last)
        first = strtok (NULL, ", \t\r\n");

    if (last && first) {
        sprintf(firstName, "%.19s", first);
        sprintf(lastName, "%.19s", last);
        printf ("%s %s\n", firstName, lastName);
    }
    return 0;
}
3
chqrlie On

You can modify the sscanf format to have it perform a more stringent test:

char eol[2];
if (sscanf(line, " %19[a-zA-Z-] , %19[a-zA-Z-]%1[\n]", lastName, firstName, eol) == 3) ...

sscanf will verify that the user typed exactly 2 words made of letters separated by a comma and optional spaces and followed by a line feed.

But I strongly encourage you to parse the input yourself instead of relying on sscanf. It is not difficult, much more precise and flexible, and less error prone:

char lastName[LINESIZE];
char firstName[LINESIZE]; 
char line[LINESIZE]; 
while(fgets(line,LINESIZE,stdin)) {
   char *p = line, *q;
   while (isspace((unsigned char)*p)) p++;
   for (q = lastName; isalpha((unsigned char)*p); p++) {
       *q++ = *p;
   }
   *q = '\0';
   while (isspace((unsigned char)*p)) p++;
   if (*p == ',') p++;
   while (isspace((unsigned char)*p)) p++;
   for (q = firstName; isalpha((unsigned char)*p); p++) {
       *q++ = *p;
   }
   *q = '\0';
   while (isspace((unsigned char)*p)) p++;
   if (*lastName && *firstName && !*p) {
       // format is OK
       printf("Hello %s %s\n", firstName, lastName);
   } 
}