无法将文本的所有单词存储在字符数组中

unable to store all the words of a text in a character array

我想将文本中的单词存储在二维字符数组中,其中相同的单词只存储一次。问题是程序似乎没有存储最后几个字。我已经包含了整个程序,因为我无法找出有问题的部分。 这是我的尝试:

#include <stdio.h>
#include <ctype.h>
#include <string.h>
#define N 20
#define M 110

int main() { 
    char text[M], c[N][N], word[N];
    int i, j, k=0, l=0, d, v;

    for(i=0; i<N; i++) {
        for(j=0; j<N; j++) {
            c[i][j]='[=10=]';
        }
    } 
    for(i=0; i<M; i++) {
        text[i]='[=10=]';
    }    
    for(i=0; i<N; i++) {
        word[i]='[=10=]';
    }    
    for(i=0; i<M; i++) {
        d=scanf("%c", &text[i]);  
        if(d==EOF) {
            text[i]='[=10=]';
            break;
        }    
    }        
    for(i=0; i<strlen(text); i++) {    
        if(isspace(text[i])==0) {
            word[l]=tolower(text[i]);
            l++;
        }
        if((i==strlen(text)-1)||((isspace(text[i])!=0)&&(isspace(text[i+1])==0))) {    
            for(v=0; v<i; v++) {
                for(j=0; j<N; j++) {
                    if(word[j]!=c[v][j]) {
                        break;
                    }
                }
                if(j==N) {
                    l=0;
                    break;
                }
            }
            if(v==i) {  
                for(j=0; j<l; j++) { 
                    c[k][j]=word[j];
                }
                k++;
                l=0;
            }
        }
    }
    printf("\n\n");
    for(i=0; i<N; i++) { 
        for(j=0; j<N; j++) {
            printf("%c", c[i][j]);
        }    
        printf(" ");
    }        
    return 0;
}

对于某些输入,并不是所有的单词都被打印出来(没有存储?)。 例如输入:a b c d e f g h i k l m n o pCtrl+D 输出是:a b c d e f g h i k

我注意到,如果我增加 N 并提供相同的输入,打印的字数也会增加。任何帮助将不胜感激。

编辑:

如果我们替换

for(v=0; v<i; v++)
for(j=0; j<N; j++)
//...
if(j==N)
//...
if(v==i)

for(v=0; v<k; v++)
for(j=0; j<l; j++)
//...
if(j==l)
//...
if(v==k)

程序运行正常。

如何使用调试器查找错误

首先,为了让您在调试器中重新启动程序时不必输入一长串输入,我建议您更换代码

for(i=0; i<M; i++) {
    d=scanf("%c", &text[i]);  
    if(d==EOF) {
        text[i]='[=10=]';
        break;
    }    
} 

与:

strcpy( text, "a b c d e f g h i j k l m n o p" );

这样,您在问题中指定的输入将被硬编码到程序中,不再需要键盘输入。

如果你的 运行 你的程序在调试器中,在关键位置设置断点,然后 运行 逐行运行程序,那么你会注意到

if(word[j]!=c[v][j]) {

变量 v 有时具有值 20。这是越界访问数组 c,因为有效索引仅为 019。这会导致未定义的行为,并导致您的程序错误地认为该词已存在于数组中,因此不会打印它。

如何修复错误

上一节中描述的错误可能是由于行

for(v=0; v<i; v++) {

错了。变量 v 应限制为 N,而不是 i。因此,您应该将该行更改为以下内容:

for(v=0; v<N; v++) {

如果你随后也更改行

if(v==i) {

if(v==N) {

那么程序就有了预期的输出。

其他备注

还值得注意的是,您向输出流发送了将近 400 个空字符。您的 terminal/console 似乎忽略了它们而不是显示它们,但某些终端的行为可能有所不同。因此,您可能需要更改行

for(i=0; i<N; i++) {
    for(j=0; j<N; j++) {
        printf("%c", c[i][j]);
    }
    printf(" ");
}

以下内容:

for(i=0; i<N; i++) {
    printf("%s", c[i]);
    printf(" ");
}

这样,空字符就不会被发送到输出流。但是,如果这样做,您只能在每个字符串中存储 19 个字符而不是 20 个字符,因为终止空字符现在需要一个额外的字节。您可能需要更改代码以强制执行此限制。