输出文件.exe没有响应并停止工作C

问题描述:

这是一个简单的程序,用于检查字符串是否是回文。我在程序中编写了以下代码。输出文件.exe没有响应并停止工作C

program to check string is palindrome or not

当我编译它,没有错误,但是当我尝试运行.exe文件,我总是得到以下信息。

.exe is not responding

+4

[不要将代码和文本输出为图像](https://meta.stackoverflow.com/q/303812/995714)。在这里复制并粘贴它们 –

+1

如果'strlen(str)'为0,那么未定义的行为....另外,[在任何情况下都不要使用'gets()'](https://stackoverflow.com/questions/1694036/why-是最被-IT-应该 - 不被使用的功能,如此危险,这一点)。这个危险的函数不再是C语言的一部分。 –

根本这里的问题是,循环退出条件不能得到满足,这导致一个无限循环:

(i != j || i != j - 1) 

这种情况是逻辑上等同于:

!(i == j && i == j - 1) 

这显然总是正确的,所以循环无限期地继续。循环只需要继续,只要j > i

这里还有一个问题;即dangerous function gets() should never be used.此函数在C99中已弃用,并且已从C11中的语言中完全删除。一种替代方法是使用fgets()。请注意,此函数保留换行符(如果缓冲区中有空间),所以您需要在获取输入后将其删除。而且,如果缓冲区太小,字符可能会留在输入流中。出于这个原因,最好宣布一个慷慨大小的输入缓冲区以降低此处出现问题的风险。没有理由不使用一个包含1000个字符的输入缓冲区,而我通常只用4096来表示这样的事情。内存很便宜。

此外,在发布的代码中存在未定义行为的风险,因为输入字符串可能为空。在这种情况下,strlen(str)将为0,因此在循环主体j的第一次执行中将递减为-1。但数组访问str[-1]超出范围,并导致未定义的行为。

此问题可以通过检查j在第一次递减前为正值来解决。请注意0​​是数组索引的正确类型,因为它是一个unsigned整数类型,保证能够保存任何数组索引。另请注意,strlen()函数返回的值为size_t,而不是int

以下是发布代码的修改版本。 size_t类型用于数组索引。输入字符串的长度存储在j中,然后只有当它是正值时才会递减;这将j设置为空终止符前面的字符的索引,只要输入字符串不是空字符串即可。循环继续,而j大于i,并且由这些值索引的字符相匹配。循环结束后,str[i]str[j]应该同意;如果他们不这样做,那么投入就不是回文。

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

#define BUF_SZ 4096 

int main(void) 
{ 
    char str[BUF_SZ]; 

    printf("Enter string:\n"); 
    fgets(str, sizeof str, stdin);   // Never use gets() 
    str[strcspn(str, "\r\n")] = '\0';  // remove '\n' 

    size_t i = 0; 
    size_t j = strlen(str); 
    if (j > 0) { 
     --j; 
    } 

    while (i < j && str[i] == str[j]) { 
     ++i; 
     --j; 
    } 

    if (str[i] == str[j]) { 
     puts("string is palindrome!!"); 
    } else { 
     puts("string is not palindrome!!"); 
    } 

    return 0; 
}