• ベストアンサー

作成したプログラムを変更したいのですがどうすればいいのかわかりません。どなたか教えていただけないでしょうか?

「商品コード」(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から商品データを読み込み、すべてのレコードをこの構造体配列に格納するように(画面への出力も同様にすべてのレコードを出力)したいのですがどう変更すればいいのかわかりません。どなたか教えていただけないでしょうか?

質問者が選んだベストアンサー

  • ベストアンサー
  • yama5140
  • ベストアンサー率54% (136/250)
回答No.2

>・ >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 ? } 注:インデントに全角空白使用。

nadonado
質問者

お礼

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

すると、全ての回答が全文表示されます。

その他の回答 (3)

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.4

一部訂正   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行目まで取り込んだら中断するように変更

nadonado
質問者

お礼

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

すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

#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; } といった具合でしょう

すると、全ての回答が全文表示されます。
  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

『gift.dat』のフォーマットは例示の 商品コード:JZK-30 商品名:Jizake_tsumeawase 価格:4500 といった文言で各項目が改行で区切られているのでしょうか? 4行1セットと考えればいいのか ・・・ それとも 『,』区切りなどのように JZK-30,Jizake_tsumeawase,4500 と1行にデータがあるのでしょうか FileIO系のランタイム関数を使ってといった具合になるでしょう fopen,fclose,fscanf(場合によっては sscanf)などでしょう

nadonado
質問者

補足

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』の中身です。

すると、全ての回答が全文表示されます。

関連するQ&A