4

The following code should take strings from the user (containing data of items in a storage).

I'm having trouble make the program iterate over to a new line. It aborts when I push "enter" but instead I need it to just take the next line as input. code:

for (i; i < STORE_SIZE; i++) {
    fgets(seq, MAX_STRING_LEN, stdin);
    if (strcmp(seq, "stop")) {
        break;
    }
    else {
        init(seq, ptr);
        *(storage + i) = ptr;
    }
}

The program should abort when it gets the string "stop" in the next line, and not by pushing enter.

Zong
  • 6,160
  • 5
  • 32
  • 46
GaryB
  • 51
  • 1
  • 1
  • 5
  • Shouldn't i be set to 0? – kylemart Apr 28 '16 at 01:17
  • 3
    Please review what [`strcmp`](http://linux.die.net/man/3/strcmp) returns when it has a match. It's not what you think it is as shown in your code. Also please review [Removing trailing newline character from fgets() input](https://stackoverflow.com/questions/2693776/removing-trailing-newline-character-from-fgets-input) – kaylum Apr 28 '16 at 01:20
  • 1
    1) If the buffer ends in a newline remove it. 2) If the buffer is now empty, call `fgets` again. – David Schwartz Apr 28 '16 at 01:31
  • when calling `fgets()`, always check the returned value to assure the operation was successful. one way would be: `for (i; i < STORE_SIZE && fgets(seq, MAX_STRING_LEN, stdin); i++) { – user3629249 Apr 28 '16 at 17:25
  • there is nothing in this code snippet that would cause the program to abort when the string "stop" is input. All that string would do is exit the `for()` loop – user3629249 Apr 28 '16 at 17:26
  • however, there seems to be a problem with this line: `init(seq, ptr);` and the contents of `ptr` cannot be updated via that line. Perhaps you meant: `init(seq, &ptr);` – user3629249 Apr 28 '16 at 17:28
  • the call to `strcmp()` returns 0 (false) when the strings match. so this program will always call `break;` except when the input is `stop`. Suggest: `if ( 0 == strcmp(seq, "stop")) {` however, that will NEVER be true because the call to `fgets()` will have a '\n' (newline) in the string. That newline needs to be allowed for. One way is: `if (0 == strcmp(seq, "stop\n")) {` – user3629249 Apr 28 '16 at 17:31

1 Answers1

6

fgets will always add the linefeed character to the buffer when it encounters it. The only way to get rid of it is to manually remove it, e.g.:

size_t len = strlen(seq);
if (len > 0 && seq[len - 1] == '\n')
    seq[len - 1] = '\0';

Or, more concisely but perhaps more confusingly:

seq[strcspn(seq, "\n")] = '\0';

The strcspn() function looks for the first occurrence of any of the characters in the second argument inside the first argument, and returns the index of that character, or the index of the end of the string if none of the characters were found.

Also, keep in mind that strcmp() returns 0 if the strings are equal. The function is used to compare strings lexically.

Additionally, the first part of your for loop is meaningless, are you sure you didn't mean:

for (i = 0; ...)
Nownuri
  • 689
  • 2
  • 7
  • 19
dreamlax
  • 93,976
  • 29
  • 161
  • 209