![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
「商品コード」(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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# C言語初心者 構造体 課題について 1 2023/03/10 19:30
- C言語・C++・C# カードシャッフルのブログラムを使ってc言語でブラックジャックをしたい 2 2022/04/12 15:13
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
C言語の課題です
-
csvファイルの読み込みで失敗し...
-
commons-netでのFTP送信について
-
c言語でのfscanfについて
-
【C言語】ファイルを読み込んで...
-
「コマンドライン引数チェック...
-
fscanfでループしてしまう。
-
C言語でセグメンテーションエ...
-
CRC32の計算方法
-
C言語でファイル読み書きを早く...
-
ファイルに行番号を追加
-
C++で、先頭に同じ文字列がある...
-
テキストファイル内に対して, ...
-
C言語にてXMLファイルから任意...
-
fgets( ) の返り値は何?
-
大量の入力ファイルを扱うとき...
-
c言語 DFAのプログラム
-
_popen() のエラー取得
-
ファイルが読み込めない・・・
-
複数ファイルの同時読み込みの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ガンマ変換 C言語でプログラ...
-
c言語でのfscanfについて
-
なぜCSQとCIP形式ではコ...
-
複数ファイルの同時読み込みの...
-
fopenでファイル名に、変数を使...
-
ファイル出力で改行を入れたい!
-
ファイルへの書込み処理が異常...
-
【C言語】ファイルを読み込んで...
-
エラーがわかりません、、
-
C言語でセグメンテーションエ...
-
C言語でファイル読み書きを早く...
-
テキストファイル内に対して, ...
-
fgets( ) の返り値は何?
-
ファイルに行番号を追加
-
OpenGLによる描画内容をBMP出力
-
fscanfでループしてしまう。
-
c言語 ファイルから数字を読み...
-
ファイルが読み込めない・・・
-
CRC32の計算方法
-
CSVファイルの内容を構造体に格...
おすすめ情報