0

If i give my program this:

abcdefghijklmnopqrstuvwxyz

It answered with this?!

Invalid command a
Invalid command c
Invalid command e
Invalid command g
Invalid command i
Invalid command k
Invalid command m
Invalid command o
Invalid command q
Invalid command s
Invalid command u
Invalid command w
Invalid command y

Any idea why only every other letter is getting my default message, and why there is so many and not just one, how can i fix this so i only get one default message no matter how many invalid characters i input?

Here is that part of my code:

while (1) {
  scanf("%c", &command);
  getchar();

  switch (command) {
  case 'A': // Adds a new entry to the program database.
    if (scanf("%s %f", name, &price) != 2) {
      printf("A should be followed by exactly 2 arguments.\n");
      // while (getchar() != '\n'); // Clear the input buffer
    } else {
      getchar(); // Consume the newline character
      addGame(&games, &numGames, name, price); // Pass pointer to games
    }
    break;
  case 'B': // Buy game command, which sells a specified number of games
    if (scanf("%s %d", name, &count) != 2 || count <= 0) {
      getchar(); // Consume the newline character
      printf("Number of bought items cannot be less than 1.\n");
    } else {
      getchar(); // Consume the newline character
      buyGame(games, numGames, name, count);
    }
    break;
  case 'L': //Prints a list of the program database into the standard output
    printDatabase(games, numGames);
    break;
  case 'W': //Writes the program database into a text file
    scanf("%s", filename);
    getchar();
    saveToFile(games, numGames, filename);
    break;
  case 'O': //Loads the database from the specified text file
    scanf("%s", filename);
    getchar();
    loadFromFile(&games, &numGames, filename); // Pass pointer
    break;
  case 'Q': //Quits the program after releasing the program database
    releaseMemory(games, numGames);
    return 0;
  case '\n': //Not sure i need this?
    break;
  default:
    printf("Invalid command %c\n", command);
  }
}

I can send more of my code if someone think it's needed :)

Jean-Baptiste Yunès
  • 34,548
  • 4
  • 48
  • 69
  • 2
    `scanf(" %c", &command);` Put a space before `%c` to skip leading whitespace. That may help. [scanf() leaves the newline character in the buffer](https://stackoverflow.com/questions/5240789/scanf-leaves-the-newline-character-in-the-buffer) – Retired Ninja Aug 22 '23 at 13:10
  • 3
    Please indent your code, it will make it easier to read and understand what it does. – Some programmer dude Aug 22 '23 at 13:11
  • And the whole "consume the newline character" business is not needed. See the comment by @RetiredNinja for a simple way to remove all those `getchar()` calls. Note, that leading space in the format is *only* needed by `%c` (and `%[`), not for any other format which does it automatically. – Some programmer dude Aug 22 '23 at 13:13
  • 1
    @Someprogrammerdude: `%n` also doesn’t consume white space, but it is something of an oddball conversion specification. – Jonathan Leffler Aug 22 '23 at 13:20
  • Thank you all for your answers :) Answer to "Please indent your code" I tried to paste my code how it should be, but the "add your question" page didn't let me post until i rap*d it like that x) – Ronja Oksanen Aug 22 '23 at 14:01
  • I tried that " Put a space before %c" but it messed things up with cases that has arguments – Ronja Oksanen Aug 22 '23 at 14:02
  • Speaking of indentation: that's rather for _you_ than for us. Unindented code is hard to work with and even harder for beginners. – Jabberwocky Aug 22 '23 at 14:18
  • You inputed lowercases while uppercases are waited. try `ABCDE...` – Jean-Baptiste Yunès Aug 22 '23 at 14:19
  • @RonjaOksanen then edit the code by hand. – Jean-Baptiste Yunès Aug 22 '23 at 14:20

3 Answers3

0

In the beginning of the while loop you have

while (1) {
scanf("%c", &command);
getchar()
//...

So when you enter such a sequence of symbols

abcdefghijklmnopqrstuvwxyz

then the call of scanf reads one character as for example 'a' and the next call of getchar reads the next character 'b'. As the command 'a' is invalid then next call of scanf reads the next character 'c' and the call of getchar reads the letter 'd' and so on. What you do is what you get.

Instead of these two calls

scanf("%c", &command);
getchar()

you could use only one call of scanf like

scanf(" %c", &command);

Pay attention to the leading space in the format string. It allows to skip white space characters including the new line character '\n'. And if the input is invalid you should clear the input buffer under the label default for example like

while ( getchar() != '\n' );

or

scanf( "%*[^\n]" );

And remove calls of getchar also in other places of your code.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

You read only one character at a time, not whole lines. That's why you get "so many and not just one".

To read whole lines use fgets instead. And add validation that only one character was input, if you need.

The reason you only get every second character reported as wrong, is just because of the misguided getchar call after scanf("%c", &command). The scanf call will read e.g. a, then the getchar call will read the b. And so on.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

in your loop, at the top:

  scanf("%c", &command);  /* read one char into command */
  getchar();              /* skip the next char, ignoring it */

you read a character into command, then getchar() just drops the next char. This is why you read alternate characters and produce that output, as the input characters are lowercase while you are checking only for some uppercase characters.

Luis Colorado
  • 10,974
  • 1
  • 16
  • 31