2016-05-29 16 views
-4

こんにちは、こんにちは、これは重複していますが、私は絶望的な点であり、.txtファイルの一部を印刷する

私は学校のプロジェクトのためにCでプログラムを書いていますが、私はほとんど終わっていますが、私は立ち往生しています。 私はこのイメージに示すtxtファイルがあります:私はこの時点でそれを行うに必要なもの cars.txt

が記載されているカラープリントであるが、すべて異なる色は一度だけ印刷されなければなりません。 自動車メーカーと同じですが、それは後であります。

私はアイデアを完全によ...すべてのヘルプは大幅にこのプログラムは、あなたが示したようにフォーマットされたファイルを読み込み、色の重複を削除...

+0

すべての値を構造体の配列に読み込み、構造体の配列内でそれぞれの固有の存在を示す色と製造元用の個別のポインタ配列を作成し、それらを出力します。 –

+0

私はあなたが言っていることを理解していますが、ポインタ配列を作成する方法はわかりません...あなたが少しでも助けてくれるように親切であれば、私は感謝の気持ちになります。@David C. Rankin –

+0

私はあなたにちょっと待ってもらいます。 –

答えて

0

[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 

行われているものに目を通す:それは次のように簡略化して行うことができます。各行が読み取られ、値が分離されます。色または製造者の配列が空の場合、最初の色/製造者が追加されます。他のすべてのものについては、現在の色または製造者を以前のものと比較し、重複している場合は、その自動車の印刷をスキップする。さらに質問がある場合はお知らせください。

+0

これに取り組んでいただきありがとうございますが、私はいくつかのレベルがこれに悩まされています。私は実際に構造体を使用していますが、その中のすべての配列はchar型です。 私はその後 –

+0

...魔女は、より組織的問題でファイルを印刷するだけで正常に動作しますが、色と文字列の配列を持ついくつかの理由が問題である)(はstrtokを使用してTXT内の各ラインの色の一部を取得しようとしました私はそれを試み、私が前に印刷されていないだけの色を印刷しようとしたforループ2を用いて使用する構造体の配列。 は、いくつかのデバッグのprintf Sを用い、私は文字列の配列が正しくそれはforループ内のランダムなシンボルを印刷し、いくつかの理由でいっぱいにしていることを見ることができました.... –

+0

ああ、申し訳ありませんが、あなたは構造体OKの配列を理解していますか?もしそうなら、あなたは苦労しています。ポインタの配列は、Xは、固有色/メーカーの数である充填された第1のX元素を有することになります。ポインタの配列[0]、色[1]、etc..'代わり 'P1、P2、P3、...'それぞれの場合において、それらは最初にポイントのポインタだけそのコレクション(例えば '色であります構造体の配列で色やメーカーの発生。あなたは色[4] '(BLACK)'のアドレスを見れば、あなたが表示され、それは、(最初​​の車 'と同じアドレス[10] .color'を指しBLACK) –

0

を理解されるであろう。他の重複を削除する方法は同じです。

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

void rmdup(char *resentence) { 
    char *temp1 = malloc(100); 
    char *temp = NULL; 

    *temp1 = 0; 
    temp = strtok(resentence, " "); 

    if (temp != NULL) {// && strstr(temp1, temp) == NULL) 
     strcpy(temp1, temp); 
     while ((temp = strtok(NULL, " ")) != NULL) { 
      if (strstr(temp1, temp) == NULL) { 
       strcat(temp1, " "); 
       strcat(temp1, temp); 
      } 
     } 
    } 
    strcpy(resentence, temp1); 
    puts(resentence); 
    free(temp1); 
} 

int main(int argc, char *argv[]) { 

    ssize_t read; 
    char *line = NULL; 
    size_t len = 0; 
    FILE *fp; 

    fp = fopen("file.txt", "r"); 

    char str[80]; 
    strcpy(str, ""); 
    while ((read = getline(&line, &len, fp)) != -1) { 
     char * date2 = strtok(line, " "); 
     date2 = strtok(NULL, " "); 
     strcat(str, strdup(date2)); 
     strcat(str, " "); 
    } 
    fclose(fp); 

    rmdup(str); 
    printf("after: %s", str); 

    exit(0); 
} 

あなたは出力が唯一のユニークな色で出力を参照

after: RED BLUE ORANGE BLACK 

:私はこのようなファイル

4132 RED ALFA ROMERO 2005 
1234 BLUE FIAT BLAHOGA 2032 
4132 RED ALFA ROMERO 2005 
1234 ORANGE FIAT BLAHOGA 2032 
4132 RED ALFA ROMERO 2005 
1234 BLACK FIAT BLAHOGA 2032 
1234 ORANGE FIAT BLAHOGA 2032 
1234 ORANGE FIAT BLAHOGA 2032 

プログラムをテストします。

関連する問題