分段错误 (C)

Segmentation Fault Error (C)

我目前正在编写一个程序,该程序应该从文本文件接收输入并输出有关文本的统计信息,例如字母数量、单词大小、出现频率以及每个单词出现次数.但是,每次我 运行 该程序时,我都会收到一个分段错误。程序 运行s 直到我点击行 Letter Count Analysis。我收到分段错误错误。这是一些示例文本:

1 你好,我的名字是鲍勃 我住在加拿大

数字表示应该读取多少行。我应该怎么做才能纠正我的问题?我对编程很陌生,所以我确定它是基础知识。

 #include <stdio.h>
 #include <string.h>


#define MAX_LINE_LENGTH 80
#define MAX_WORD_LENGTH 20
#define MAX_LINES 10

void letterAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);
int wordLengthAnalysis(char [][MAX_LINE_LENGTH], int lineTotal, int wordLength);
void wordAnalysis(char [][MAX_LINE_LENGTH], int lineTotal);


int main (void){

    int lineTotal, wordSize;
    char text[lineTotal][MAX_LINE_LENGTH];
    char n[1];

    fgets(n, 10, stdin);
    lineTotal = n[0] - '0';


    for(int i = 0; i < lineTotal; i++){
        fgets(text[i], MAX_WORD_LENGTH, stdin);
    }

    printf("\n***Letter count analysis***\n");
    letterAnalysis(text, lineTotal);

    printf("\n***Word length analysis***\n");
    for (int i = 1; i <= MAX_WORD_LENGTH; i++){
        wordSize = wordLengthAnalysis(text, lineTotal, i);
        if (wordSize == 1){
            printf("\n%-2d\tword of length %d", wordSize, i);
        }
        else{
            printf("\n%-2d\twords of length %d", wordSize, i);
        }
    }

    printf("\n\n***Word analysis***\n");
    wordAnalysis(text, lineTotal);

    return 0;

}

void letterAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){

    int alphabet[26] = {0};

    for (int i = 0; i < lineTotal; i++){
        for(int j = 0; j < MAX_LINE_LENGTH; j++){
            switch(text[i][j]){
                case 'A': case 'a':
                alphabet[0]++;
                break;
                case 'B': case 'b':
                alphabet[1]++;
                break;
                case 'C': case 'c':
                break;
                alphabet[2]++;
                case 'D': case 'd':
                alphabet[3]++;
                break;
                case 'E': case 'e':
                alphabet[4]++;
                break;
                case 'F': case 'f':
                alphabet[5]++;
                break;
                case 'G': case 'g':
                alphabet[6]++;
                break;
                case 'H': case 'h':
                alphabet[7]++;
                break;
                case 'I': case 'i':
                alphabet[8]++;
                break;
                case 'J': case 'j':
                alphabet[9]++;
                break;
                case 'K': case 'k':
                alphabet[10]++;
                break;
                case 'L': case 'l':
                alphabet[11]++;
                break;
                case 'M': case 'm':
                alphabet[12]++;
                break;
                case 'N': case 'n':
                alphabet[13]++;
                break;
                case 'O': case 'o':
                alphabet[14]++;
                break;
                case 'P': case 'p':
                alphabet[15]++;
                break;
                case 'Q': case 'q':
                alphabet[16]++;
                break;
                case 'R': case 'r':
                alphabet[17]++;
                break;
                case 'S': case 's':
                alphabet[18]++;
                break;
                case 'T': case 't':
                alphabet[19]++;
                break;
                case 'U': case 'u':
                alphabet[20]++;
                break;
                case 'V': case 'v':
                alphabet[21]++;
                break;
                case 'W': case 'w':
                alphabet[22]++;
                break;
                case 'X': case 'x':
                alphabet[23]++;
                break;
                case 'Y': case 'y':
                alphabet[24]++;
                break;
                case 'Z': case 'z':
                alphabet[25]++;
                break;
            }       
        }
    }

    for(int i = 0; i <= 25; i++){
        printf("%c: \t%d\n",'a' + i, alphabet[i]);;
    }
}

int wordLengthAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal, int wordLength){

    int sentenceLength;
    int counter, wordSize = 0;

    for(int i = 0; i < lineTotal; i++){
        sentenceLength = strlen(&text[i][0]);
        for(int j = 0; j < sentenceLength + 2; j++){
            if(text[i][j] == ' '){
                if(counter == wordLength){
                    ++wordSize;
                    counter = 0;
                }
                else{
                counter = 0;
                }
            }
            else{
                counter++;
            }
        }
    }

    return wordSize;
}

void wordAnalysis(char text[][MAX_LINE_LENGTH], int lineTotal){

    char maxWords[800];
    char word[MAX_LINE_LENGTH], word2[MAX_WORD_LENGTH], *ptrText, *ptrTextCounter;
    int counter, textCounter = 0;
    int sentenceLength, wordTracker;
    int lineFlag;

    for(int i = 0; i < lineTotal; i++){
        ptrText = &text[i][0];
        sentenceLength = strlen(ptrText);
        counter = 0;

        for (int j = 0; j < sentenceLength + 1; j++){
            wordTracker = 1;

            if (text[i][j] == ' ' ){
                if (counter != 0){
                    sprintf(word, "%.*s", counter, ptrText);
                    ptrTextCounter = &text[i][j+1];
                    lineFlag = j;

                if(strstr(maxWords, word) == NULL){
                    for (int k = i; k < lineTotal; k++){
                        textCounter = 0;

                        if (lineFlag == j){
                            ptrTextCounter = &text[i][j+1];
                        }
                        else{
                            lineFlag = 0;
                            ptrTextCounter = &text[i][j+1];
                        }

                        for ( ; lineFlag < sentenceLength; lineFlag++){
                            if(text[k][lineFlag] == ' '){
                                if (textCounter != 0){
                                    if(textCounter == counter){
                                        sprintf(word2, "%.*s", textCounter, ptrTextCounter);
                                            if(strcmp(word, word2) == 0){
                                                wordTracker++;
                                            }
                                    }
                                    ptrTextCounter = &text[k][lineFlag];
                                    textCounter = 0;
                                }
                                else{
                                    ptrTextCounter = &text[k][lineFlag+1];
                                }
                            }
                            else{
                                textCounter++;
                            }
                        }
                    }

                    if(wordTracker == 1){
                        printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
                    }
                    else{
                        printf("\n\"%.*s\"\t\tappeared %d time", counter, ptrText, wordTracker);
                    }
                }


                strcat(maxWords, word);
                    ptrText = &text[i][j+1];
                    counter = 0;
                }
                else{
                    ptrText = &text[i][j+1];
                }
            }
            else{
                counter++;
            }
        }

    }


}

我收到了一些警告:

main.c:17:14: warning: variable length array used [-Wvla]
    char text[lineTotal][MAX_LINE_LENGTH];
             ^
main.c:17:15: warning: variable 'lineTotal' is uninitialized when used here [-Wuninitialized]
    char text[lineTotal][MAX_LINE_LENGTH];
              ^~~~~~~~~

您尚未初始化 lineTotal 但正在使用它。这会导致未定义的行为。

main.c:64:21: warning: code will never be executed [-Wunreachable-code]
                    alphabet[2]++;
                    ^~~~~~~~

您的 break; 可能放错地方了。

main.c:152:20: warning: variable 'counter' may be uninitialized when used here [-Wconditional-uninitialized]
                if(counter == wordLength){
                   ^~~~~~~

同样,您正在使用一个可能未初始化的变量。

还有:

char n[1];

fgets(n, 10, stdin);

您的数组只有一个元素,但您告诉 fgets 它最多可以访问 n[10]

提示(如果不是很明显):永远不要在没有警告的情况下编写 C 程序。