1

実装しようとしているコードは、.txt ファイルを読み取り、文字列をノードに変換するメソッドです。基本的に、.txt ファイルを読んでいるときは、最初に文字以外をチェックします (単語は数字で始めることも、単語のインデックスに英数字以外を含めることもできません)。最初の文字が見つかると、プログラムはループを終了し、スペースが見つかるまでループする別の文字に入ります。単語の作成に成功したら (スペースが見つかったときに単語が「終了」します)、リンクされたリストにその単語を入力します。

これを実行すると、Bus Error: 10 が発生します。これは word[b] 配列が原因だと思っていましたが、malloc しても同じエラーが発生します。

前もって感謝します!

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

#define TRUE 1
#define FALSE 0


struct Node{
   char value[100];
   int numOccur;
   int numVariance;
   struct Node *next;
};

void testprint(struct Node * head){
    int data;
    data = head->value;
    strcpy(data,head->value);
    while(head != NULL){

        printf("%s\n", data);
        head = head->next;
    }

}

int main()
{
   struct Node *curr;
   struct Node *n;
   struct Node *head =0;
   struct Node *tail =0;
   struct Node *next;
   char word[100];
   int a;
   int x;



   FILE *file1;
   file1 = fopen("test1.txt", "r");           //opens text file

   if(file1 == NULL){
       fprintf(stderr,"Error: Could not open file");     //if file1 has error, returns    error message
   exit(1);
   }
   a = fgetc(file1);
   int b = 0;
   while(a != EOF){
       while(!isalpha(a)){
           a = fgetc(file1);
           continue;
       }

       n = (struct Node *) malloc( sizeof( struct Node));
       while(isalnum(a)){
           while( a != ' ' && a != EOF){
               word[b] = a;
               a = fgetc(file1);
               b++;
           }
           word[b] = '\0';
       }
       n->next = 0;
       if(head == 0){
           head = n;
           tail = n;
       }
       else{
           tail->next = n;
           tail = n;
       }
   }
    testprint(head);
    fclose(file1);
}
4

1 に答える 1

3

コンパイラからの警告に注意を払う必要があります。-Wall -Wextra(そして、より多くの警告を取得するために、常に でコンパイルすることをお勧めします。)

Barney Hsiao が指摘したtestprint()ように、 Node ポインターの代わりに FILE ポインターで呼び出されます。


関係ありませんが、 truefalse の定数が必要な場合は、これらを提供する標準ヘッダー ファイルがあります (小文字で、つまりtrue, false)。

#include <stdbool.h>

このコードをコンパイルすると、次のコンパイラ警告が表示されます。

$ CFLAGS="-Wall -Wextra" make bus10
cc -Wall -Wextra bus10.c -o bus10
bus10.c: 関数 'testprint' 内:
bus10.c:20:14: 警告: 互換性のないポインター型からの代入
bus10.c: 関数 'main' 内:
bus10.c:48:8: 警告: 配列の添字の型は 'char' です
bus10.c:54:8: 警告: 配列の添字の型は 'char' です
bus10.c:68:23: 警告: 互換性のないポインター型からの代入
bus10.c:34:8: 警告: 未使用の変数 'x'
bus10.c:31:17: 警告: 未使用の変数 'next'
bus10.c:27:17: 警告: 未使用の変数 'c​​urr'
bus10.c:74:1: 警告: 制御が非 void 関数の終わりに達しました

現在、これらのいくつかは他のものよりも深刻です。「配列添え字の型は 'char' です」は、私には問題のようには思えません (正直なところ、それが何を意味するのかさえわかりません)。「未使用の変数」とは、変数を作成 (宣言) した後、それを使用しないことを意味します。「制御が非 void 関数の終わりに達する」とは、値を返すように宣言されている関数があるが、return ステートメントなしでコードが下に落ちることを意味します。

しかし、「互換性のないポインタ型からの割り当て」は悪いです。相容れないという言葉は悪い。20行目は次のとおりです。

     head = head->next;

68行目は次のとおりです。

        tail->next = n;

その理由は

struct Node{
   ...
   struct node *next;
};

見る?*nextではなくstruct Nodestruct nodeです。大文字/小文字のカウント。


Ok。ここに大きなものがあります。そして、コンパイラは何も言わなかった。まあ、公平を期すために、そうでした。しかし、それが何を意味するのか、私たちは知りませんでした。33行目:

    char a;

あなたが言うことの何が問題なのですか?キャラを抱え込むタイプですよね?問題はここにあります:

    a = fgetc(file1);

あなたはまだそれを見ますか?ここはどうですか?

    while(a != EOF){

EOF は、大きすぎて a に収まらないセンチネル値ですchar。このようになっているはずです。関数fgetcが、ファイルからの別のバイトだけでなく、End Of File 状態が発生したことを通知するには、char の範囲外の値を返す必要があります (0..255 符号なし、-128..127 符号付き)。 . EOF と等しい値を比較できないため、while条件が失敗することはありません。char

したがって、 ではなく、 であると宣言aします。intchar

于 2013-02-15T04:33:44.627 に答える