繁体   English   中英

C排序程序中的分段错误

[英]Segmentation fault in C sorting program

我正在用C开发一个函数,该函数对给定键周围的文本进行排序。 假设您有以下文件:

this line is first
but this line is second
finally there is this line

如果您运行该程序并将该文件作为输入,则应打印:

but this line is second
finally there is this line
this line is first

因为但是依字母顺序才最终在此之前。

但是,如果传递标志以对其他键进行排序,则会得到不同的输出。 例如,如果在此文件上调用fastsort -2,则应该得到:

this line is first
finally there is this line
but this line is second

因为线在此之前。 是的,我假设-2表示每行中的第二个单词(就像大多数人一样,除了总是希望从0开始的计算机科学家)。

而且,如果输入文件的特定行上不存在指定的键,则应仅将该行的最后一个单词用作键。 例如,如果用户想要对第4个单词(-4)进行排序,并且排序遇到这样的一行( 示例行 ),则排序应使用单词line对该进行排序。

我的问题来自最后一个假设,我使用strtok()提取键给定的单词,但是如果键大于行中的单词数,则会遇到分段错误。 这是函数的主体;

 typedef struct {
     char word[128];
     int index;
 } wordIndex;

char** fastsort(char** text, int word){

char** sortedText;
char* LineAux;
int i;
wordIndex tokenLines[numLines];

for(i=0; i<numLines; i++){
    char* token;
    int j = 0; //counter

    LineAux = (char*) malloc(MAX_LENGTH*sizeof(char)); //MAX_LENGTH = 128
    if (LineAux==NULL){
        fprintf(stderr,"Error, malloc failed");
        exit(1);
    }

    strcpy(LineAux,text[i]);

    token = strtok(LineAux, " \n");
    j++;

    if(token == NULL){ //if blank line
        token=" ";

    } else {

        while(token != NULL){  //segmentation fault
            if(j == word){
                break;
            }
            token = strtok(NULL, " \n");
            j++;

        }
    }

    strcpy(tokenLines[i].word,token);
    tokenLines[i].index=i;
    free(LineAux); //free Aux string
    printf("token: %s   Line: %d  \n",tokenLines[i].word, tokenLines[i].index);
}

qsort(tokenLines,numLines,sizeof(wordIndex),compareTo); //sorting tokens

sortedText = (char**) malloc(numLines*sizeof(char*));
if (sortedText==NULL){
    fprintf(stderr,"Error, malloc failed");
    exit(1);
}


//reordering text
int n; 
for (n=0; n<numLines; n++){
    int index;

    sortedText[n]=(char*) malloc(MAX_LENGHT*sizeof(char));

    if (sortedText[n]==NULL){
        fprintf(stderr,"Error, malloc failed");
        exit(1);
    }

    index = tokenLines[n].index;
    strcpy(sortedText[n],text[index]);

}


return sortedText;

}

分段错误出现在while循环内。 希望能对您有所帮助,谢谢。

我在机器上运行了上面的代码。 一个警告,它起作用。 word是1索引的,而不是您期望的0,因为j在与任何事物进行比较之前都会先递增。 因此,如果您输入0 ,就像您想要按第一个单词进行排序一样,这自然是不可能的:

if(j == word){

因此,您的while循环将继续直到token为NULL为止。 然后,在循环之后,您的strcpy崩溃,因为它试图引用传递给它的空指针:

strcpy(tokenLines[i].word,token); // don't NULL me bro!

这是您崩溃的原因。 要解决此问题,我将进行两项更改:

  1. 在循环之前摆脱j++ 让索引从0开始,因为这通常是在C语言中完成的操作,也是函数用户通常所期望的。

  2. 循环结束后,测试token以查看它是否为NULL 如果是这样,请优雅地退出该函数,可能会向用户返回某种错误。 如果有人输入无效的单词号而导致崩溃,则是错误的用户界面。

Allrigth,我有解决方案;

问题是while循环内的指令顺序。

这是有效的解决方案:

/**
 * Function that sorts text by a given key
 * @param text: array of strings which is going to be sorted
 * @param word: key where the sort starts
 * @return sorted text
 */
char** fastsort(char** text, int word){

    char** sortedText;
    char* LineAux;
    int i;
    wordIndex tokenLines[numLines];

    for(i=0; i<numLines; i++){
        char* token;
        int j = 0; //counter

        LineAux = (char*) malloc(MAX_LENGHT*sizeof(char));
        if (LineAux==NULL){
            fprintf(stderr,"Error, malloc failed");
            exit(1);
        }

        strcpy(LineAux,text[i]);

        token = strtok(LineAux, " \n");
        j++;

        if(token == NULL){ //if blank line
            token=" ";

        } else {

            while(token != NULL){  //segmentation fault
                strcpy(tokenLines[i].word,token);
                if(j == word){
                    break;
                }

                token = strtok(NULL, " \n");
                j++;

            }
        }

        tokenLines[i].index=i;
        free(LineAux); //free Aux string
    }

如您所见,这种更改不是很有效,但是它确实可以正常工作,如果您有其他解决方案,我将很乐意尝试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM