質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.45%

  • C

    4679questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C言語 指定バイト数の切り出し(固定長ファイルの読み込み)

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 749

watan

score 7

C言語で固定長ファイルを構造体に読み込む処理にて、指定バイト数の切り出しがうまく組めません。

include <stdio.h>

include <stdlib.h>

include <string.h>

typedef struct{
char    sStr1[3] ;
char    sNum[3] ;
char    sDate[6] ;
}stTest ;

const   char    sLine[3][20] = { "xABCxx123xx180730xx","xXYZxx456xx180731xx","xEFGxx789xx180801xx" }; 
void    main(){
stTest  kTest[3] ;
int     iLp;

for( iLp = 0; iLp < 3 ; iLp ++ ){
//2Bytes目から3バイト文字列を構造体に格納する。
strncpy( kTest[iLp].sStr1, &sLine[iLp][1], 3 ) ;

//7Bytes目から3バイト文字列を構造体に格納する。
strncpy( kTest[iLp].sNum, &sLine[iLp][6], 3 );

//12Bytes目から6バイト文字列を構造体に格納する。
strncpy( kTest[iLp].sDate, &sLine[iLp][11], 6 ) ;

printf( "sTr1[%s] sNum[%s] sDate[%s]\n",  kTest[iLp].sStr1,  kTest[iLp].sNum,  kTest[iLp].sDate);
}
return ;
}


sTr1[ABC] sNum[123] sDate[180730]
sTr1[XYZ] sNum[456] sDate[180731]

sTr1[EFG] sNum[789] sDate[180801]

としたいのですが、上記を実行すると以下のような結果となります。
sTr1[ABC123180730@] sNum[123180730@] sDate[180730@] sTr1[XYZ456180731@] sNum[456180731@] sDate[180731@]
sTr1[EFG78918081x╗] sNum[78918081x╗] sDate[18081x╗]

どの部分が問題なのか、ご指導お願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+1

固定長のファイルを読み込む場合、たいていの場合は読み込まない部分も構造体のメンバとして定義しておいて、丸ごと読み込みます。

typedef struct{
    char    sDummy1[1] ;
    char    sStr1[3] ;
    char    sDummy2[2] ;
    char    sNum[3] ;
    char    sDummy3[2] ;
    char    sDate[6] ;
    char    sDummy4[2] ;
}stTest ;

stTest work;
fread(&work, sizeof(work), 1, fp);


これを今回のコードに当てはめるとこんな感じでしょうか。

typedef struct{
    char    sDummy1[1] ;
    char    sStr1[3] ;
    char    sDummy2[2] ;
    char    sNum[3] ;
    char    sDummy3[2] ;
    char    sDate[6] ;
    char    sDummy4[2] ;
}stTest ;

const   char    sLine[3][20] = { "xABCxx123xx180730xx","xXYZxx456xx180731xx","xEFGxx789xx180801xx" }; 
void    main(){
    stTest  kTest[3] ;
    int     iLp;

    for( iLp = 0; iLp < 3 ; iLp ++ ){
        memcpy(&kTest[iLp], &sLine(iLp), sizeof(stTest));
        printf( "sTr1[%.3s] sNum[%.3s] sDate[%.6s]\n",  kTest[iLp].sStr1,  kTest[iLp].sNum,  kTest[iLp].sDate);
    }
    return ;
}


ちなみに今ある構造体の定義のままでも上記のprintfを使えば期待通りになると思います。
要はNULL終端ではない文字列を出力しようとしているだけの問題です。

NULL終端文字列として取り込みたいのであれば、構造体の各メンバの領域を増やす必要があります。

typedef struct{
    char    sStr1[4] ;  // 1バイト拡張
    char    sNum[4] ;  // 1バイト拡張
    char    sDate[7] ;  // 1バイト拡張
}stTest ;

const   char    sLine[3][20] = { "xABCxx123xx180730xx","xXYZxx456xx180731xx","xEFGxx789xx180801xx" }; 
void    main(){
    stTest  kTest[3] ;
    int     iLp;

        // 領域全体を初期化しておく
    memset(&kTest, 0x00, sizeof(kTest));

    for( iLp = 0; iLp < 3 ; iLp ++ ){
        //2Bytes目から3バイト文字列を構造体に格納する。
        strncpy( kTest[iLp].sStr1, &sLine[iLp][1], 3 ) ;

        //7Bytes目から3バイト文字列を構造体に格納する。
        strncpy( kTest[iLp].sNum, &sLine[iLp][6], 3 );

        //12Bytes目から6バイト文字列を構造体に格納する。
        strncpy( kTest[iLp].sDate, &sLine[iLp][11], 6 ) ;

        printf( "sTr1[%s] sNum[%s] sDate[%s]\n",  kTest[iLp].sStr1,  kTest[iLp].sNum,  kTest[iLp].sDate);
    }
    return ;
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/30 19:29

    大変わかりやすく解説いただきまして、ありがとうございました。
    構造体にそのまま読み込むことが出来るのですね。サンプルまでご提示いただきとても助かりました。

    キャンセル

+1

文字列とは終端に'\0'が必要です
ですんで、3バイトの文字列には、最低4バイト分の領域が必要となります
そこらへん修正してやり直してみてください

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/07/30 19:26

    ありがとうございました!
    基本的な知識が不足しておりました。大変参考になりました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.45%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C

    4679questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。