while循环用分号

Gay*_*avi -1 c scanf while-loop

这个指令做了什么?分号和while循环有什么用?

while(scanf("%s",&s [strlen(s)])== 1);

我正在研究一个程序来检查字符串是否是一个字母组合.这是完整的代码:

int main(){

char s[100];
while (scanf("%s", &s[strlen(s)]) == 1);
char big[26] = {0};
char small[26] = {0};
for (int i = 0; i < strlen(s); i++) {
    if (s[i] >= 'a' && s[i] <= 'z') {
        small[s[i] - 'a'] = 1;
    }
    else if (s[i] >= 'A' && s[i] <= 'Z') {
        big[s[i] - 'A'] = 1;
    }
}

for (int i = 0; i < 26; i++) {
    if (!(big[i] == 1 || small[i] == 1)) {
        printf("not pangram");
        return 0;
    }
}

printf("pangram");

return 0;
Run Code Online (Sandbox Code Playgroud)

}

Joh*_*ger 5

strlen(s) 返回字符串的长度(假设它实际上是一个正确终止的字符串).

s[strlen(s)] 因此指定字符串的终止空字节.

&s[strlen(s)]因此,它是指向字符串终结符的指针,或者等效于指向s零长度尾部子字符串.

scanf("%s", &s[strlen(s)])因此尝试从标准输入扫描空格分隔的字符串到尾部s.如果s有足够的未使用空间且输入确实可用,那么这可能会成功.如果是,则scanf()返回1,成功扫描的输入字段数.

但是,如果在扫描任何非空格之前检测到文件的末尾,则scanf()返回零而不添加任何内容s.

因此,每次测试while条件时(scanf("%s", &s[strlen(s)]) == 1),它都会尝试将下一个字符串从标准输入追加到结尾s.

循环体是一个空语句(;).这没有任何作用,因此整个循环只是重复测试循环条件,直到它的计算结果为false.如果它s最初是一个终止的字符串并且它有足够的空间,那么它具有连接标准输入,减去所有空格的整体副作用s.但是,如果不满足这些条件,则行为未定义.

由于您没有采取任何措施来确保s最初终止,您将面临UB的严重风险(尽管行为是否定义实际上是不确定的).此外,您的程序非常容易受到缓冲区溢出的影响,因为它会将用户提供的输入扫描到固定大小的缓冲区中,而无需验证是否有足够的可用空间.