0

次のような文字列 int int 形式のテキスト ファイルから値を読み取りたいとします。

testing 5 17
charlie 12 1
delta 88 4

fscanfを使用してファイルを読み取り、入力をいくつかの変数に入れ、それらをリンクリストノードとして挿入する関数に送信する関数があります。

void readFile(LinkedList *inList, char* file)
    {
    char* tempName;
    int tempLoc, tempNum;

    FILE* f;
    f = fopen(file, "r");
    if(f==NULL) 
        {
        printf("Error: could not open file");
        }
    else
        {
        while (fscanf(f, "%s %d %d", tempName, &tempLoc, &tempNum) != EOF)
            {
            insertFirst (inList, tempName, tempLoc, tempNum);
            }
        }   
    }

insertFirst 関数:

void insertFirst(LinkedList* list, char* inName, int inLoc, int inNumMeth)
    {
    LinkedListNode* newNode;
    newNode = (LinkedListNode*)malloc(sizeof(LinkedListNode));
    newNode->className = inName;
    newNode->loc = inLoc;
    newNode->numMethods;
    newNode->next = list->head;
    list->head = newNode;
    }

リンクされたリストをトラバースして値を出力すると、セグメンテーション違反でクラッシュする前に、名前に奇妙な記号 (�t) が表示され、int に正しくない数値が表示されます。原因究明に困っています。

4

5 に答える 5

4

あなたのfscanf呼び出しは、初期化されていないポインタに書き込んでいます。これは未定義の動作を引き起こし、クラッシュしないのは少し驚くべきことです。

文字列用のストレージを割り当てる必要があります

char tempName[30];

また、最大でこの数の文字を読み取るように呼び出しを変更fscanfし、名前、場所、メソッドの3つすべてが読み取られたことを確認する必要があります

while (fscanf(f, "%29s %d %d", tempName, &tempLoc, &tempNum) == 3)

classNameMarcus が指摘したように、 in にもストレージを割り当てる必要がありますLinkedListNode。最も簡単な方法はclassName、30 要素のchar配列を作成して使用することです。strcpy

strcpy(newNode->className, inName);

または、classNameとして残し、char*そのメモリを動的に割り当てることもできます

newNode->className = malloc(strlen(inName)+1);
/* check for newNode->className != NULL */
strcpy(newNode->className, inName);

これを行う場合はclassName、ノードを解放するときに必ず解放してください。

于 2013-05-17T07:53:14.390 に答える
1
char* tempName;

メモリ領域を指していません。メモリに割り当てずに fscanf で使用しました。

tempname 宣言を変更することで修正できます。

char tempName[MAX_NAME_SIZE];

または、宣言を保持して、fscanf の書式文字列指定子の"%ms"代わりに使用できます。"%s"

fscanf(f, "%ms %d %d", &tempName, &tempLoc, &tempNum)

%msfscanf が tempName にメモリを割り当てることを許可します。free()あなたの記憶が役に立たなくなったら、この記憶を解放しなければなりません

注記%msは、gcc のバージョンが > の場合に有効ですgcc 2.7

于 2013-05-17T07:53:21.933 に答える
0

また、inName; をディープ コピーする必要があります。あなたがしていることすべて

newNode->className = inName

実際の文字列データではなく、ポインターをコピーしています。strcpy を使用してそれを行うことができます。

于 2013-05-17T07:53:28.467 に答える