[OK]をコメントから続け、コメントに記載されているように、データ処理の問題で最初に行う必要があるのは、すべてのデータをフォームに読み込んで、必要です。ここでは、すべてのユニット(この場合は車)を構成するさまざまな種類のデータがあります。あなたがユニットとして扱わなければならないデータの種類が異なるときはいつも、structを考えるべきです。
typedef struct { /* struct for cars */
int id;
char color[MAXN];
char manf[MAXN];
int year;
} car;
あなたは今、配列またはstruct car
にあなたのデータファイルの各行を読んで、あなたのコードの残りの部分で容易に利用可能なすべてのデータを持つことができます:ここでは構造体car
は理にかなっています。
あなたはラインデータのを持って今まで、あなたが例えば、行指向入力を考えるべきですfgets
またはgetline
。ここではscanf
ファミリを使用することができますが、一度に1行ずつ読み込み、読み込まれた各行のデータを解析する方がよいでしょう。また、データを一時変数に解析する方が良い場合もあります。次に、すべてを考慮して検証したら、一時変数を構造体にコピーしてインデックスを増やします。
/* constants for max name, chars & structs */
enum { MAXN = 16, MAXC = 64, MAXS = 128 };
...
car cars[MAXS] = {{ .id = 0 }}; /* array of struct car */
char buf[MAXC] = "";
size_t i, j, idx = 0, nc = 0, nm = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
...
while (idx < MAXS && fgets (buf, MAXC, fp)) { /* read each line */
int tid, tyr; /* temp variables */
char tcol[MAXC] = "", tman[MAXC] = "";
/* separate into temp variables, validate, copy to struct */
if (sscanf (buf, " %d %s %s %d%*c", &tid, tcol, tman, &tyr) == 4) {
cars[idx].id = tid;
snprintf (cars[idx].color, MAXN, "%s", tcol);
snprintf (cars[idx].manf, MAXN, "%s", tman);
cars[idx++].year = tyr;
}
}
は今、あなたは構造体のあなたの配列内のすべてのデータを持っており、残された唯一の事は、あなたのデータの中に持っている独特の色やメーカーを決定することです。たとえば、次の操作を行うことができます。データを別の配列に再コピーする必要はありません。ポインタの配列を使用して、構造体配列内の一意の値を指すだけです。
char *colors[MAXN] = {NULL}, *manfs[MAXN] = {NULL}; /* pointer arrays */
...
for (i = 0; i < idx; i++) { /* find unique colors */
if (!nc) { colors[nc++] = cars[i].color; continue; }
for (j = 0; j < nc; j++)
if (!strcmp(colors[j], cars[i].color)) goto cdup;
colors[nc++] = cars[i].color;
cdup:;
}
(nc
はユニークな色の数のために、ちょうどあなたのカウンターです)
をあなたのメーカーのために同じことを行うことができます:あなたは、次のようにそれを行うことができます。
#include <stdio.h>
#include <string.h>
/* constants for max name, chars & structs */
enum { MAXN = 16, MAXC = 64, MAXS = 128 };
typedef struct { /* struct for cars */
int id;
char color[MAXN];
char manf[MAXN];
int year;
} car;
int main (int argc, char **argv) {
car cars[MAXS] = {{ .id = 0 }}; /* array of struct car */
char *colors[MAXN] = {NULL}, *manfs[MAXN] = {NULL}; /* pointer arrays */
char buf[MAXC] = "";
size_t i, j, idx = 0, nc = 0, nm = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (idx < MAXS && fgets (buf, MAXC, fp)) { /* read each line */
int tid, tyr; /* temp variables */
char tcol[MAXC] = "", tman[MAXC] = "";
/* separate into temp variables, validate, copy to struct */
if (sscanf (buf, " %d %s %s %d%*c", &tid, tcol, tman, &tyr) == 4) {
cars[idx].id = tid;
snprintf (cars[idx].color, MAXN, "%s", tcol);
snprintf (cars[idx].manf, MAXN, "%s", tman);
cars[idx++].year = tyr;
}
}
if (fp != stdin) fclose (fp);
for (i = 0; i < idx; i++) /* output all data */
printf ("%4d %-6s %-10s %d\n", cars[i].id, cars[i].color,
cars[i].manf, cars[i].year);
putchar ('\n');
for (i = 0; i < idx; i++) { /* find unique colors */
if (!nc) { colors[nc++] = cars[i].color; continue; }
for (j = 0; j < nc; j++)
if (!strcmp(colors[j], cars[i].color)) goto cdup;
colors[nc++] = cars[i].color;
cdup:;
}
for (i = 0; i < idx; i++) { /* find unique manufacturers */
if (!nm) { manfs[nm++] = cars[i].manf; continue; }
for (j = 0; j < nm; j++)
if (*manfs[j] == *cars[i].manf) goto mdup;
manfs[nm++] = cars[i].manf;
mdup:;
}
/* output unique colors & unique manufacturers */
for (i = 0; i < nc; i++) printf ("%s\n", colors[i]);
putchar ('\n');
for (i = 0; i < nm; i++) printf ("%s\n", manfs[i]);
putchar ('\n');
return 0;
}
注:なかったあなたの場合
あなたはこのような何かを行うことができ、一緒にすべてのピースを置く(そもそもユニーク拳の手紙を持っており、あなたのメーカーのすべてのに注意) すべてメーカー固有の最初の文字はありません。最初の文字を比較するのではなく、色のようにテストするときは、完全なstrcmp
が必要です。
例入力
$ cat dat/cars.txt
4132 RED ALFA-ROMEO 2005
5230 BLUE FIAT 2004
4321 WHITE NISSAN 2000
5233 BLUE BMW 2001
7300 YELLOW CITROEN 1999
1232 BLUE PEUGEOT 1990
9102 RED VW 1995
1998 YELLOW ALFA-ROMEO 2004
5333 WHITE VW 1999
6434 BLUE NISSAN 2000
8823 BLACK MERCEDES 2003
4556 BLACK SEAT 1997
1554 RED MERCEDES 2001
6903 YELLOW NISSAN 2000
7093 BLACK FIAT 1978
1023 WHITE VW 1998
3422 BLUE SEAT 2005
3555 RED BMW 2004
6770 YELLOW SEAT 2002
使用例/出力
$ ./bin/cars <dat/cars.txt
4132 RED ALFA-ROMEO 2005
5230 BLUE FIAT 2004
4321 WHITE NISSAN 2000
5233 BLUE BMW 2001
7300 YELLOW CITROEN 1999
1232 BLUE PEUGEOT 1990
9102 RED VW 1995
1998 YELLOW ALFA-ROMEO 2004
5333 WHITE VW 1999
6434 BLUE NISSAN 2000
8823 BLACK MERCEDES 2003
4556 BLACK SEAT 1997
1554 RED MERCEDES 2001
6903 YELLOW NISSAN 2000
7093 BLACK FIAT 1978
1023 WHITE VW 1998
3422 BLUE SEAT 2005
3555 RED BMW 2004
6770 YELLOW SEAT 2002
RED
BLUE
WHITE
YELLOW
BLACK
ALFA-ROMEO
FIAT
NISSAN
BMW
CITROEN
PEUGEOT
VW
MERCEDES
SEAT
注:これはちょうどあなたが始めることです。残りの課題については依然としてデータを使用する必要がありますが、ここでは管理しやすくするためのアプローチがあります。ご質問がある場合はお知らせください。
簡易版は、印刷非重複色&私はあなたが持った難しさと、あなたが最終的にどのように使用するかわからないから茎必要どのくらいの詳細を知ることで、基本的な問題について考え
メーカーあなたのデータ。最初は、データファイル内の固有の色やメーカーを特定する方法が必要でした。最初のコードは、すべてのデータを独自の色とメーカのコレクションに分けていますが、必要なものを実装するために残しておきます。しかし、ユニークなメーカーが独自の色で車のリストを出力するだけであれば、構造体の配列を格納する必要はありません。
#include <stdio.h>
#include <string.h>
/* constants for max name, chars & structs */
enum { MAXN = 16, MAXC = 64 };
int main (int argc, char **argv) {
char colors[MAXN][MAXN] = {{0}}, manfs[MAXN][MAXN] = {{0}};
char buf[MAXC] = "";
size_t i, nc = 0, nm = 0;
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
int tid, tyr; /* temp variables */
char tcol[MAXC] = "", tman[MAXC] = "";
/* separate into temp variables, validate, copy to struct */
if (sscanf (buf, " %d %s %s %d%*c", &tid, tcol, tman, &tyr) == 4) {
if (!nc) /* 1st color - add it */
strcpy (colors[nc++], tcol);
else {
for (i = 0; i < nc; i++) /* compare against stored colors */
if (!strcmp (colors[i], tcol)) /* duplicate */
goto dupe; /* skip it */
strcpy (colors[nc++], tcol); /* add it */
}
if (!nm) /* do the same for manufacturers */
strcpy (manfs[nm++], tman);
else {
for (i = 0; i < nm; i++)
if (!strcmp (manfs[i], tman))
goto dupe;
strcpy (manfs[nm++], tman);
} /* if not a duplicate, print the vehicle */
printf ("%4d %-6s %-10s %d\n", tid, tcol, tman, tyr);
dupe:;
}
}
if (fp != stdin) fclose (fp);
return 0;
}
使用例/出力
$ ./bin/cars2 <dat/cars.txt
4132 RED ALFA-ROMEO 2005
5230 BLUE FIAT 2004
4321 WHITE NISSAN 2000
7300 YELLOW CITROEN 1999
8823 BLACK MERCEDES 2003
行われているものに目を通す:それは次のように簡略化して行うことができます。各行が読み取られ、値が分離されます。色または製造者の配列が空の場合、最初の色/製造者が追加されます。他のすべてのものについては、現在の色または製造者を以前のものと比較し、重複している場合は、その自動車の印刷をスキップする。さらに質問がある場合はお知らせください。
すべての値を構造体の配列に読み込み、構造体の配列内でそれぞれの固有の存在を示す色と製造元用の個別のポインタ配列を作成し、それらを出力します。 –
私はあなたが言っていることを理解していますが、ポインタ配列を作成する方法はわかりません...あなたが少しでも助けてくれるように親切であれば、私は感謝の気持ちになります。@David C. Rankin –
私はあなたにちょっと待ってもらいます。 –