【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集

CSVファイルの内容をfreadで読み込み、strtokを使わずにbuffに格納した後、
buffから1文字ずつbuff2へコピーさせていって、コンマがきたら数字、
改行がきたら名前と判別して、自作関数に渡して表示させたいです。

CSVファイルの内容は
『11,名前1(改行)
15,名前2(改行)
18,名前3』
といった感じです。

-------------------------------------------------------
#define _CRT_SECURE_NO_DEPRECATE 1
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define NUM 256
struct kou
{
short nenrei;
char namae[30];
};
void pri(struct kou *o)
{
printf("%d\n%s\n",o->nenrei,o->namae);
}
int main(void)
{
FILE *fp; // ファイルポインタ
char buff1[NUM] = {0};
char buff2[NUM] = {0};
char *fname = "text1.csv"; // ファイル名を指定
short i = 0;
int n = 0;
struct kou p;

fp = fopen(fname, "r");

if(fp == NULL)
{
printf("%sファイルをオープンできませんでした。\n",fname);
}

fread(buff, 1, NUM, fp);

while(buff1[n] != NULL)
{
buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。

if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。
{
i = (short)atoi(buff2); // char型からshort型への変換
p.nenrei = i;
}


if(buff2[n] == '\n')
{
strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。
pri(&p);
}
n++;
}

fclose(fp);
printf("ファイルをクローズしました。\n");

return 0;
}
-------------------------------------------------------

今のままだと
『11
11,名前1

11
11,名前1
15,名前2』
という表示になってしまいます。

while 内で既に読み込んだ部分を読み込ませないよう(表示させないよう)にできたら良いと思うんですが、そういったやり方はあるのでしょうか?
むしろやり方を変えたほうが良いでしょうか・・・。
まだC言語を学び始めて日が浅いので、色々間違っている部分もあると思いますが、
そういったことを含めてアドバイスをいただけたらと思います。
よろしくお願いします。

A 回答 (3件)

以下の部分が要求仕様を満たしているのか確認しましょう



int main(void)
{
  FILE *fp; // ファイルポインタ
  char buff1[NUM] = {0};
  char buff2[NUM] = {0};
  char *fname = "text1.csv"; // ファイル名を指定
  short i = 0;
  int n = 0;
  struct kou p;

  fp = fopen(fname, "r");

  if(fp == NULL)
  {
    printf("%sファイルをオープンできませんでした。\n",fname);
  }

  fread(buff, 1, NUM, fp);
  // 読み込みが成功したのかチェックしなくてもいいのか

  while(buff1[n] != NULL)
  {
    buff2[n] = buff1[n]; // buff2[0]からbuff1の中を一文字ずつコピーしていく。

    if(buff2[n] == ',') // buff2に格納されていく中にコンマがきたら以下の作業を行う。
    {
      i = (short)atoi(buff2); // char型からshort型への変換
      p.nenrei = i;
      // カンマを処理したので次に取り込むbuf2への書き込み位置を
      // 変更しなくてもいいのか
    }

    if(buff2[n] == '\n')
    {
      // buf2先頭から構造体のメンバーにコピーするのなら
      // buf1/buf2にアクセスする変数nは1つで出来るのか
      // この記述だと構造体のnameに"\n"が付加されるが
      // これは意図した動作か
      strcpy(p.namae,buff2); // p.namaeにbuff2をコピー。
      pri(&p);
    }
    n++;
  }

  fclose(fp);
  printf("ファイルをクローズしました。\n");

  return 0;
}
    • good
    • 0
この回答へのお礼

丁寧な回答をありがとうございます。
しっかり読んで理解を深めようと思います。

お礼日時:2009/04/24 06:30

#2です。


>pri(&p);

pri関数の仕様から見て、ポインタを渡す必然性はないです。
    • good
    • 0
この回答へのお礼

補足回答をありがとうございます。

お礼日時:2009/04/24 06:33

>if(fp == NULL)



ファイルが存在しない、などの理由でオープンできなかったときも
強引に読み込もうとしていますね。まずいです。

>fread(buff, 1, NUM, fp);

1行ずつ読み込むのでしたら、freadよりもfgetsあたりの方が使いやすいと思います。
ところで、buffという変数は定義していません。

>while(buff1[n] != NULL)

NULLはポインタです。buff1[n]というchar型と比較することは正しくありません。

>i = (short)atoi(buff2); // char型からshort型への変換
>p.nenrei = i;

iという中間的な変数を設ける必要はありません。
p.nenrei = atoi(buff2);
でじゅうぶんです。

まずは、fgetsの使い方を調べてみてはいかがでしょうか。
    • good
    • 0
この回答へのお礼

丁寧な回答をありがとうございます。
やっぱりか~という部分とそうなのか!という部分がありました。
しっかり読んで理解を深めようと思います。

お礼日時:2009/04/24 06:32

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