[英]Most common character in a file in C
我正在做C编程课程作业,我需要在给定的文件中找到一个最普通的字符。
我使用测试文件,空文件和其他少量文本文件进行的测试效果很好(或者至少我认为是这样),但是在最后一个较长的测试文件中出了点问题,错误消息是: “应该返回'e'(101)for文件rfc791.txt。您返回了'b'(98)“ 。
所以我要问的是,我的代码可能出什么问题了,而突然之间最普通的字母不应该是什么?
int most_common_character(char *filename) {
FILE *f;
if ((f = fopen(filename, "r")) == NULL) {
fprintf(stderr, "Not opened: %s\n", strerror(errno));
return -1;
}
char frequency[26];
int ch = fgetc(f);
if (ch == EOF) {
return 0;
}
for (ch = 0; ch < 26; ch++) {
frequency[ch] = 0;
}
while (1) {
ch = fgetc(f);
if (ch == EOF) {
break;
}
if ('a' <= ch && ch <= 'z') {
frequency[ch - 'a']++;
}
else if ('A' <= ch && ch <= 'Z') {
frequency[ch - 'A']++;
}
}
int maxCount = 0;
int maxChar = 0;
for (int i = 0; i <= 26; ++i) {
if (frequency[i] > maxCount) {
maxCount = frequency[i];
maxChar = i;
}
}
fclose(f);
return maxChar + 'a';
}
如果有人有任何修复我的代码的提示,我将不胜感激:)我试图从许多其他相关主题中搜索此问题的解决方案,但似乎无济于事。
您应该在第二个for循环中使用<运算符。 因此,当您检查frequency [i]> maxCount时,在frequency [26]时,它表现为未定义的行为,这意味着该索引处的值可能小于或大于比较值。
您的代码确实存在一些问题。 但是,它们是如此之小,因此代码仍然可以在小型测试中很好地工作。
int ch = fgetc(f);
删除文件中的第一个字符
for (int i = 0; i <= 26; ++i)
超出数组的范围(仅从0-> 25)
除了这些小错误之外,您的代码还不错。 做得好#thumbsup
循环越界。 @风向标
// for (int i = 0; i <= 26; ++i) { for (int i = 0; i < 26; ++i) {
代码将丢弃第一个字符的结果。 @BLUEPIXY
int ch = fgetc(f); if (ch == EOF) { return 0; } // This value of ch is not subsequently used.
其他修复如下
int most_common_character(char *filename) {
...
// Use a more generous count @Weather Vane
// char frequency[26];
// Consider there may be more than 26 different letters
// fgetc return EOF and value in the unsigned char range
int frequency[UCHAR_MAX + 1] = { 0 };
// Not needed as array was initialize above
// for (ch = 0; ch < 26; ch++) { frequency[ch] = 0; }
// BTW correct type declaration of int, avoided rookie mistake of using char
int ch;
// Codes use tolower(), islower() as that is the portable way to
// handle type-of-character detection
while ((ch = fgetc(f)) != EOF) {
frequency[tolower(ch)]++; // could add check to insure frequency[] does not overflow
}
int maxCount = 0;
int maxChar = -1;
for (int i = 0; i <= UCHAR_MAX; ++i) {
if (islower(i) && frequency[i] > maxCount) {
maxCount = frequency[i];
maxChar = i;
}
}
fclose(f);
return maxChar;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.