检查字符串是否为回文是一个简单的程序。我在程序中制作了以下代码。
当我编译它时,没有错误但是当我尝试运行.exe文件时,我总是得到以下消息。
答案 0 :(得分:0)
这里的根本问题是永远不能满足循环退出条件,这会导致无限循环:
(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
是否为正来解决此问题。请注意,size_t
是数组索引的正确类型,因为它是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;
}