我有一个程序来检查键盘上读取的句子是pangram。
但是当显示结果(在最后for
- 循环中)时,它会超出预期的界限。如果您取消注释printf
语句,则可以看到即使将i<26
设置为循环条件,它也会运行到i = 27
并且大小为26的数组包含元素cache[26] = garbage value
和cache[27] = 0
。我的上一个循环有什么问题?
int main() {
char* string = (char*)malloc(1024*sizeof(char));
fgets(string, 1024, stdin);
int i=0, cache[25]={0};
while(string[i]!='\0' ){
cache[(toupper(string[i])-'A')]++;
i++;
}
for( i=0; i<26; i++){
// printf("%d - %d\n",i,cache[i]);
if(!cache[i]){
printf("not pangram");
return(0);
}
}
printf("pangram");
return 0;
}
答案 0 :(得分:2)
问题是你的数组首先对于字母表中的26个字母来说太小了。它至少应为cache[26]
。
然后,对于任何非字母字符(逗号,空格等),以下内容可能会超出范围:
cache[(toupper(string[i])-'A')]++;
超出范围会破坏你的记忆(例如,覆盖i或者当行为未定义时可能发生的任何事情)。
如何解决问题?
您可以考虑保护缓存增量:
if (isalpha(string[i]))
cache[(toupper(string[i])-'A')]++;
请注意,一些更具异国情调的地区可能会考虑范围之外的一些字符&#39; A&#39; Z&#39; Z&#39;作为阿尔法。所以你甚至可能想要更加严格:
int letter=toupper(string[i])-'A';
if (letter>=0 && letter<26)
cache[(toupper(string[i])-'A')]++;