掲示板利用宣言

 次のフォームをすべてチェックしてからご利用ください。

 私は

 題名と投稿者名は具体的に書きます。
 課題の丸投げはしません。
 ソースの添付は「HTML変換ツール」で字下げします。
 返信の引用は最小限にします。
 環境(OSとコンパイラ)や症状は具体的に詳しく書きます。
 返信の付いた投稿は削除しません。
 マルチポスト(多重投稿)はしません。

掲示板2

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.26648

ファイル内の統計をとる
投稿者---ビギナー(2006/04/19 14:28:49)


C言語をつい最近はじめたばかりで課題、問題をやっているのですがまったくわかりません。よろしければヒントや考え方を教えてください。
問題は
a 1
b 3
c 4
d 1
a 3
...
というようなコードと数のならんだファイルを読み込みコードごとの数の総和を表示するというものです。
OSはXPでcygwinを使用してます。


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:ファイル内の統計をとる 26649 REE 2006/04/19 14:32:49
<子記事> Re:ファイル内の統計をとる 26653 KING・王 2006/04/19 20:38:01


No.26649

Re:ファイル内の統計をとる
投稿者---REE(2006/04/19 14:32:49)


>C言語をつい最近はじめたばかりで課題、問題をやっているのですがまったくわかりません。よろしければヒントや考え方を教えてください。

まず、プログラムを使わずに手作業でやってみる。
次に、その手作業での手順をプログラムで記述する。



この投稿にコメントする

削除パスワード

No.26653

Re:ファイル内の統計をとる
投稿者---KING・王(2006/04/19 20:38:01)


REEさんから指摘されているように、
>まず、プログラムを使わずに手作業でやってみる。
>次に、その手作業での手順をプログラムで記述する。
が重要です。

とりあえず、コードの数と種類が決まっていると仮定して、
日本語で手順を書くと、だいたい次のようになると思います。

(1)コードごとの総和用の変数を用意し、初期化しておく。
(2)1行読み込む。
(3)読み込んだ行からコードと数を取得する。
(4)取得したコードを判別し、そのコードの総和用の変数に、取得した値を追加する。
(5)上記(2)〜(4)をファイルにデータがなくなるまで繰り返す。
(6)各コードごとの総和の値を表示する。




この投稿にコメントする

削除パスワード

No.26655

Re:ファイル内の統計をとる
投稿者---ビギナー(2006/04/20 14:31:27)


REEさん、KING・王さん ありがとうございます。

>(3)読み込んだ行からコードと数を取得する。
>(4)取得したコードを判別し、そのコードの総和用の変数に、取得した値を追加する。

で、(3)(4)をどのようにしたらよいのかわかりません。どのように得てきたものを追加したらよいですか?



この投稿にコメントする

削除パスワード

No.26656

Re:ファイル内の統計をとる
投稿者---shu(2006/04/20 15:31:19)


>で、(3)(4)をどのようにしたらよいのかわかりません。どのように得てきたものを追加したらよいですか?

KING・王さんが書かれたように、
(3)について、
(3.1), (3.2), (3.3) ・・・・・・
(4)について、
(4.1), (4.2), (4.3) ・・・・・・
というように、もっと細かく分けてみる。


この投稿にコメントする

削除パスワード

No.26657

Re:ファイル内の統計をとる
投稿者---とろり(2006/04/20 16:52:18)


こんにちは。

>>(3)読み込んだ行からコードと数を取得する。
>>(4)取得したコードを判別し、そのコードの総和用の変数に、取得した値を追加する。
>
>で、(3)(4)をどのようにしたらよいのかわかりません。どのように得てきたものを追加したらよいですか?

できたところまでソースを載せると、有効なレスが付きやすくなります。


さて、今回の場合、連想配列を使用すると非常に簡単にできます。
しかし残念ながらCには連想配列はないので、コードを格納する変数と和を格納する変数を対応させる等して実現します。
こういった場合、構造体を使用すると簡単にできます。
struct DATA {
 char code;
 int num;
};
struct DATA data[32];
こんな感じです。

また、単純に配列を使って、
char code[32];
int num[32];
code[0]とnum[0]、code[1]とnum[1]、・・・
のように対応付けることもできます。

なお、コードが文字か文字列かで、コーディングも変ってくるので注意が必要です。


この投稿にコメントする

削除パスワード

No.26659

Re:ファイル内の統計をとる
投稿者---ビギナー(2006/04/20 18:27:43)


アドバイスありがとうございます。
>できたところまでソースを載せると、有効なレスが付きやすくなります。
ということなのでまったくおかしいと思いますが自分でできないなりにも考えてみたので載せてみたいと思います

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

struct DATA {
char code;
int num;
};

struct DATA data[32];

int main()
{
int a=0, b=0, c=0, d=0;
char i;
FILE *fp;
char filename[20], ss[256];
struct DATA *dp;

dp=data;

printf("input filename:");
gets(filename);

fp = fopen(filename, "r");

if(strcmp(ss, "a") == 0){
strcpy(dp, code, "a");
fseek(fp, 3L, SEEK_CUR);
fscanf(fp, "%d", dp->num);
printf("%c:%d",data[0].code,data[0].num);
}

fclose(fp);

return 0;
}

ですが動作してくれません。
どこがおかしいのか、どのようにしたら良いか助言をお願いします。



この投稿にコメントする

削除パスワード

No.26660

Re:ファイル内の統計をとる
投稿者---nop(2006/04/20 19:31:23)


以下、ダメな点

> if(strcmp(ss, "a") == 0){

・未初期化の変数「ss」と比較している。
・ファイルから読み込みもせずに、いきなり比較している。
・ループすらしていない。


まだまだ突っ込み所はありますが、
とりあえず、この辺りを見直してみましょう。


この投稿にコメントする

削除パスワード

No.26661

Re:ファイル内の統計をとる
投稿者---とろり(2006/04/21 09:27:43)


こんにちは。

>>できたところまでソースを載せると、有効なレスが付きやすくなります。
>ということなのでまったくおかしいと思いますが自分でできないなりにも考えてみたので載せてみたいと思います
>
>ですが動作してくれません。

提示されたソースはコンパイラ通りませんでした。(WinXP/VC++6.0)
#(プログラミングの世界で)一般に「動作しない」と言うと
「コンパイラは通ったが、期待通りの動作をしてくれない(実行結果が期待値と違う)」という意味に取られます。

>どこがおかしいのか、どのようにしたら良いか助言をお願いします。

提示プログラムについてはnopさんが既に指摘している通りなので、置いておくとして、ちょっとしたヒント(?)だけ。

ファイル入出力はこのホームページの17章に詳しく記載されています。そこに解答が書いてあるのですが、
読込みの場合に良く使われるコーディングは
fp = fopen(filename, "r");
while (NULL != fgets(buf, sizeof(buf), fp)) {
 ・・・・・
}
fclose(fp);
で1行づつ、ファイルの最後まで読込むことができます。

fscanf()を使うのなら、例えば
while (EOF != fscanf(fp, "%s%d", code, &no)) {
 ・・・・・
}
です。デリミタが空白である場合はfscanf()を使用すると楽です。

兎にも角にも17章を読んで、理解してみて下さい。

今、codeは"文字列"をあつかおうとしていますね?
なので、構造体は
struct DATA {
 char code[16];
 int num;
};
などとすべきです。
> なお、コードが文字か文字列かで、コーディングも変ってくるので注意が必要です。
さては、読み飛ばしましたね。。。

ファイルから1レコード読込めたら、あとは1行ごとにstrcmp(),strcpy()等を使用して、
構造体の追加/参照/更新を繰り返していけば良いです。
なお、その場合、"現在どこまで構造体にデータが設定されているか"を常に把握しておく必要があります。
(構造体データ保存数を別変数に確保しておく、構造体を"終端"で初期化しておくなど)


以上


この投稿にコメントする

削除パスワード

No.26670

Re:ファイル内の統計をとる
投稿者---ビギナー(2006/04/21 15:07:57)


いろいろとありがとうございます。
とりあえず一番最初に自分で示したファイルの中身がわかっている前提でのプログラムは一応何とかできました。


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

struct DATA {
char code[16];
int num;
};

struct DATA data[32];

int main()
{
int i;
FILE *fp;
char filename[20], ss[256];

data[0].num = 0;

printf("input filename:");
gets(filename);

fp = fopen(filename, "r");

while(fscanf(fp, "%s", &ss) != EOF){
if(strcmp(ss, "a") == 0){
strcpy(data[0].code, "a");

fscanf(fp, "%d", &i);

data[0].num+=i;
}
else if(strcmp(ss, "b") == 0){
strcpy(data[1].code, "b");

fscanf(fp, "%d", &i);

data[1].num+=i;
}
else if(strcmp(ss, "c") == 0){
strcpy(data[2].code, "c");

fscanf(fp, "%d", &i);

data[2].num+=i;
}
else if(strcmp(ss, "d") == 0){
strcpy(data[3].code, "d");

fscanf(fp, "%d", &i);

data[3].num+=i;
}

}

printf("%s:", data[0].code);
printf("%d\n", data[0].num);
printf("%s:", data[1].code);
printf("%d\n", data[1].num);
printf("%s:", data[2].code);
printf("%d\n", data[2].num);
printf("%s:", data[3].code);
printf("%d\n", data[3].num);

fclose(fp);

return 0;
}

こんな感じです。
次にファイルの中身を知らないことを前提に同じことをやりたいのですがどのように変えたらよいでしょうか? 
変換ツールがうまく使えなくてごめんなさい。              




この投稿にコメントする

削除パスワード

No.26685

Re:ファイル内の統計をとる
投稿者---wis(2006/04/22 19:02:23)


とりあえず整形。
HTML昆布はプレビュで表示されたほうじゃなくて、
貼り付けしたところからもう一度コピペすればいいですよ。

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

struct DATA {
  char code[16];
  int num;
};

struct DATA data[32];

int main()
{
  int i;
  FILE *fp;
  char filename[20], ss[256];

  data[0].num = 0;

  printf("input filename:");
  gets(filename);

  fp = fopen(filename, "r");

  while(fscanf(fp, "%s", &ss) != EOF){
    if(strcmp(ss, "a") == 0){
      strcpy(data[0].code, "a");
      fscanf(fp, "%d", &i);
      data[0].num+=i;

    } else if(strcmp(ss, "b") == 0){
      strcpy(data[1].code, "b");
      fscanf(fp, "%d", &i);
      data[1].num+=i;

    } else if(strcmp(ss, "c") == 0){
      strcpy(data[2].code, "c");
      fscanf(fp, "%d", &i);
      data[2].num+=i;

    }else if(strcmp(ss, "d") == 0){
      strcpy(data[3].code, "d");
      fscanf(fp, "%d", &i);
      data[3].num+=i;
    }
  }

  printf("%s:", data[0].code);
  printf("%d\n", data[0].num);
  printf("%s:", data[1].code);
  printf("%d\n", data[1].num);
  printf("%s:", data[2].code);
  printf("%d\n", data[2].num);
  printf("%s:", data[3].code);
  printf("%d\n", data[3].num);

  fclose(fp);

  return 0;
}




この投稿にコメントする

削除パスワード

No.26686

Re:ファイル内の統計をとる
投稿者---とろり(2006/04/22 21:30:50)


こんばんは。

> 次にファイルの中身を知らないことを前提に同じことをやりたいのですがどのように変えたらよいでしょうか?

codeがa,b,c,dのいずれかかを判別している部分を構造体から検索するようにして、
構造体になければ追加するようにすれば良いです。

以下は、基本情報技術者試験調ヒント。
コメントa〜dに適切なコードを追加することにより完成します。
#あくまでコーディングの一例。プログラムには決まった解答はないので。


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

#define MAX_DATA    32

typedef struct DATA {
    char code[MAX_DATA];
    int num;
} Data;

int main(void)
{
    int i;
    char code[MAX_DATA];
    int num;
    char filename[MAX_DATA];
    FILE *fp;

    Data data[MAX_DATA];
    int datanum;

    printf("input file name -->");
    scanf("%s", filename);

    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("file open error. %s\n", filename);
        return -1;
    }
    memset(data, 0x00, sizeof(data));
    datanum = 0;
    while (EOF != fscanf(fp, "%s%d", code, &num)) {

        for (/* a */) {
            if (0 == strcmp(data[i].code, code))
                break;
        }
        if (/* b */) {  /* codeは既出 */
            strcpy(data[i].code, code);
            data[i].num = num;
            /* c */
        } else {        /* codeは未出 */
            /* d */
        }

    }
    fclose(fp);

    for (/* a */) {
        printf("%d : %s = %d\n", i+1, data[i].code, data[i].num);
    }

    return 0;
}



この投稿にコメントする

削除パスワード

No.26687

Re:ファイル内の統計をとる
投稿者---とろり(2006/04/22 21:41:31)


訂正。

コード中、コメントの「codeは既出」と「codeは未出」が逆になってます。


この投稿にコメントする

削除パスワード

No.26699

Re:ファイル内の統計をとる
投稿者---ビギナー(2006/04/24 17:53:11)


自分なりにつっくた物を載せます。
どこをどのように直していったらよろしいでしょうか?
おかしいところばかりですが、できたら添削などしていただけると助かります。

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

struct DATA {
  char code[16];
  int num;
};

struct DATA data[32];

int main()
{
  int i,j=0;
  FILE *fp;
  char filename[20], ss[256];
  char *p;
  int count=0;

  data[0].num = 0;

  printf("input filename:");
  gets(filename);

  fp = fopen(filename, "r");

  while(!feof(fp)){
        fgets(p,256, fp);
        count++;
        }

  fscanf(fp, "%s", &ss);
  strcpy(data[0].code, ss);

  fscanf(fp, "%d", &i);
  data[0].num=i;

  while(!feof(fp)){
          fscanf(fp, "%s", &ss);

    if(strcmp(ss, data[count].code) == 0){

        fscanf(fp, "%d", &i);
        data[count].num+=i;
      }
      else {
        strcpy(data[count].code, ss);

        fscanf(fp, "%d", i);
          data[count].num+=i;
      }
  }
  for(j=0; j<=count; j++){

    printf("%s:", data[j].code);
           printf("%d\n", data[j].num);
  }

  fclose(fp);

  return 0;
}




この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧