「商品コード」(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から商品データを読み込み、すべてのレコードをこの構造体配列に格納するように(画面への出力も同様にすべてのレコードを出力)したいのですがどう変更すればいいのかわかりません。どなたか教えていただけないでしょうか?
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 ?
}
注:インデントに全角空白使用。
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行目まで取り込んだら中断するように変更
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;
}
といった具合でしょう
No.1
- 回答日時:
『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』の中身です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
複数ファイルの同時読み込みの...
-
C言語でファイル読み書きを早く...
-
日本語ファイル名のFTPについて
-
構造体のリスト
-
C++でcsvファイルから文字列...
-
ファイルサイズを得る関数
-
ファイルの特定行の抽出
-
fopenでファイル名に、変数を使...
-
csvファイルのデータを構造体に
-
C言語 csv 配列
-
Winsockの通信処理にてファイル...
-
C言語による画像処理で出力時に...
-
2÷3などの余りについて
-
Enterキーを押されたら次の処理...
-
「指定されたキャストは有効で...
-
マイナスからプラスへ転じた時...
-
二次関数と関数の違いは何ですか?
-
「Aに対するBの割合」と「Aに対...
-
C言語初心者です、、、お助けく...
-
数字以外が入力されたらエラー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
c言語でのfscanfについて
-
ファイルへの書込み処理が異常...
-
C言語でファイル読み書きを早く...
-
エラーがわかりません、、
-
日本語ファイル名のFTPについて
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
テキストファイル内に対して, ...
-
複数ファイルの同時読み込みの...
-
C言語の課題です
-
C言語を用いて、csvファイル内...
-
バイナリファイルの読み込み(C...
-
C言語にてXMLファイルから任意...
-
ファイルが読み込めない・・・
-
構造体のメンバにファイルポイ...
-
CRC32の計算方法
-
ファイルからCR/LFを除去したい
-
C言語におけるファイル読み込み...
-
C言語 csv 配列
-
エラー C2664
おすすめ情報