简体   繁体   English

scanf 接受一个带空格的字符串,然后接受一个字符

[英]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.问题是,在请求优先级并获取值之后,它会返回“输入消息”并且没有输入需要一个空字符串。

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. while (message != "")总是 false: message == ""比较数组message的地址和字符串常量""存储在 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.您不能将字符串与==进行比较,您必须使用strcmp()或简单地使用while (*message != '\0')message未初始化,因此此测试具有未定义的行为。 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 ] . s不正确,字符 class 规范在]处停止。

  • if (result == 0) is not enough: scanf() will return EOF on end of file, so you should test if (result != 1) if (result == 0)还不够: scanf()将在文件末尾返回EOF ,因此您应该测试if (result != 1)

  • priority = getchar() will read the pending newline, which scanf(" %c", &priority) would ignore anyway, remove this line. priority = getchar()将读取挂起的换行符, scanf(" %c", &priority)无论如何都会忽略,删除此行。

  • 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. scanf(" %c", &priority)将从用户那里读取下一个非空白字符,但会将用户输入的行的 rest 留在输入 stream 中,包括换行符,这将导致下一次迭代失败,因为可用的第一个字符将是换行符,导致scanf()返回 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;
}

Use fgets() to read a line of user input instead of scanf() until you understand why scanf() is so troublesome.使用fgets()代替scanf() ) 来读取一行用户输入,直到你明白为什么scanf()如此麻烦。

    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);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM