嗨,这是一个关于Kernighan和Ritchie关键字计数程序的问题(ANSI版第6章第3节)。我已经在下面的链接中包含整个代码。
当我尝试在任何 C 源代码上运行代码时,我没有得到任何输出。因此,为了查明问题所在,我在代码的不同点打印了语句。终端窗口中程序的输出(应用于自身时)现在如下所示:
./a.out < keywords.c
I've got past the beginning of the getword loop.
I've got past the beginning of the getword loop.
I'm past the word[0] condition.
Segmentation fault
当我使用另一种搜索方法(通过结构键数组进行线性搜索)时,我得到了相同输出的另一种组合,这次没有分割错误。根据 printf 语句的输出,我倾向于认为 getword 函数有问题。那么是什么导致了这些错误呢?
以下是具有二进制和线性搜索函数的完整代码:
http://pastebin.com/sPEYYge6
你的代码调用binsearch()
并尝试使用 mid
访问数组tab
但mid
从未初始化过,所以你死在那里。
int binsearch (char * word, struct key tab[], int n) {
int cond;
int low, high, mid;
low = 0;
high = n -1;
// Missing setting mid here!
while (low <= high) {
if ((cond = strcmp(word,tab[mid].word)) < 0) // That's going to be bad...
Mike 正确诊断分段错误是由 binsearch
中使用未初始化的mid
引起的。
代码中的进一步错误(我不是 100% 确定我发现了所有错误)是:
- 您的
getch()
是错误的,return (bufp > 0) ? BUFF[bufp--] : getchar();
返回索引bufp
处的 char,如果这是> 0
,但bufp
是缓冲区中存储的元素数量,应该在那里--bufp
。 - 在
ungetch
中,测试if (bufp > BUFFSIZE)
应使用>=
。
您从未找到任何关键字的原因是(使用更传统的缩进和间距):
// You loop until you find a non-space character
while (isspace(c = getch())) {
;
}
// If it's not a letter, this is not a word, return here
if (!isalpha(c)) {
*w = ' ';
return c;
}
// If it was a letter, read the following letters and store them in the buffer
for ( ; --lim > 0; w++) {
if (!isalnum(*w = getch())) {
ungetch(*w);
break;
}
}
您从不存储任何单词的第一个字母,因此当遇到volatile
时,缓冲区中仅存储olatile
。
只需在if
和for
循环之间添加*w++ = c;
即可修复它,并且您的程序可以正常工作(当getch
和ungetch
修复也进行了时)。