2

これは古典的な問題ですが、簡単な解決策を見つけることができません。

私は次のような入力ファイルを持っています:

1 3 9 13 23 25 34 36 38 40 52 54 59 
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114 
2 4 9 15 23 27 34 36 63 67 76 85 86 90 93 99 108 115 
1 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113 
2 3 9 16 24 28 
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76 

スペースで区切られた整数の数が異なる行。

それらを配列で解析し、各行をマーカーで区切りたいと思います-1

難しいのは、整数と行の戻り値を処理する必要があることです。

ここに私の既存のコードは、scanfループでループします(scanfは特定の位置で開始できないため)。

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv) {

  if (argc != 4) {
    fprintf(stderr, "Usage: %s <data file> <nb transactions> <nb items>\n", argv[0]);
    return 1;
  }
  FILE * file;
  file = fopen (argv[1],"r");
  if (file==NULL) {
    fprintf(stderr, "Error: can not open %s\n", argv[1]);
    fclose(file);
    return 1;
  }
  int nb_trans = atoi(argv[2]);
  int nb_items = atoi(argv[3]);
  int *bdd = malloc(sizeof(int) * (nb_trans + nb_items));
  char line[1024];
  int i = 0;

  while ( fgets(line, 1024, file) ) {
    int item;
    while ( sscanf (line, "%d ", &item )){
      printf("%s %d %d\n", line, i, item);
      bdd[i++] = item;
    }
    bdd[i++] = -1;
  }

  for ( i = 0; i < nb_trans + nb_items; i++ ) {
    printf("%d ", bdd[i]);
  }
  printf("\n");
}
4

4 に答える 4

6

あなたには多くの選択肢がありますが、これは一般的に私がそれを攻撃する方法です:

fgets()を使用して、入力ファイルをテキストファイル(つまり、文字列の束)として読み込みます。これは、改行またはEOFがヒットするまで読み取られます。読み取られた各行のスペースをスキャンし、スペースの前に部分文字列を返す文字列トークナイザー関数を使用します。これで、整数の文字列表現ができました。必要に応じて、それを実際のintに解析するか、部分文字列自体を配列に格納します。intに切り替える場合、大きくなりすぎた場合のオーバーフローに注意する必要があります。

于 2010-06-10T15:14:31.440 に答える
1

入力を文字列として読み込み、改行を検索し、改行がある場所に-1で新しい文字列を作成し、すべての改行が-1に置き換えられるまでこれを繰り返します。これを行っている間、スペースの数を数えることもできるので、配列を宣言する大きさがわかります。(ただし、改行を置き換えた後で行う必要があります。)

次に、アレイを作成します。

次に、sscanfなどを使用して、ループ内の文字列から整数を解釈し、すべての整数(-1を含む)が解釈されるまで、それらを適切な場所の配列に追加します。

編集:...そして、それはあなたがすでに行っていることにかなり近いようです。私が答えを入力している間にあなたが質問に追加したコードを見ていきます。

于 2010-06-10T15:14:17.233 に答える
0

OK私は解決策を見つけました、ノイズでごめんなさい、私はもっと検索する必要があります...

stdin(C)から不明な数の整数を読み取る

私のscanfループの代わりに、これを使用してください:

  while ( fgets(line, 1024, file) ) {
    int item;
    for (p = line; ; p = e) {
        item = strtol(p, &e, 10);
        if (p == e)
            break;
        bdd[i++] = item;
    }
    bdd[i++] = -1;
  }
于 2010-06-10T15:16:42.710 に答える
0

これを行う方法を示す完全なCプログラムを次に示します。基本的に、で一度に1行ずつ読み取りfgets、次にsscanfその行の各inetegrを処理するために使用します。

初歩的なエラーチェックがありますが、悪いデータ(数値以外の行)でテストされていませんが、良いスタートになるはずです。printfステートメントを、各番号を配列に追加するコードに置き換えるだけです。

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

int main (void) {
    char line[1000];
    FILE *fIn;
    char *str;
    int val, num;

    // Open input file and process line by line.

    if ((fIn = fopen ("infile.txt", "r")) == NULL) {
        fprintf (stderr, "Cannot open infile.txt, errno = %d\n", errno);
        return 1;
    }

    while (fgets (line, sizeof (line), fIn) != NULL) {
        // Check if line was too long.

        if (line[strlen (line) - 1] != '\n') {
            fprintf (stderr, "Line too long: [%s...]\n", line);
            fclose (fIn);
            return 1;
        }

        // Oyput the line and start processing it.

        printf ("%s   ", line);
        str = line;

        // Skip white space and scan first inetegr.

        while (*str == ' ') str++;

        num = sscanf (str, "%d", &val);

        // Process the integer if it was there.

        while ((num != 0) && (num != EOF)) {
            // Print it out then skip to next.

            printf ("[%d] ", val);
            while ((*str != ' ') && (*str != '\0')) str++;
            while (*str == ' ') str++;
            num = sscanf (str, "%d", &val);
        }

        // -1 for line separator.

        printf ("[%d]\n", -1);
    }

    // Close input file and exit.

    fclose (fIn);

    return 0;
}

そして、これが機能していることを示す出力です。

1 3 9 13 23 25 34 36 38 40 52 54 59
   [1] [3] [9] [13] [23] [25] [34] [36] [38] [40] [52] [54] [59] [-1]
2 3 9 14 23 26 34 36 39 40 52 55 59 63 67 76 85 86 90 93 99 108 114
   [2] [3] [9] [14] [23] [26] [34] [36] [39] [40] [52] [55] [59] [63] [67] [76] [85] [86] [90] [93] [99] [108] [114] [-1]
2 4 9 15 23 27 34 36 63 67 76 85 86 90 93 99 108 115
   [2] [4] [9] [15] [23] [27] [34] [36] [63] [67] [76] [85] [86] [90] [93] [99] [108] [115] [-1]
1 25 34 36 38 41 52 54 59 63 67 76 85 86 90 93 98 107 113
   [1] [25] [34] [36] [38] [41] [52] [54] [59] [63] [67] [76] [85] [86] [90] [93] [98] [107] [113] [-1]
2 3 9 16 24 28
   [2] [3] [9] [16] [24] [28] [-1]
2 3 10 14 23 26 34 36 39 41 52 55 59 63 67 76
   [2] [3] [10] [14] [23] [26] [34] [36] [39] [41] [52] [55] [59] [63] [67] [76] [-1]
于 2010-06-10T15:46:39.243 に答える