0

構造が単純なファイルがあります:
{number}\#
{some_text_with_lines}
\#

問題は、プログラムにこのファイルのすべてのエントリを読み取らせたいことです。これは、この構造が複数回出現することを意味します。

それで、私の最初の考えは、ある種のstruct my_struct abc[MAX];. MAXプリプロセッサ定義です。

fscanf{number} を配列の番号として格納し、{some_text_with_lines} を構造体配列内の文字列として格納する必要がありました。したがって、各配列には独自の文字列があります。

アイデアは、 fscanf が次の形式を読み取り、%d#\r\n%s\r\n#r\n最初の整数%dを配列の番号として使用することです。&abc[%d]のようなもの。
構文が間違っていることはわかっていますが、この数値 %d を読み取って配列の数値として使用する方法がわかりません。また、%s に問題があります。\0? がありません。

それで、私はいくつかの助けが必要です、事前に感謝します.

4

2 に答える 2

1

This code works. It will accept an arbitrary list of paragraphs in the file, and the set of lines in each paragraph is allowed to be of arbitrary length, too.

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

struct data
{
    int     number;
    char  **lines;
    int     num_lines;
    int     max_lines;
};

int main(void)
{
    struct data *info = 0;
    int   num_entries = 0;
    int   max_entries = 0;
    char line[4096];

    while (fgets(line, sizeof(line), stdin) != 0)
    {
        int number;
        char hash;
        if (sscanf(line, "%d%c", &number, &hash) != 2 || hash != '#')
        {
            fprintf(stderr, "Format error (number# expected): %s", line);
            return(1);
        }

        if (max_entries >= num_entries)
        {
            int new_size = (max_entries + 2) * 2;
            struct data *new_info = realloc(info, new_size * sizeof(*new_info));
            if (new_info == 0)
            {
                fprintf(stderr, "Out of memory\n");
                return(1);
            }
            info = new_info;
            max_entries = new_size;
        }

        struct data *curr = &info[num_entries];
        curr->number    = number;
        curr->lines     = 0;
        curr->max_lines = 0;
        curr->num_lines = 0;

        while (fgets(line, sizeof(line), stdin) != 0)
        {
            char *p = strchr(line, '\n');
            if (p == 0)
            {
                fprintf(stderr, "Format error: no newline? (%s)\n", line);
                return(1);
            }
            *p = '\0';
            if (strcmp(line, "#") == 0)
                break;
            if (curr->max_lines >= curr->num_lines)
            {
                int new_size = (curr->max_lines + 2) * 2;
                char **new_lines = realloc(curr->lines, new_size * sizeof(*new_lines));
                if (new_lines == 0)
                {
                    fprintf(stderr, "Out of memory\n");
                    return(1);
                }
                curr->lines = new_lines;
                curr->max_lines = new_size;
            }
            curr->lines[curr->num_lines] = strdup(line);
            if (curr->lines[curr->num_lines] == 0)
            {
                fprintf(stderr, "Out of memory\n");
                return(1);
            }
            curr->num_lines++;
        }

        num_entries++;
    }

    for (int i = 0; i < num_entries; i++)
    {
        printf("%d#\n", info[i].number);
        for (int j = 0; j < info[i].num_lines; j++)
            printf("  %d: %s\n", j, info[i].lines[j]);
    }

    return(0);
}

Given the input file:

13#
Unlucky for some
#
20121221#
The end of the world?
No, it seems that we survived yet another doomsday!
#
18#
More lines,
And more lines still.
The verse is weird.
The terse is worse.
#
19#
As for one,
Then another,
It is still too short
For comfort,
But the fifth line shall trigger
an extra reallocation.
#
20#
All for one,
And one for all!
The Three Musketeers?
Nay, D'Artagnan, the Four Musketeers.
Yahoo! Bing?  Google?
#

It gives the output:

13#
  0: Unlucky for some
20121221#
  0: The end of the world?
  1: No, it seems that we survived yet another doomsday!
18#
  0: More lines,
  1: And more lines still.
  2: The verse is weird.
  3: The terse is worse.
19#
  0: As for one,
  1: Then another,
  2: It is still too short
  3: For comfort,
  4: But the fifth line shall trigger
  5: an extra reallocation.
20#
  0: All for one,
  1: And one for all!
  2: The Three Musketeers?
  3: Nay, D'Artagnan, the Four Musketeers.
  4: Yahoo! Bing?  Google?

There is undoubtedly room for improvement in the code, but it seems to work (though it does not release the memory before it exits). It assumes that there is a function char *strdup(const char *str) that allocates enough space for a copy of the string it is given.

于 2012-12-24T02:50:47.767 に答える
1

次のようにします。

int index;
char array[1024][1024];               // big array :)

while(fscanf(file, "%d#\r\n", &index) == 1) {
  fscanf(file, "%s\r\n", array[index]);
  int c; 
  while ((c = fgetc(file)) != EOF && c != '\r') { }
  fgetc(file);                          // read '\n'
}
于 2012-12-23T22:30:32.723 に答える