0

fscanf 関数が呼び出されると、プログラムがハングします。理由がわかりません。次のテキスト ファイルから情報を読み取ろうとしています。

     R1 N001 N003 20
     R2 N002 N001 5
     R3 N001 0 10
     R4 N002 N003 10
     R5 N003 N000 5
     I1 0 N002 10

これが私の構造です:

    #include<stdlib.h>
    #include<stdio.h>
    #ifndef MYDATA_H_
    #define MYDATA_H_

    typedef struct comp{
       char *name;
       char *node1;
       char *node2;
       float val;
    } ComponentType;

    typedef struct ListNodeT{
       ComponentType Component;
       float currnet;
       float voltage;
       float power;
    } ListNodeType;

    #endif

これは、テキスト ファイルを読み取り、ComponentType の構造を設定する関数です。

void ReadFile (ComponentType *CircuitData, int *numEl, int *numNodes){
*numEl = 0;
*numNodes = 0;
int index= 0;
FILE *myFile = fopen("mydata.dat", "r");


if (myFile == NULL){
    printf("Error: File the file is not open");
}
printf("This worked\n"); //gets to this point

while (!feof(myFile)){
fscanf(myFile,"%cf",CircuitData[index].name,
    CircuitData[index].node1,CircuitData[index].node2,
    &CircuitData[index].val);
printf("\nfscanf works");
*CircuitData[index].node1 = intFromString(CircuitData[index].node1);
*CircuitData[index].node2 = intFromString(CircuitData[index].node2);


    if ((int)CircuitData[index].node1 > *numNodes ){
        *numNodes = (int)CircuitData[index].node1;
    }

    if ( (int)CircuitData[index].node2 > *numNodes ){
        *numNodes = (int)CircuitData[index].node2;
    }

    (*numEl)+=1;
    index++;
}
fclose(myFile);
4

1 に答える 1

2

コードに多くのエラーがあります。

呼び出しから始めましょうfscanf: 単一の文字を読み取る形式しかありませ"%c"んが、解析したい多くの値があります。変数ごとに 1 つのフォーマット コードが必要であり、正しい必要があります (つまり"%s"、文字列の場合)。

fscanf(myFile, " %s %s %s %f",
    CircuitData[index].name,
    CircuitData[index].node1,
    CircuitData[index].node2,
    &CircuitData[index].val);

入力の先頭の空白をスキップするように指示する先頭のスペースに注意してください。fscanfこれは、改行が前の行からの入力バッファにまだあるために必要です。

次に、上記のコードがクラッシュする可能性のある原因について説明します。文字列にメモリを割り当てる必要があります。動的に割り当てる (例: CircuitData[index].name = malloc(SOME_SIZE)) か、配列として宣言する (例: char name[SOME_SIZE])。

node1およびフィールドを使用する場合node2、これらは実際には整数フィールド (例: int node1) である必要があります。次に、 で読み取る文字列用の一時変数がいくつか必要ですfscanf。また、標準ライブラリには、次のような文字列を整数に変換する関数がありますstrtol

CircuitData[index].node1 = strtol(temp_node1, NULL, 10);

また、読み取りループにも問題があり、次のようにする必要があります。

while (fscanf(...) == 4) { ... }

そしてもちろん、CircuitData配列にメモリを割り当てたと思いますか?

現在、ポインター関連のエラーは他にもたくさんありますが、変更node1node2て整数にすると、そのうちのいくつかは解決されます。

于 2013-10-15T09:30:27.647 に答える