dポイントプレゼントキャンペーン実施中!

「商品コード」(10文字未満の文字列)、「商品名」(40文字未満の文字列)、「値段」(整数値)の3つのメンバをもつ構造体を宣言する。その構造体のデータを最大100個格納できる配列を定義し、ファイルgifts.datの最初の2行と同じ内容を、宣言と同時にそれらの変数の初期値として設定(ファイルから読み込むのではなく、プログラム中にデータを埋め込む)。さらに、次の形式で構造体配列の内容を画面に出力するプログラムを作成する。

商品コード:JZK-30
商品名:Jizake_tsumeawase
価格:4500

商品コード:BSP-15
商品名:Body_soup_set
価格:3000

上記のことを元に作成したものが下記のプログラムです。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct merchandise{
char code[12];
char name[40];
int price;
};

void show_m(struct merchandise *mp, int n)
{
int i;
for(i=0;i<n;i++,mp++){
printf("code: %s\n", mp->code);
printf("name: %s\n", mp->name);
printf("price: %d\n\n", mp->price);
}
}
struct merchandise m_data[100] = {
{"JZK-30","Jizake_tsumeawase",4500},
{"BSP-15","Body_soup_set",3000},
};

int main(void)
{
show_m(m_data, 2);
return 0;
}

このプログラムをプログラム中にデータを読み込む代わりに、ファイルgifts.datから商品データを読み込み、すべてのレコードをこの構造体配列に格納するように(画面への出力も同様にすべてのレコードを出力)したいのですがどう変更すればいいのかわかりません。どなたか教えていただけないでしょうか?

A 回答 (4件)

>・


>SPO-22 Tyoumiryo_variety_set 4000
>上記がファイル『gifts.dat』の中身です。

 スペース区切りのテキストファイルですね。
 
☆1行読み込んで、「スペース」を見つければ(◆)よいのでは。

 ・そして、スペースを文字列終端コードに変換(●)。
 ・構造体にコピー(■)。
 ・整数化(▲)。

 なお、ソースは、「整数値」項目が行末尾の場合であり、「文字列」が末尾の場合は、若干の修正が必要です。
 (Borland C++5.6.4)

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

typedef struct{
 char cCode[ 16 ];
 char cName[ 64 ];
 int iPrice;
}MCD;

int DataRead( MCD sData[] )
{
 int i, iRec = 0, iTop[ 3 ], iT;
 FILE *fp;
 char cBuf[ 64 ];

 fp = fopen( "D:\\----\\++++\\gifts.dat", "r" );

 if( fp == NULL ) return( -9 );

 while( NULL != fgets( cBuf, 64, fp ) ){

  iT = 0;

  iTop[ iT ] = 0; // 第一項目先頭

  for( i = 0; i < 64; i++ ){

   if( ' ' == cBuf[ i ] ){ // ◆

    cBuf[ i ] = 0x00; // ●

    iTop[ ++iT ] = i + 1;
   }
  }
  if( 2 != iT ){ // 想定外レコード

   printf( "Err [%s]\n", cBuf );

   return( -1 );
  }
  strcpy( sData[ iRec ].cCode, &cBuf[ iTop[ 0 ] ] ); // ■
  strcpy( sData[ iRec ].cName, &cBuf[ iTop[ 1 ] ] ); // ■

  sData[ iRec ].iPrice = atoi( &cBuf[ iTop[ 2 ] ] ); // ▲

  iRec++;
 }
 fclose( fp );

 return( iRec );
}
void Show_m( MCD *sData, int iRec )
{
 int i;

 for( i = 0; i < iRec; i++, sData++ ){

  printf( "Code_: %s\n", sData->cCode );
  printf( "Name_: %s\n", sData->cName );
  printf( "Price: %d\n", sData->iPrice );

  printf( "\n" );
 }
}
int main( void )
{
 int iRec;
 MCD sData[ 100 ];

 iRec = DataRead( sData );

 Show_m( sData, iRec );

 return( iRec ); // 0 - 255 -9 ?
}
注:インデントに全角空白使用。
    • good
    • 0
この回答へのお礼

回答ありがとうございました。助かりました。

お礼日時:2008/10/06 11:47

一部訂正


  nCount = 0;
  while( NULL != fgets( sBuf, sizeof( sBuf ), fp ) ) {
    nCount += GetData( sBuf, &m_data[n] );
  }
の部分を
  nCount = 0;
  while( NULL != fgets( sBuf, sizeof( sBuf ), fp ) ) {
    if ( nCount > 99 )
      break;
    nCount += GetData( sBuf, &m_data[n] );
  }

100行目まで取り込んだら中断するように変更
    • good
    • 0
この回答へのお礼

丁寧な回答どうもありがとうございました。参考になりました。

お礼日時:2008/10/06 11:45

#include <stdio.h>


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

struct merchandise{
char code[12];
char name[40];
int price;
};

typedef struct merchandise MERCHADISE;
typedef struct merchandise *LPMERCHADISE;

struct merchandise m_data[100];
int GetData( char* lpBuf, LPMERCHADISE pData )
{
  int nLen, nPrice, nCode
  char *pTokn1, *pTokn2, *pBuf;
  char sCode[12], sName[44];
  nCode = 0;
  pBuf = NULL;
  pTokn1 = pTokn2 = NULL;
  nLen = strlen( lpBuf ) + 1;
  pBuf = (char*)malloc( nLen )
  strcpy( pBuf, lpBuf );
  pTokn1 = strtok( pBuf, " " );
  pTokn2 = strtok( NULL, " " );
  if ( pTokn1 != NULL && pTokn2 != NULL ) {
    if ( ( strlen( pTokn1 ) < 10 ) && ( strlen( pTokn2 ) < 40 ) ) {
      if ( 3 == sscanf( lpBuf, "%s %s %d", sCode, sName, &nPrice ) ) {
        strcpy( pData->code, sCode );
        strcpy( pData->name, sName );
        pData->price = nPrice;
        nCode = 1;
      }
    }
  }
  free( pBuf );
  return nCode;
}

int main( void )
{
  FILE* fp;
  char sBuf[128];
  int nCount, n;

  if ( NULL != ( fp = fopen("gift.dat", "rt") ) ) {
    fprintf( stderr, "File not found 'gidt.dat' \n" );
    return 1;
  }

  nCount = 0;
  while( NULL != fgets( sBuf, sizeof( sBuf ), fp ) ) {
    nCount += GetData( sBuf, &m_data[n] );
  }
  fclose( fp );

  for( n = 0; n < nCount; n++ ) {
    printf( "%3d: %-10s %-40s %d\n", n, m_data[n].code,
      m_data[n].name, m_data[n].price );
  }
  return 0;
}

といった具合でしょう
    • good
    • 0

『gift.dat』のフォーマットは例示の


商品コード:JZK-30
商品名:Jizake_tsumeawase
価格:4500

といった文言で各項目が改行で区切られているのでしょうか?
4行1セットと考えればいいのか ・・・

それとも 『,』区切りなどのように
JZK-30,Jizake_tsumeawase,4500
と1行にデータがあるのでしょうか

FileIO系のランタイム関数を使ってといった具合になるでしょう
fopen,fclose,fscanf(場合によっては sscanf)などでしょう

この回答への補足

JZK-30 Jizake_tsumeawase 4500
BSP-15 Body_soap_set 3000
BT-200 Bath_towel_set 2500
TEA-20 Koutya_tsumeawase 5000
THY-55 Koutya_hachimitsu_tsumeawase 3000
SPO-22 Tyoumiryo_variety_set 4000
上記がファイル『gifts.dat』の中身です。

補足日時:2008/10/03 00:43
    • good
    • 0

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