想根据用户需要多次调用fgets()

时间:2017-08-03 01:28:15

标签: c string scanf fgets

用户输入' 1'或者' 0' 0选择继续使用fgets()获取字符串。因此,当用户输入选项时,fgets会从控制台读取它。我将它存储在另一个变量中。但是fgets可以选择并将其存储在消息中。我在接受选择后尝试使用fflush(stdin)。请帮帮我。

int main() {
    int choice=1;
    char *message;
    int i=0;
    while (choice == 1) {
        fflush(stdout);
        printf("Enter the message: ");
        fflush(stdout);
        message = fgets(message,200,stdin);
        while (message[i]!='\n') {
            i++;
        }
        message[i] = '\0';
        send_message(message);
        printf("\nType '1' to continue or '0' to quit: ");
        scanf("%d",&choice);
        fflush(stdin);
     }
 }

2 个答案:

答案 0 :(得分:2)

看起来你正试图scanf()来阅读用户的输入 - 这本质上是危险的。 (见https://www.reddit.com/r/learnprogramming/comments/1d0w4x/c_scanf_d_but_error_if_user_enters_a_character/)。

我建议您使用%s作为格式字符串,或者更好的是,构建一个子程序来进行安全输入并以老式的方式解析它,例如以下内容:

/* getsafe() - Generic input using the preferred input method rather than gets() */

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


char *getsafe(char *inpstr,int inpsiz) {
    char    *seachr;                    /* Result of search via strchr()     */

    if (inpstr==NULL) {
        return(NULL);
    }
    if (fgets(inpstr,inpsiz,stdin)==NULL) {
        return(NULL);
    }
    seachr=strchr(inpstr,'\n');
    if (seachr!=NULL) *seachr=0;

    return(inpstr);
}

通过这种方式,您可以指定缓冲区长度并提供足够长度的字符串(字符数组)以防止缓冲区溢出(安全问题),然后解析该数组中的[0]位置以获得答案。

#define ANSSIZ 80               /* Maximum allowed size of user answer    */
char usrans[ANSSIZ];            /* User Answer                            */
printf("Enter 'y' or 'n': ");
getsafe(usrans, ANSSIZ-1);

答案 1 :(得分:2)

这有很多问题 - 它可能属于Code Review

然而,这是对一些主要问题的批评

int main() {
    int choice=1;
    char *message; // This is a pointer, but is not malloc'ed. You might want "char message[200]" instead?
    int i=0; // This is the only time "i" is set to 0. It needs to be reset at the start of the loop
    while (choice == 1) {
        fflush(stdout); // No need for this
        printf("Enter the message: ");
        fflush(stdout);
        message = fgets(message,200,stdin);
        while (message[i]!='\n') { // Why not use strlen?
            i++; // "i" can keep growing forever if there is no newline (if someone entered 199 characters before pressing enter)
        }
        message[i] = '\0'; // fgets does this for you - The past loop was pointless
        send_message(message);
        printf("\nType 'y' to continue or 'n' to quit: "); // You forgot to flush here!
        scanf("%d",&choice); // I don't think this will result in a 0 or 1 output... %d is for a digit, and you're asking the user for y or n.
        fflush(stdin); // This is invalid and unneeded - You can't flush stdin
    }
}