0

だから私はこの形式のテキストファイルを読んでいます:

ABC 51.555 31.555
DEF 23.445 45.345

fscanf() を使用してデータを解析しようとしています。このファイルは、ロードする方法で動的にする必要があるため、拡大または縮小する可能性があるため、malloc を使用し、以下の構造体にも格納したいのです。問題はスペースにあるか、フォーマット指定子全体を正しく記述していない可能性さえあると思います。これが私のコードです。

typedef struct data
{
    char name[4];
    char lat[7];
    char lng[7];
}coords;

int main(int argc, char *argv[])
{
    ////////////CREATES FILE POINTER/////////
    FILE* fp;
    ///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
    coords* cp;
    //////////OPENS FILE//////////
    fp = fopen(argv[1], "r");
    /////////GET THE TOTAL AMMOUNT OF LINES IN THE FILE/////////
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    rewind(fp);
    //////SKIPS FIRST LINE//////////
    while(fgetc(fp) != (int)'\n')
    {};

    /////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
    cp = malloc(sizeof(coords) * size);

    //////////READS FILE AND STORES DATA///////
    fscanf(fp,"%s[^ ] %s[^ ] %s[^\n]", cp->name, cp->lat, cp->lng);

    printf("%s\n%lf\n%lf\n", cp->name, cp->lat, cp->lng);
    fclose(fp);
    return 0;
}

はい、ヘッダーファイルを含めていないことは承知していますが、適切な stdlib と stdio を持っています

更新 1: 両方の返信を試しましたが、画面に次のように表示されます。

ABC51.555
0.000000
0.000000

51.555 が構造体の次の項目に移動していないのはなぜですか? ありがとう

/////////////////////////////////////////////// /////////////更新2///////////////////////////////// /////////////////////

さて、次のようにコードを変更しました。

typedef struct data
{
    char name[4];
    char lat[6];
    char lng[6];
}coords;

int main(int argc, char *argv[])
{
    ////////////CREATES FILE POINTER/////////
    FILE* fp;
    ///////////CREATES MALLOC POINTER TO STORE STRUCTS/////////////
    coords* cp;
    //////////OPENS FILE//////////
    fp = fopen(argv[1], "r");
    /////////GET THE TOTAL SIZE OF THE FILE/////////
    fseek(fp, 0, SEEK_END);
    long size = ftell(fp);
    long lines = -1;
    rewind(fp);
    //////GETS TOTAL AMMOUNT OF LINES/////////
    char c;
    while(c != EOF)
    {
        c = fgetc(fp);
         if(c == '\n')
         {
            lines++;
         }
    }
    rewind(fp);
    ////////////SKIPS FIRST LINE//////////
    while(fgetc(fp) != (int)'\n')
    {};
    /////////ASSIGNS MEMORY THE SIZE OF THE FILE TO //////////
    cp = malloc(sizeof(coords) * size);

    //////////READS FILE AND STORES DATA///////
    printf("Lines of text read: %d\n", lines);
    fscanf(fp,"%s %s %s[^\n]", cp[0].name, cp[0].lat, cp[0].lng);
    printf("%s\n", cp[0].name);


    fclose(fp);
    return 0;
}

cp[0].name; を印刷しようとすると、このように、スペースなしで最初の行全体を取得します。

 ABC51.55531.555

print cp[0].lat; を取得した場合 私はこれを取得します。

 51.55531.555

そして、私が cp[0].lng; を印刷するとき。私はこれを取得します。

 31.555

どれが唯一正しいのか、私はこの振る舞いを理解できません。なぜこのように振る舞うのですか?すべての投稿は、(私が最初に考えたように) fscanf の各 %s がそれらを連結せずに独自の変数に入れることを示唆しています。ドット表記または直接を使用するかどうかは問題ではありません->それでも同じ結果が得られます。ありがとう :)

4

2 に答える 2

1

フォーマット指定子"%s[^... は、空白で区切られた文字列を読み取ろうとし、その後に文字が続き、次に文字が続き[ます^。文字列は常に空白で終わるため、次の文字は常に空白になり[、 と一致せず、残りの書式指定子はどれも一致しません。

  • 常にの戻り値をチェックして、fscanf行ったことをすべて読んでいることを確認してください。戻り値が間違っている場合は、診断を行います。

  • 固定サイズの文字列配列を読み取るときは、常にフィールド サイズ制限を使用してください。

したがって、あなたの場合、あなたが望むのは次のとおりです。

if (fscanf(fp, "%3s%6s%6s", cp->name, cp->lat, cp->lng) != 3) {
    fprintf(stderr, "Incorrect data in input file, exiting!\n");
    abort(); }
于 2014-12-12T03:39:23.750 に答える
0

スペース区切り文字 [^ ] を使用するかどうかわかりません。fscanf は、デフォルトですでに空白の文字列を解析しています。これを試して、文字列が正しく解析されているかどうかを確認してください。

fscanf(fp, "%s %s %s[^\n]", cp->name, cp->lat, cp-lng);  

出力結果は次のようになります。

cp->name ---- ABC
cp->lat ----- 51.555
cp->lng ----- 31.555
于 2014-12-12T04:16:57.297 に答える