「一気に最後まで読んだ」本、教えて下さい!

こんにちは、最近C言語でファイルを扱うプログラムについて学習しているものです。

2つのファイルを用いて合計値と平均値を求めるプログラムについての質問です。
具体的には、以下に示すようなものをC言語で作成しようとしています。

例えば、以下の2つのデータファイルがあるとします。
/*(1)価格表.txt*/
わかめ 195
醤油 300
電球 298
… …
… …
納豆 88
(約2000種類)

/*(2)買い物リスト.txt*/
納豆
えび
醤油

(約500種類)

この2つのファイルを用いて、(2)買い物リスト.txtに書いてあるすべての商品価格の合計値と、価格の平均値を「価格表.txt」を用いて求めるプログラムをC言語で作成してみたいと考えています。

「価格表.txt」の商品数が少なければ、switch文を用いてプログラムを作成することができると思うのですが、「価格表.txt」の商品数が2000種類くらいある場合だと、どのようにプログラムを作成すればよいかわかりません。

よろしければご教授ください。OSはUbuntuを使っております。
よろしくお願いいたします。

A 回答 (3件)

まず、価格表と買い物リストの2つのファイルを商品名でソートします。


ソートは自分で作ってもよいのですが、linuxなのでsortコマンドを起動します。fork()を使ってプリミティブに起動してもよいのですが、初心者であればsystem()がよいと思います。

system("sort -b -o 出力ファイル 価格.txt");
出力のファイル名は適当に作ってください。

ソートした二つのファイルをオープンして順次scanf()で読み込みながら商品が一致する場合に価格を読み込んで一致した場合に金額の処理を行えばよいのです。

fscanf(買い物fp,"%s",買い物アイテム);
do{
fscanf(価格fp,"%s %d",価格アイテム,金額);
}while(価格アイテム!=買い物アイテム);
金額の処理

最後にソートしたファイルをクローズした後に消しておきます。
    • good
    • 0
この回答へのお礼

みなさんいろいろとアドバイスありがとうございます。
なんとか自分なりにプログラムを完成することができました。

お礼日時:2010/11/26 14:12

UNIX系ですので、リダイレクトを使うことを前提にしてあります。

プログラムは品目倍角3文字の比較として、たかだか12Kバイトの比較ですので先に「価格表.txt」を読み込んでおいたうえで strcmp() をそのまま使っています。また、「買い物リスト.txt」のサイズは無制限です。
なお、全角ではなく、半角で書いてありますので悪しからず。


--- 使い方 ---
./a.out<kaimono.txt
または、記録したいなら
./a.out<kaimono.txt>reg1.txt



----- kakaku.txt -----
わかめ 195
醤油 300
電球 298
納豆 88
えび 234


----- kaimono.txt -----
16/Oct/2010 No.1
納豆 3
えび 5
醤油 1


/* Gcc on Mac OSX */
#include <stdio.h>
#include <string.h>//strcmp()
#include <stdlib.h>//exit()
#define ROOT_FILE "kakaku.txt"
#define DAT_SIZE 2000
#define STR_SIZE 32

struct set1 {
char hinmoku[STR_SIZE];
int kakaku;
int kosu;
};

char *format(int x, char buffer[]);

int main(void)
{
struct set1 main_hyo[DAT_SIZE], *ptr, *base;
struct set1 kaimono_hyo;
FILE *fp;
int n, i, j, sum;
char print_date[64], code[32];
char printout_kakaku[12], printout_goukei[12];

if((fp=fopen(ROOT_FILE,"r"))==NULL){
fprintf(stderr, "Can't open %s file.\n", ROOT_FILE);
exit(1);
}
n=0;
ptr=&main_hyo[n];
while(fscanf(fp, "%s %d %d", ptr->hinmoku, &ptr->kakaku, &ptr->kosu) != EOF)
ptr=&main_hyo[++n];
fclose(fp);
fprintf(stderr, "Ready to register(%d).\n", n);

fscanf(stdin, "%s %s", print_date, code);
printf("Receipt date: %s -- %s\n", print_date, code);
sum=0;
while(fscanf(stdin, "%s %d", kaimono_hyo.hinmoku, &kaimono_hyo.kosu) != EOF){
for(j=0; j<n; j++) {
if(strcmp(main_hyo[j].hinmoku,kaimono_hyo.hinmoku)==0) {
kaimono_hyo.kakaku=main_hyo[j].kakaku * kaimono_hyo.kosu;
sum+=kaimono_hyo.kakaku;
printf("hinmoku:%s \tkakaku:%s \tkosu:%d \tkei:%s\n",
kaimono_hyo.hinmoku, format(main_hyo[j].kakaku, printout_kakaku),
kaimono_hyo.kosu, format(kaimono_hyo.kakaku, printout_goukei));
break;
}
}
}
printf("\ttotal= %syen\n", format(sum, printout_goukei));

return 0;
}


char *format(int x, char buffer[])
{
if(x<1000) sprintf(buffer,"%d", x);
else sprintf(buffer,"%d,%d", x/1000, x % 1000);
return buffer;
}
    • good
    • 0

コーディングじゃなく考え方を書きます。



1.買い物リストのファイルをオープンする。(EOFまでループする事。)
2.買い物リストのデータを読み込む。
3.価格表リストオープンする。1行読み込む。
4.読み込んだ価格表の賞品リストと買い物リストを比較する。
5.一致すれば、一致件数をカウントし、合計金額の足しこみもする。ブレーク。
6.一致しなければ「3.」にループ。
7.価格表ファイルクローズ。
8.「2.」へループする。
9.買い物ファイルクローズ。
10.金額合計と金額合計を件数で割れば平均価格が求められる。

という寸法です。まあ、買い物リストと価格表リストが一致しない場合も考えなければなりませんが、課題であればそこまでの意地悪はないと思います。
速度を優先するなら、配列変数に全て読み込んでメモリ上で処理する方法も考えられます。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!