如何在C语言中声明可重复使用的临时字符串?

3
我有一个while循环,它会接收用户输入直到用户输入“quit”,但我不确定如何正确声明字符串。如果用户只输入一个单词,第二个变量将保持上一次循环的值。
int main(int argc, char * argv[]){
    char user_input[25];
    char var1[25], var2[25];
    while(strcmp(var1, "quit") != 0){
        clear_buffer(user_input);
        fgets(user_input, 30, stdin);
        sscanf(user_input, "%s %s", var1, var2);
        do_stuff(var1, var2);
    }
    printf("%s", "Done\n");

3
考虑到缓冲区仅有25个字节,fgets(user_input, 30)似乎是错误的。 - Mooing Duck
当您第一次进入循环时,var1 尚未被初始化。 - chqrlie
@DigitalNinja:我认为有些命令只有一个单词,这种情况下第二个单词应该传递一个零长度的字符串。 - Mooing Duck
1
printf("Done\n"); - chqrlie
1
如果用户只输入一个单词,第二个变量将保持前一个循环的相同值。这是一个要求还是问题? - chqrlie
显示剩余4条评论
4个回答

5

我不确定如何正确声明字符串

字符串不是一种类型。它们是一种值模式,就像其他值一样,我们不声明它们; 我们使用 strcpy 和其他函数来分配它们(在这种情况下)。如果你说一个 int 存储十的倍数,那么它以 0 结尾……如果你说一个 char 数组存储一个字符串,那么它以第一个 '\0' 结尾。现在你看到规律了吗?我们可以将十的倍数存储在不同类型的整数变量中,同样地,在存储字符串时,我们可以选择不同类型的字符数组。同样,在声明用于存储字符串的数组时,您需要确保该数组具有足够的空间来存储字符串的所有字符以及以 '\0' 结尾的字符。

如果用户只输入一个单词,则第二个变量将保持与上一次循环相同的值。

检查 sscanf 的返回值。

例如,考虑 int x = sscanf(user_input, "%s %s", var1, var2); 时,您可能想要确保给 sscanf 的 2 个参数已被赋值,这时您将检查 x == 2。如果您只关心第一个参数被赋值,那么当 x == 1 时,您也会很高兴。但是,如果 x <= 0,则您无法信任 var1var2


2

多重问题

  1. You never initialize var1 but you use strcmp(), you need to initialize var1 before trying to use strcmp(), if you want to initialize to an empty string just

    var1[0] = '\0';
    
  2. You pass 30 to fgets() but user_input can only hold 25 characters.

现在我们需要弄清程序的行为方式,您需要检查sscanf()是否读取了两个字符串,如果没有,它就不会改变传递的参数。 scanf()函数返回与输入相匹配的说明符数量。因此,如果
  1. scanf()返回0,则表示两个参数均未初始化/修改。
  2. scanf()返回1,其中一个参数已初始化/修改。
  3. 当两者都被初始化/修改后,它将返回2,因此检查这一点将让您知道出了什么问题,并且您可以打印输入字符串以验证scanf()的正确性以及输入的错误。

嘿,你上一句话有误:如果 scanf 没有读取两个字符串,它就需要清除参数。 - Mooing Duck

1
char user_input[50+1];
char var1[25], var2[25];

while(fgets(user_input, sizeof(user_input), stdin)){
    int state = sscanf(user_input, "%24s %24s", var1, var2);
    if(state == 1 && strcmp(var1, "quit") == 0)
        break;
    else if(state == 2)
        do_stuff(var1, var2);
}

为什么应该调用 do_stuff 来退出程序,更重要的是,为什么不带参数的命令应该被忽略? - chqrlie
如果输入只有一个,则不需要启用退出功能。这是因为当您想要停止时,无需指定第二个参数。另外,如果输入不足两个,则被视为无效。原因是do_stuff需要两个参数。 - BLUEPIXY
从OP的问题中可以说要求并不清晰。你对于quit的论点是有争议的。那么没有参数的命令呢?仅仅忽略它们似乎是不正确的。 - chqrlie

1

这是一个考虑了注释并保护sscanf参数的修改版本:

int main(int argc, char *argv[]) {
    char user_input[80];
    char var1[25], var2[25];

    while (fgets(user_input, (int)(sizeof user_input), stdin)) {
        *var2 = '\0';
        if (sscanf(user_input, "%24s %24s", var1, var2) > 0) {
            if (!strcmp(var1, "quit"))
                break;
            do_stuff(var1, var2);
        }
    }
    printf("Done\n");
    return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接