gpt4 book ai didi

c - 键入退出以退出C程序

转载 作者:行者123 更新时间:2023-12-02 09:08:38 24 4
gpt4 key购买 nike

我在想程序的问题是什么。键入quit时无法退出程序。
这是我所拥有的:

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

int main(void) {

char string[200];

printf("Enter a bunch of words: ");
do
{
scanf("%[^\n]c", string);


}while(strcmp(string,"quit")!=0);

return 0;
}

最佳答案

您的两个最大问题是使用scanf困扰新C程序员的两个最常见问题:

  1. You are using an incorrect format string; and
  2. You fail to check the return of scanf.


让我们首先解决第一件事:
scanf("%[^\n]c", string);

您的格式字符串 "%[^\n]c"使用字符类格式说明符 "%[...]"来读取 string的文本。然后是 "c"-仅与您输入字符串末尾的文字 'c'相匹配。由于 "%[^\n]"将读取不是 '\n'的所有字符,仅留下 '\n'进行读取,而这与 'c'不匹配,因此不会发生这种情况。

此外, "%[...]"说明符与 "%c"说明符一起不占用前导空格( '\n'为空格)。因此,将 '\n'保留为未读状态时,您对 stdin的下一次调用将失败,因为 scanf不会读取 "%[^\n]",并且它与 '\n'不匹配,从而导致匹配失败,因此 'c'仍未读入 '\n'中,事情很快就失去了控制。

要解决所有问题,您需要记住上面的 stdin,并使用field-width修饰符保护 (2.)的数组边界,然后应阅读并保存提取的字符并将其放在 string中以保存到 中,以确保完整读取了输入行-如果没有,则 是您的责任,负责在尝试下一次读取之前删除 string 中剩余的所有多余字符。

对于初学者,您可以使用格式适当受限的字符串,该字符串开头应包含stdin,这将导致space放弃所有前导空格,例如
    " %199[^\n]%c"

请注意,上面将保存最终字符,将进行两次转换,因此您将需要一个字符变量来处理最终转换说明符的结果,例如
    do {
char c; /* final character read */
int retn; /* variable to save scanf return */
/* prompt */
fputs ("Enter a bunch of words ('quit' exits): ", stdout);
/* read saving scanf return */
retn = scanf (" %199[^\n]%c", string, &c);

(注意:,提示已在scanf循环内移动了)

接下来的负责每次检查do {...} while (..);返回。您必须处理三个条件
  • scanf用户通过按Ctrl + d(或在Windows上Ctrl + z)生成手动(return == EOF)来取消输入;
  • EOF,必须处理匹配或输入失败,并且必须考虑输入缓冲区中可能剩余的每个字符。 (通常,您将在输入缓冲区中向前扫描,直到找到(return < expected No. of conversions)'\n'丢弃任何剩余的多余字符,请参见示例中的EOF函数);和
  • empty_stdin()表示读取成功-然后由您检查输入是否满足任何其他条件(例如正整数,正浮点等)。

  • 综上所述,您可以使用(return == expected No. of conversions)循环阅读并寻找scanf作为提示退出的关键字,如下所示:
        do {
    char c; /* final character read */
    int retn; /* variable to save scanf return */
    /* prompt */
    fputs ("Enter a bunch of words ('quit' exits): ", stdout);
    /* read saving scanf return */
    retn = scanf (" %199[^\n]%c", string, &c);
    if (retn == EOF) { /* check the return against EOF */
    fputs ("(user canceled input)\n", stderr);
    return 0;
    }
    else if (retn < 2) { /* checking both string and c read */
    fputs ("input failure.\n", stderr);
    empty_stdin();
    }
    else if (c != '\n') { /* check c is '\n', else string too long */
    fprintf (stderr, "warning: input exceeds %d characters.\n",
    MAXC - 1);
    empty_stdin();
    }
    else /* good input, output string */
    printf ("string: %s\n", string);

    } while (strcmp (string,"quit") != 0);

    最后,请勿在代码中使用幻数("quit"是幻数)。相反,如果您需要一个常量,请使用200一个(或多个)。您必须对数字进行硬编码的唯一地方是例如#define字段宽度修饰符-不能使用变量,宏或命名常量。这是该规则的一个例外。同样,请勿对文件名或路径进行硬编码。所有函数都带有参数,甚至是scanf,都将所需的信息传递给您的程序。

    综上所述,您可以执行以下操作:
    #include <stdio.h>
    #include <string.h>

    #define MAXC 200 /* constant - maximum characters in string */

    void empty_stdin (void)
    {
    int c = getchar();
    while (c != EOF && c != '\n')
    c = getchar();
    }

    int main (void) {

    char string[MAXC]; /* use constants for array bounds */

    do {
    char c; /* final character read */
    int retn; /* variable to save scanf return */
    /* prompt */
    fputs ("Enter a bunch of words ('quit' exits): ", stdout);
    /* read saving scanf return */
    retn = scanf (" %199[^\n]%c", string, &c);
    if (retn == EOF) { /* check the return against EOF */
    fputs ("(user canceled input)\n", stderr);
    return 0;
    }
    else if (retn < 2) { /* checking both string and c read */
    fputs ("input failure.\n", stderr);
    empty_stdin();
    }
    else if (c != '\n') { /* check c is '\n', else string too long */
    fprintf (stderr, "warning: input exceeds %d characters.\n",
    MAXC - 1);
    empty_stdin();
    }
    else /* good input, output string */
    printf ("string: %s\n", string);

    } while (strcmp (string,"quit") != 0);

    return 0;
    }

    示例使用/输出
    $ ./bin/scanf_string_quit
    Enter a bunch of words ('quit' exits): Hello
    string: Hello
    Enter a bunch of words ('quit' exits): My dog has fleas and my cat has none.
    string: My dog has fleas and my cat has none.
    Enter a bunch of words ('quit' exits): quit
    string: quit

    使用Ctrl + d(或在windoze中为Ctrl + z)生成手动main():
    $ ./bin/scanf_string_quit
    Enter a bunch of words ('quit' exits): Hello
    string: Hello
    Enter a bunch of words ('quit' exits): (user canceled input)

    EOF重置为MAXC并将字段宽度修饰符重置为20更改为scanf,您可以检查对太长的行的处理,例如第一个输入合适,第二个输入太长:
    $ ./bin/scanf_string_quit
    Enter a bunch of words ('quit' exits): my dog has fleas and my cat has none.
    warning: input exceeds 19 characters.
    Enter a bunch of words ('quit' exits): 1234567890123456789
    string: 1234567890123456789
    Enter a bunch of words ('quit' exits): 12345678901234567890
    warning: input exceeds 19 characters.
    Enter a bunch of words ('quit' exits): quit
    string: quit

    仔细检查一下,如果您还有其他问题,请告诉我。

    关于c - 键入退出以退出C程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55033405/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com