3

入力ファイルを取得して保存する C プログラムを作成しています。入力ファイルには 2 つの列があり、次のように、最初の列に整数、2 番目の列に文字列が含まれます。

    12  apple
    17  frog
    20  grass

fgets を使用して行全体を文字列として取得し、scanf を使用して分割しようとしましたが、多くの問題が発生しています。かなり検索しましたが、私の質問に答えるものは何も見つかりませんでしたが、何か明らかなことを見逃していたらごめんなさい。これは私が試してきたコードです:

    while(fgets(line, sizeof(line), fp))
    {
        scanf(line, "%d\t%s", &key, value);
        insert(key, value, newdict);
    }
4

4 に答える 4

2

strtok誰かがそれについて言及したので、簡単にやってみましょう。ファイルが呼び出されfile.txt、次の内容が含まれているとします。

10 aaa 
20 bbb 
30 ccc 

これを解析する方法は次のとおりです。

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

#define MAX_NUMBER_OF_LINES 10 // parse a maximum of 10 lines
#define MAX_LINE_SIZE 50       // parse a maximum of 50 chars per line

int main ()
{
    FILE* fh = fopen("file.txt", "r"); // open the file

    char temp[MAX_LINE_SIZE]; // some buffer storage for each line

    // storage for MAX_NUMBER_OF_LINES integers
    int  d_out[MAX_NUMBER_OF_LINES];

    // storage for MAX_NUMBER_OF_LINES strings each MAX_LINE_SIZE chars long
    char s_out[MAX_NUMBER_OF_LINES][MAX_LINE_SIZE];

    // i is a special variable that tells us if we're parsing a number or a string (0 for num, 1 for string)
    // di and si are indices to keep track of which line we're currently handling
    int i = 0, di = 0, si = 0;

    while (fgets(temp, MAX_LINE_SIZE, fh) && di < MAX_NUMBER_OF_LINES) // read the input file and parse the string
    {
        temp[strlen(temp) -1] = '\0'; // get rid of the newline in the buffer

        char* c = strtok(temp, " ");  // set the delimiters

        while(c != NULL)
        {
            if (i == 0) // i equal to 0 means we're parsing a number
            {
                i = 1; // next we'll parse a string, let's indicate that
                sscanf(c, "%d", &d_out[di++]);
            }
            else // i must be 1 parsing a string
            {
                i = 0; // next we'll parse a number
                sprintf(s_out[si++], "%s", c);
            }
            c = strtok(NULL, " ");
        }
        printf("%d %s\n", d_out[di -1], s_out[si - 1]); // print what we've extracted
    }

    fclose(fh);

    return 0;
}

これにより、ファイルからコンテンツが抽出され、それぞれの配列に格納されます。次に、それらを出力して元のコンテンツを取得します。

$ ./a.out 
10 aaa 
20 bbb 
30 ccc 
于 2013-09-03T08:51:39.607 に答える
0

ここでの問題は、ファイルから2 回読み取っていることにあるようです。最初に でfgets、次に でscanf。を使用してもおそらくコンパイラからエラーは発生しませんが、フォーマット文字列に使用し、他の引数がフォーマットと一致しないため、scanf警告が表示されるはずです。また、正常にスキャンされたアイテムの数が返されるため、lineからの戻り値を確認した場合も明らかです。scanfあなたの呼び出しはおそらくゼロを返します(またはファイルの終わりに達した場合はマイナス1)。

sscanfで読み取った行を解析するには、代わりに を使用する必要がありますfgets

さまざまなバリアントについては、たとえばこのリファレンスを参照してください。scanf

于 2013-09-03T08:37:01.193 に答える
0

使用する:

fgets (name, 100, stdin);

100バッファの最大長です。必要に応じて調整する必要があります。

使用する:

scanf ("%[^\n]%*c", name);

[]scanset 文字です。入力が改行( )[^\n]ではない'\n'間、入力を取ることを示します。次に%*c、入力バッファーから改行文字を読み取り (読み取られない)、 は*、入力で読み取られたこの読み取りが破棄されることを示し (割り当ての抑制)、必要がないため、バッファー内のこの改行は作成されません。あなたが取るかもしれない次の入力のための問題。

于 2013-09-03T08:28:30.887 に答える