3

My C program is suppose to receive a full name separated by a comma. Example output is below:

Enter input string:
Jill, Allen

First word: Jill

Second word: Allen

Enter input string:
Golden , Monkey

First word: Golden

Second word: Monkey

Enter input string:
Washington,DC

First word: Washington

Second word: DC

Enter input string:
q*

However, with my current code, Jill, Allen works as intended but the other two names do not work properly as the first letter is missing. I think this happens because of the input format. Every name is separated by a new line so the machine doesn't read the terminating line and thus ignores the first letter. This is how my code looks right now when outputted:

Enter input string:
Jill, Allen

First word: Jill

Second word: Allen

Enter input string:
Golden , Monkey

First word: olden

Second word: ,

Enter input string:
Washington,DC

First word: ashington

Second word: ,

As you can see the first letter in First word is missing which then messes up Second word. Any advice would be appreciated thanks. My code:

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

int main(void) {

   char name[100];
   char firstName[100];
   char lastName[100];
   char comma = ',';
   char quit; 
   int i;

   while(quit != 'q')
   {
      printf("Enter input string:\n");
      fgets(name, 100, stdin);
      scanf("%c", &quit);

         if(!(strchr(name, comma)))
         {
            printf("Error: No comma in string.\n\n");
         }

            if((strchr(name, comma)))
            {
               sscanf(name, "%s%s", firstName, lastName);
               for(i = 0; i < strlen(name); i++)
               {

                  if(firstName[i] == ',')
                  {
                     firstName[i] = '\0';
                  }
               }
               printf("First word: %.10s\n", firstName);
               printf("Second word: %.10s\n\n", lastName);
            }

   } 

   printf("Enter input string:\n");

   return 0;
}
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 2
    I guess the purpose is to remove a newline. But the statement `scanf("%c", &quit);` is taking the first character of the *next* line, because `fgets` retains the newline, and already read it. – Weather Vane Nov 24 '19 at 21:43
  • 1
    Why don't you use a debugger to examine the errors you wrote? – U. Windl Nov 24 '19 at 21:44
  • As a consquence `name` can end with a newline, which obviously is not part of a name. You might like to read: [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input/28462221#28462221) – Weather Vane Nov 24 '19 at 21:47
  • Please note too that `sscanf(name, "%s%s", firstName, lastName);` won't stop at the comma you detected: each part stops at a whitespace character. – Weather Vane Nov 24 '19 at 21:48
  • `while (fgets (name, 100, stdin)) { if (*name == 'q' && name[1] == '\n') break; ... }` – David C. Rankin Nov 24 '19 at 22:32
  • Who approved this edit? It clearly conflicts with author's intent. I am rolling it back, sorry. – gsamaras Nov 25 '19 at 14:39
  • Who approved this edit? It clearly conflicts with author's intent. I corrected it, but please be more careful next time. – gsamaras Nov 25 '19 at 17:30

2 Answers2

1

Since you want to stop when user types "q", you should check what you read with fgets(), and if that's equal to the string "q", then break the loop.

So now, you won't read into name, but into line, since what you are reading can, validly, either be a name, or the command to quit.

Moreover, that means that instead of a while loop, you can now use a do-while loop, that runs "indefinitely" (the stop condition is 1), until the user inputs "q'.

Furthermore, you don't need the trailing newline of fgets(), so you could remove it.

As @weatherVane commented: sscanf(name, "%s%s", firstName, lastName); won't stop at the comma you detected: each part stops at a whitespace character.

But you need to ignore whitespaces characters, if any, so instead of running a for loop after the call to sscanf(), you could get rid of that method, and employ two loops, one that fills in the first name, and then, the other fills in the last name.

Putting everything together, you get:

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

int main(void)
{
   char line[100];
   char firstName[100];
   char lastName[100];
   char comma = ',';
   do {
      printf("Enter input string:\n");
      fgets(line, 100, stdin);
      line[strcspn(line, "\n")] = 0;
      if(!strcmp(line, "q"))
      {
        printf("Exiting..\n");
        break;
      }
      if(!(strchr(line, comma)))
      {
        printf("Error: No comma in string.\n\n");
      }
      if((strchr(line, comma)))
      {
        int i = 0, j = 0; // i'' index for line, 'j' index for 'firstName'
        while(line[i] != ',')
        {
          if(line[i] != ' ')
          {
            firstName[j] = line[i];
            j++;
          }
          i++;
        }
        i++; // since we had stopped at the comma character
        firstName[j] = '\0';
        int k = 0; // 'k' index for 'lastName'
        while(line[i] != '\0')
        {
          if(line[i] != ' ')
          {
            lastName[k] = line[i];
            k++;
          }
          i++;
        }
        lastName[k] = '\0';
        printf("First word: %.10s\n", firstName);
        printf("Second word: %.10s\n\n", lastName);
      }
   } while(1);
   return 0;
}

Output:

Enter input string:
Jill, Allen
First word: Jill
Second word: Allen

Enter input string:
Golden , Monkey
First word: Golden
Second word: Monkey

Enter input string:
Washington,DC
First word: Washington
Second word: DC

Enter input string:
q
Exiting..
gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • 1
    Thanks for the response but my input was specifically made like that to test that the output will still work correctly even if there were spaces before and after the comma. The first letter of the first word now appears but the second word is still just a comma. I think it's because the machine thinks the "," is the last name is thus prints it like that and I am unsure how to make it ignore the , – Demonic Zebra Nov 25 '19 at 00:09
  • @DemonicZebra you are welcome! Welcome to Stack Overflow! :) Absolutely, you are right, as I had suspected, so please, check my updated answer, that now answers your question, I believe. If this is the case, please accept it (click the green checkmark on the answer's left upper corner), if not, then, please let me know. – gsamaras Nov 25 '19 at 14:39
1

I don't think using sscanf is appropriate here; if the goal is to figure out where the first comma is, you've already done that with strchr, which returns a pointer to the comma's memory location (if successful). Also, we can use else instead of calling strchr twice with negation.

Now that we have the comma pointer, we can increment it and call everything from that location to end of line second. As we increment, we can write a null byte over the comma location, turning the fgets buffer into first. Chances are, you want to overwrite the newline at the end of second while you're at it.

I'm also not sure if the approach of using scanf for quitting is very intuitive, so using the q character from a failed (commaless) input to exit seems reasonable.

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

int main() {
    size_t buf_size = 100;
    char first[buf_size];

    for (;;)
    {
        printf("Enter input string: ");
        char *second = strchr(fgets(first, buf_size, stdin), ',');

        if (second)
        {
            second[strlen(second)-1] = '\0';
            *(second++) = '\0';
            printf("[%s] [%s]\n\n", first, second);
        }
        else
        {
            if (first[0] == 'q') break;

            printf("Error: No comma in string.\n\n");
        }
    }

    return 0;
}

Here's a sample run:

Enter input string: aa,bb
[aa] [bb]

Enter input string: a,b
[a] [b]

Enter input string: aa,b
[aa] [b]

Enter input string: a,bb
[a] [bb]

Enter input string: a,
[a] []

Enter input string: ,b
[] [b]

Enter input string: ,
[] []

Enter input string: ,,
[] [,]

Enter input string: a,b,c
[a] [b,c]

Enter input string: aa
Error: No comma in string.

Enter input string:
Error: No comma in string.

Enter input string: hello world, how are you?
[hello world] [ how are you?]

Enter input string: q
ggorlen
  • 44,755
  • 7
  • 76
  • 106