C语言 为什么我的循环不工作时,我不包括这个变量在一个函数?

kcwpcxri  于 2023-03-12  发布在  其他
关注(0)|答案(4)|浏览(162)

我正在写一个程序,它不断地提示用户写一些东西,直到他们写“完成”。
如果在函数的三元运算符中不包含continueFlag(最后一行),do/while循环只运行一次,为什么呢?如果我们只检查检查匹配字母的标志(quitFlag),结果不是一样的吗?

#include <stdio.h>
int checkWord(char userInput[]);

int main()
{
  int flag = 0;
  char userInput[30];

  do
  {
    printf("Speak: ");
    scanf("%s", userInput);
    flag = checkWord(userInput);

  } while (flag == 0);

  return 0;
}

int checkWord(char userInput[])
{
  char quitWord[5] = "done";
  int continueFlag = 0;
  int quitFlag = 0;

  for (int i = 0; i < 4; i++)
  {
    if (quitWord[i] != userInput[i])
    {
      continueFlag = 1;
    }
    else
    {
      quitFlag = 1;
    }
  }

  return (quitFlag == 1 /* && continueFlag == 0 */) ? 1 : 0; // ternary operator
}
mklgxw1f

mklgxw1f1#

如果任何字符匹配,则quitflag为1。
如果任何字符不匹配,则continueflag为1。
如果你找到至少一个匹配字符并且没有找到任何不匹配的字符,那么整个字符串都是相等的,这种情况在代码中用quitflag == 1 && continueflag == 0表示。
如果您从三元组中删除continueflag,那么您只是测试是否至少有一个匹配项,而不是所有匹配项。
实际上根本不需要quitflag,只要没有不匹配的字符,字符串就匹配。

return continueflag == 0;

你完全可以不使用变量来完成,只要在你发现一个不匹配的字符时返回false,如果你通过了循环就返回true。

for (int i = 0; i < 4; i++) {
    if ((quitWord[i] != userInput[i]) {
        return 0;
    }
    return 1;
}
8dtrkrch

8dtrkrch2#

如果任何字母匹配,代码将设置quitFlag = 1;,如果任何字母不匹配,代码将设置continueFlag = 1;,因此,quitFlag==1意味着至少有一个字母匹配。
quitFlag==1 && continueFlag==0表示至少有一个字母与 * 匹配,并且 * 没有一个字母不匹配,这与表示它们都匹配是相同的。

50few1ms

50few1ms3#

1.使用一个无限循环和break来代替所有这些标志,这样你重复的次数就少了。
1.检查scanf()的返回值,否则您可能正在对未初始化的数据进行操作。
1.使用strcmp()或失败,实施适当的替换my_strcmp()
1.函数名checkWord()不明确。检查成功是什么意思?成功是0还是1?
1.在阅读字符串时,总是将最大字段宽度传递给scanf(),以避免缓冲区溢出。我在这里使用了一对宏,但此时在格式字符串中硬编码29也是可以的。

#include <stdio.h>

#define USER_INPUT_LEN 29
#define str(s) str2(s)
#define str2(s) #s

int my_strcmp(const char *s1, const char *s2) {
    while(*s1 && *s2 && *s1++ == *s2++);
    return *s2 - *s1;
}

int main() {
    char userInput[USER_INPUT_LEN + 1];
    for(;;) {
        printf("Speak: ");
        if(scanf("%" str(USER_INPUT_LEN) "s", userInput) != 1) {
            printf("scanf failed\n");
            break;
        }
        if(!my_strcmp(userInput, "done"))
            break;

    }
}

和示例运行:

Speak: test
Speak: do
Speak: done2
Speak: done
oalqel3c

oalqel3c4#

如果两个字符串中至少有一个字符出现在同一位置,则变量quitFlag设置为1

if (quitWord[i] != userInput[i])
{
  continueFlag = 1;
}
else
{
  quitFlag = 1;
}

因此,如果两个字符串中至少有一个字符出现在相同的位置,则函数checkWord返回1,do-while循环中断;否则函数返回0,do-while循环继续迭代。
所以你的陈述
如果在函数的三元运算符中不包含continueFlag(最后一行),那么do/while循环只运行一次,为什么呢?
通常是错误的,因为用户可以在相同位置输入一个字符串,该字符串的任何一个字符都不等于字符串"done"中的字符,因为在这种情况下函数checkWord返回0。
此return语句

return (quitFlag == 1 && continueFlag == 0 ) ? 1 : 0;

当字符串的所有4字符彼此相等时,返回1
与上述return语句相反,此return语句

return (quitFlag == 1 ) ? 1 : 0;

如果两个字符串中至少有一个字符位于同一位置,则返回1。
但无论如何,您的函数都是错误的,至少因为用户可以传递给包含4个以上字符的函数,例如"donealready"
使用循环的方法,可以按以下方式声明和定义函数

int checkWord( const char userInput[] )
{
    const char *quitWord = "done";

    const char *p = quitWord;

    while ( *p != '\0' && *p == *userInput )
    {
        ++p;
        ++userInput;
    }

    return *p == *userInpit;
}

大体上你可以写

do
{
    printf( "Speak: " );
    scanf( "%29s", userInput );
} while ( !checkWord( userInput ) );

相关问题