0

テキスト ファイルを読み込んで、文字列を単語ごとにリンク リストに追加しようとしています。私はCの初心者で、ポインターをよく理解していません。いじっているだけでいくつかの異なるエラーが発生しましたが、現在、挿入メソッドでセグメンテーション違反が発生しています。それは実際にはかなりイライラします。誰かが私がここで間違っていることを説明できますか?

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

struct listNode {  /* self-referential structure */
   char data[50];
   struct listNode *nextPtr;
};

typedef struct listNode LISTNODE;
typedef LISTNODE *LISTNODEPTR;

void insert(LISTNODEPTR *, char[]);
void printList(LISTNODEPTR);
char fpeek(FILE *);

main() {

    FILE *fptr;
    char file_name[20];
    int nrchar = 0;
    LISTNODEPTR startPtr = (struct listNode *) malloc(sizeof(struct listNode));
    char word[50];
    char c;
    int i;

    printf("What is the name of the file in which the text is stored?\n");
    scanf("%s",file_name);
    //  printf("Type the number of characters per line");
    //scanf("%d", &nrchar);
    fptr = fopen(file_name,"r");
        while(fpeek(fptr) != EOF) {
      i = 0;
      while(fpeek(fptr) != ' '){
        word[i] = fgetc(fptr);
        i++;
        printf("%d", i);
      }
      word[strlen(word)] = '\0';
      insert(&startPtr, word);
      word[0] = '\0';
    }
    fclose(fptr);
    printList(startPtr);


return 0;
}

    /* Insert a new value into the list in sorted order */
    void insert(LISTNODEPTR *sPtr, char value[])
    {
      LISTNODEPTR newPtr, currentPtr;

      newPtr = malloc(sizeof(LISTNODE));
      strcpy(newPtr->data, value);
      newPtr->nextPtr = NULL;
      currentPtr = *sPtr;

      while(currentPtr != NULL){
        currentPtr = currentPtr->nextPtr;
      }
      currentPtr->nextPtr = newPtr;

    }


    /* Return 1 if the list is empty, 0 otherwise */
    int isEmpty(LISTNODEPTR sPtr)
    {
       return sPtr == NULL;
    }

    /* Print the list */
    void printList(LISTNODEPTR currentPtr)
    {
       if (currentPtr == NULL)
          printf("List is empty.\n\n");
       else {
          printf("The list is:\n");

          while (currentPtr != NULL) {
             printf("%s --> ", currentPtr->data);
             currentPtr = currentPtr->nextPtr;
          }

          printf("EOF\n\n");
       }
    }

    char fpeek(FILE *stream) {
        char c;
        c = fgetc(stream);
        ungetc(c, stream);
        return c;
    }
4

3 に答える 3

3

まず、fopen() などのライブラリ関数からの戻り値を確認します。

次に、simonc の回答を参照してください。

第三に、このループの後:

  while(currentPtr != NULL){
    currentPtr = currentPtr->nextPtr;
  }
  currentPtr->nextPtr = newPtr;

currentPtr は null であるためcurrentPtr->nextPtr = newPtr;、null ポインターを逆参照します。おそらく次のようなもの

  while(currentPtr && currentPtr->nextPtr) {
    currentPtr = currentPtr->nextPtr;
  }
  currentPtr->nextPtr = newPtr;

あなたが探しているものはもっとあります。

ついに、

char fpeek(FILE *stream) {
    char c;
    c = fgetc(stream);
    ungetc(c, stream);
    return c;
}

する必要があります

int fpeek(FILE *stream) {
    int c;
    c = fgetc(stream);
    ungetc(c, stream);
    return c;
}

そして主に

char fpeek(FILE *);

する必要があります

int fpeek(FILE *);
于 2013-10-14T21:26:54.710 に答える
0

私はあなたのコードをざっと見て、セグメンテーションの問題がここにあると確信しています:

while(currentPtr != NULL){
   currentPtr = currentPtr->nextPtr;
}
currentPtr->nextPtr = newPtr;

currentPtrこれが行うことは、 nullになるまでリストをループすることです。次に、null ポインター ( ) を介して構造体フィールドを割り当てようとしていますcurrentPtr->nextPtr。これにより、セグメンテーション フォールトが発生します。

于 2013-10-14T21:28:56.787 に答える
0

わかりました、これはここにあります:

while(fpeek(fptr) != EOF) {
      i = 0;
      while(fpeek(fptr) != ' '){
        word[i] = fgetc(fptr);
        i++;
        printf("%d",i);
      }
      word[i] = '\0';
      insert(&startPtr, word);
      printf("%c", word[4]);
      word[0] = '\0';
    }

完全なコードを実行すると、12345oooooooooooooooooooooo... などと出力されます。私のテスト ファイルでは、最初の単語は「Hello」なので、無限の「o」はそこから来ています。外側のループが無限ループの場合、2 番目の while ループも複数回実行されませんか? つまり、なぜ 2 番目の print ステートメントだけが繰り返されるのでしょうか?

于 2013-10-15T17:21:18.440 に答える