1

.txt ファイルから入力を読み込んで、それを単独のリンクリストに追加しようとしています。私が抱えている問題は、ノードが正しく作成されて接続されていることです (正しい長さを取得しています) が、すべてのノードを追加した後、各データ フィールドは同じです。私は問題が何であるか、そしてそれを修正する方法を考えていました。しばらくやってました!

機能を追加:

#include "linkedList.h"
#include <stdlib.h>
#include <string.h>

void addOrdered(Node ** Head,char * input)
{

        printf("\nInput: %s\n",input);

        Node * cur = (*Head);

        Node * newNode = malloc(sizeof(Node));
        newNode->Data = malloc(sizeof(Person));

        newNode->Data->FName = strtok(input," ");
        newNode->Data->LName = "test";
        newNode->Data->id = 5;
        newNode->Next = NULL;

        if(cur == NULL)
        {
            (*Head) = newNode;
        }
        else
        {

            for(;cur->Next != NULL;cur = cur->Next)
            {
                printf(" Cur->Next ");
            }

            cur->Next = newNode;
        }
}

処理中のファイル:

void processFile(Node ** Head, FILE * fd)
{
    char * input = malloc(sizeof(char)*SIZE);

    while(fgets(input,SIZE,fd) != NULL)
    {
        addOrdered(Head,input);
    }


    free(input);
}
4

2 に答える 2

1

strtok は文字列で見つかった最後のトークンへのポインタを返します。取得するトークンが残っていない場合は、null ポインターが返されます。次のようなことをする必要がありますpch = strtok(input," ");

于 2013-04-06T05:05:42.667 に答える
1

あなたのコードのバグは次のとおりです。processFile() 関数を呼び出すとアドレスの割り当てnewNode->Data->FNameが無効になりfree(input)、空きメモリにアクセスすると、実行時に「未定義の動作」が発生します。

コードを修正するには:

次のような単純な代入の代わりに:

newNode->Data->FName = strtok(input," ");

以下のように別のメモリに割り当ててコピーします。

char *ptr =  strtok(input," ");
newNode->Data->FName = malloc(strlen(ptr)+1);
strcpy(newNode->Data->FName, ptr);

実際にはinputaddOrdered() でアドレス空間からメモリアドレスを割り当てていてfree()processFile()関数を作ります。

以下にコードを詳しく説明します。

最初の読み取り: char * strtok ( char * str, const char * delimiters ); マニュアル:

最初の呼び出しでは、関数は str の引数として C 文字列を予期します。その最初の文字は、トークンをスキャンする開始位置として使用されます。後続の呼び出しでは、関数は null ポインターを予期し、最後のトークンの末尾の直後の位置をスキャンの新しい開始位置として使用します。

戻り値

文字列で見つかった最後のトークンへのポインター。取得するトークンが残っていない場合は、null ポインターが返されます。

新しいメモリを送信するのではなく、input最近 free() したメモリを送信します。strtok() 関数の動作を理解するために、次のコードを書きました。

int main (){
  char str[] ="- This, a sample string.";
  printf("str address: %p, ends on:  %p \n", str, str+strlen(str));
  printf ("Splitting string \"%s\" into tokens:\n",str);
  char * pch;
  pch = strtok (str," ,.-");
  while (pch != NULL){
    printf ("pch: %7s,  address: %p\n",pch, pch);
    pch = strtok (NULL, " ,.-");
  }
  return 0;
}

上記のプログラムの実行 (アドレスは実行ごとに異なる場合があります):

~$ ./a.out 
str address: 0x7fff96958d50, ends on:  0x7fff96958d68 
Splitting string "- This, a sample string." into tokens:
pch:    This,  address: 0x7fff96958d52
pch:       a,  address: 0x7fff96958d58
pch:  sample,  address: 0x7fff96958d5a
pch:  string,  address: 0x7fff96958d61

注意:アドレスは アドレス scapepchから/内にあります。str

newNode->Data->FName = strtok(input," ");コードでも同様に、関数内に割り当てaddOrdered()ます。のメモリアドレス値 newNode->Data->FNameは、後で関数input内で解放するため、無効になり、コードは未定義の動作として実行されますprocessFile()newNode->Data->FName

void addOrdered(Node ** Head,char * input){

        printf("\nInput: %s\n",input);
        // some code here
                                                     step-2 
        newNode->Data->FName = strtok(input," "); <--"assign memory"  
                                                ^
      //  Some code here                        |
}                                               |   
                                                |  
void processFile(Node ** Head, FILE * fd){      |    step-1
    char * input = malloc(sizeof(char)*SIZE); <-|----"Allocate memory"
    while(fgets(input,SIZE,fd) != NULL){        |
        addOrdered(Head,input); -----------------
    }                                                step-3  
    free(input); <-----------------------------------"Free memory"
}

So, "What is assign to newNode->Data->FName becomes invalid"

次に、バッファ内のファイルから 1 つ少ない文字を読み取り、 null 用のスペースを確保する必要があります\0

fgets(input, SIZE-1, fd)
于 2013-04-06T05:05:52.447 に答える