0

テキストファイルを読み取り、すべての行をchar配列に入れ、その行をリンクリストノードに格納するCプログラムに取り組んでいます。リンク リストを作成するプロセスは機能しているようですが、リンク リストに保存されているテキストを母音なしで出力するはずの関数を呼び出すと (理由は聞かないでください!)、セグメンテーション エラーが発生します。 ...母音なしですべてのテキストを印刷した後。

LinkedList ノードは次のようになります。

typedef struct linked_list_node link;

struct linked_list_node {
char* word;
link* next;
};

母音なし関数は次のようになります。

void print_no_vowels(link* lines)
{
char vowels[] = "aeiouy";
unsigned int i = 0;
unsigned int j = 0;
unsigned int check = 0;
link* first = lines;

while(first != NULL)
{
    printf("%p\n", first);
    for(i = 0; i < strlen(first->word)-1; i++)
    {
        for(j = 0; j < strlen(vowels)-1; j++)
        {
            if(first->word[i] == vowels[j])
            {
                check = 1;
            }
        }
        if(check != 1)
        {
            printf("%c", first->word[i]);
        } else {
            check = 0;
        }
    }
    printf("\n");

    first = first->next;
}
}

多くの printf-ing の後、最初のポインターが NULL を指す必要がある後でも、プログラムが再び print_no_vowels 関数で while ループに入るという結論に達しました。なぜこれが起こるのか分かりません - 同じ方法を使用してリンクされたリストを反復処理する他のすべての関数では、プログラムは最初の == NULL のときに再び while ループに入りません。

どんな助けでも大歓迎です、事前に感謝します!


編集:

これは、リンクされたリストの init 関数です。

link* read_file(FILE *input)
{
char line[100];
link *first = malloc(sizeof(link));
first->word = NULL;
link *curr = NULL;
while(fgets(line, 100, input) != NULL)
{
    if(first->word == NULL)
    {
        first->word = malloc(100);
        strcpy(first->word, line);
        first->next = malloc(sizeof(link));
        curr = first->next;
    }
    else
    {
        if(line != NULL)
        {
            curr->word = malloc(100);
            strcpy(curr->word, line);
            curr->next = malloc(sizeof(link));
            curr = curr->next;
        }
    }
}

return first;
}

あなたがそう言う前に -- 私は C の初心者であることを知っています。

4

2 に答える 2

1

nextクラッシュは、新しく割り当てられた のポインターを NULL に確実に設定していないためですlinkが、反復はそれが NULL であることに依存しています。また、文字を読み取る前にfirst->wordNULL でないことを確認する必要があります。print_no_vowels()

また、あなたは望んでいませんstrlen(vowels)-1- それは y を残します。

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

typedef struct linked_list_node link;

struct linked_list_node
{
    char *word;
    link *next;
};

static void print_no_vowels(link *lines)
{
    char vowels[] = "aeiouy";
    unsigned int i = 0;
    unsigned int j = 0;
    unsigned int check = 0;
    link *first = lines;

    while (first != NULL && first->word != NULL)
    {
        printf("%p: ", first);
        for (i = 0; i < strlen(first->word)-1; i++)
        {
            for (j = 0; j < strlen(vowels); j++)
            {
                if (first->word[i] == vowels[j])
                {
                    check = 1;
                }
            }
            if (check != 1)
            {
                printf("%c", first->word[i]);
            }
            else
            {
                check = 0;
            }
        }
        printf("\n");

        first = first->next;
    }
}

static link *read_file(FILE *input)
{
    char line[100];
    link *first = malloc(sizeof(link));
    first->word = NULL;
    first->next = NULL;
    link *curr = NULL;
    while (fgets(line, 100, input) != NULL)
    {
        if (first->word == NULL)
        {
            first->word = malloc(100);
            strcpy(first->word, line);
            first->next = malloc(sizeof(link));
            curr = first->next;
        }
        else
        {
            curr->word = malloc(100);
            strcpy(curr->word, line);
            curr->next = malloc(sizeof(link));
            curr = curr->next;
        }
        curr->next = NULL;
        curr->word = NULL;
    }

    return first;
}

int main(void)
{
    link *list = read_file(stdin);
    if (list != 0)
        print_no_vowels(list);
    return 0;
}

ソース コードでプログラムを実行すると、次の結果が得られます。

0x7fe75b4000e0: #ncld <std.h>
0x7fe75b403a80: #ncld <stdlb.h>
0x7fe75b403b00: #ncld <strng.h>
0x7fe75b403b80: 
0x7fe75b403c00: tpdf strct lnkd_lst_nd lnk;
0x7fe75b403c80: 
0x7fe75b403d00: strct lnkd_lst_nd
0x7fe75b403d80: {
0x7fe75b403e00:     chr *wrd;
0x7fe75b403e80:     lnk *nxt;
0x7fe75b403f00: };
0x7fe75b403f80: 
0x7fe75b404000: sttc vd prnt_n_vwls(lnk *lns)
0x7fe75b404080: {
0x7fe75b404100:     chr vwls[] = "";
0x7fe75b404180:     nsgnd nt  = 0;
0x7fe75b404200:     nsgnd nt j = 0;
0x7fe75b404280:     nsgnd nt chck = 0;
0x7fe75b404300:     lnk *frst = lns;
0x7fe75b404380: 
0x7fe75b404400:     whl (frst != NULL && frst->wrd != NULL)
0x7fe75b404480:     {
0x7fe75b404500:         prntf("%p: ", frst);
0x7fe75b404580:         fr ( = 0;  < strln(frst->wrd)-1; ++)
0x7fe75b404600:         {
0x7fe75b404680:             fr (j = 0; j < strln(vwls); j++)
0x7fe75b404700:             {
0x7fe75b404780:                 f (frst->wrd[] == vwls[j])
0x7fe75b404800:                 {
0x7fe75b404880:                     chck = 1;
0x7fe75b404900:                 }
0x7fe75b404980:             }
0x7fe75b404a00:             f (chck != 1)
0x7fe75b404a80:             {
0x7fe75b404b00:                 prntf("%c", frst->wrd[]);
0x7fe75b404b80:             }
0x7fe75b404c00:             ls
0x7fe75b404c80:             {
0x7fe75b404d00:                 chck = 0;
0x7fe75b404d80:             }
0x7fe75b404e00:         }
0x7fe75b404e80:         prntf("\n");
0x7fe75b404f00: 
0x7fe75b404f80:         frst = frst->nxt;
0x7fe75b405000:     }
0x7fe75b405080: }
0x7fe75b405100: 
0x7fe75b405180: sttc lnk *rd_fl(FILE *npt)
0x7fe75b405200: {
0x7fe75b405280:     chr ln[100];
0x7fe75b405300:     lnk *frst = mllc(szf(lnk));
0x7fe75b405380:     frst->wrd = NULL;
0x7fe75b405400:     frst->nxt = NULL;
0x7fe75b405480:     lnk *crr = NULL;
0x7fe75b405500:     whl (fgts(ln, 100, npt) != NULL)
0x7fe75b405580:     {
0x7fe75b405600:         f (frst->wrd == NULL)
0x7fe75b405680:         {
0x7fe75b405700:             frst->wrd = mllc(100);
0x7fe75b405780:             strcp(frst->wrd, ln);
0x7fe75b405800:             frst->nxt = mllc(szf(lnk));
0x7fe75b405880:             crr = frst->nxt;
0x7fe75b405900:         }
0x7fe75b405980:         ls
0x7fe75b405a00:         {
0x7fe75b405a80:             crr->wrd = mllc(100);
0x7fe75b405b00:             strcp(crr->wrd, ln);
0x7fe75b405b80:             crr->nxt = mllc(szf(lnk));
0x7fe75b405c00:             crr = crr->nxt;
0x7fe75b405c80:         }
0x7fe75b405d00:         crr->nxt = NULL;
0x7fe75b405d80:         crr->wrd = NULL;
0x7fe75b405e00:     }
0x7fe75b405e80: 
0x7fe75b405f00:     rtrn frst;
0x7fe75b405f80: }
0x7fe75b406000: 
0x7fe75b406080: nt mn(vd)
0x7fe75b406100: {
0x7fe75b406180:     lnk *lst = rd_fl(stdn);
0x7fe75b406200:     f (lst != 0)
0x7fe75b406280:         prnt_n_vwls(lst);
0x7fe75b406300:     rtrn 0;
0x7fe75b406380: }

コードにはまだ改善の余地がたくさんありますが、少なくともクラッシュはしていません。とりわけ、リストを解放するコードを記述する必要があります。を使用するには、まだ修正する必要がありますstrdup()

于 2013-09-14T20:33:11.207 に答える
0
for(i = 0; i < strlen(first->word)-1; i++)
    {
        for(j = 0; j < strlen(vowels)-1; j++)

strlen()-1 を使用するのではなく、単純に strlen を使用します。空白行からの空の文字列は、i を 0xFFFFFFFF にアンダーフローさせ (32 ビット アーキテクチャで実行している場合)、ワードで無効なメモリにアクセスする原因となります。

編集:リストの最後の要素をNULLに初期化する必要もあります

 curr = first->next;
 curr->next = NULL;

curr = curr->next;
curr->next = NULL;
于 2013-09-14T20:12:10.503 に答える