Turqay Umudzade
Turqay Umudzade

Reputation: 181

scanf that takes a string with spaces and then takes a char

int main(int argc, char const *argv[]) {
    int id = access_queue();
    char priority;
    char message[100];

    while (message != "") {
        printf("Enter message:\n");
        int result = scanf("%[^\n]s", message);

        if (result == 0) {
            write_value(id, "", '3');
            break;
        }
        printf("Enter priority:\n");
        priority = getchar();
        scanf(" %c", &priority);

        if (priority == '1' || priority == '2' || priority == '3')
            write_value(id, message, priority);
        else
            printf("Priority must 1, 2 or 3 (1 being the highest)\n");
    }
}

Okay, so I have this code which is supposed get the message from the terminal and then ask for the priority until the message is empty. The problem is that after asking for the priority and getting the value, it goes back to "Enter message" and without by input takes an empty string.

Upvotes: 3

Views: 460

Answers (2)

chux
chux

Reputation: 153338

Use fgets() to read a line of user input instead of scanf() until you understand why scanf() is so troublesome.

    char buf[sizeof message * 2];

    //int result = scanf("%[^\n]s", message);
    fgets(buffer, sizeof buffer, stdin); // Better code would check return value if NULL
    int result = sscanf(buffer, "%99[^\n]", message);

...

    // scanf(" %c", &priority);
    fgets(buffer, sizeof buffer, stdin);
    sscanf(buffer, " %c", &priority);

Upvotes: 1

chqrlie
chqrlie

Reputation: 144655

There are some problems in your code:

  • while (message != "") is always false: message == "" compares the addresses of the array message and the array in which the string constant "" is stored in memory. You cannot compare strings with ==, you must use strcmp() or simply while (*message != '\0') but message is uninitialized so this test has undefined behavior. You probably just want to iterate the loop as long as the user does not enter an empty string, so make the loop an infinite loop and test the termination condition explicitly.

  • scanf("%[^\n]s", message); the s is incorrect, character class specifications stop at the ].

  • if (result == 0) is not enough: scanf() will return EOF on end of file, so you should test if (result != 1)

  • priority = getchar() will read the pending newline, which scanf(" %c", &priority) would ignore anyway, remove this line.

  • scanf(" %c", &priority) will read the next non blank character from the user but will leave the rest of the line input by the user in the input stream, including the newline, which will cause the next iteration to fail because the first character available will be a newline, causing scanf() to return 0.

Here is a modified version:

#include <stdio.h>

int main(int argc, char *argv[]) {
    int id = access_queue();
    char priority;
    char message[100];

    for (;;) {
        printf("Enter message:\n");
        int result = scanf("%99[^\n]", message);
        if (result != 1)
            break;
        printf("Enter priority:\n");
        if (scanf(" %c", &priority) != 1)
            break;
        if (priority == '1' || priority == '2' || priority == '3')
            write_value(id, message, priority);
        else
            printf("Priority must 1, 2 or 3 (1 being the highest)\n");

        /* read and ignore the rest of the line entered by the user */
        while ((c = getchar()) != EOF && c != '\n')
            continue;
    }
    write_value(id, "", '3');
    return 0;
}

Upvotes: 4

Related Questions