0

snprintfを使用して、次の形式のファイルを読み取る簡単な小さなプログラムを作成しました。

skip first 15 chars , next 9 chars are sequence number, next 2 char is message and so on.   

シーケンス番号とメッセージ、つまり文字番号 16 から 26 に興味があります。

以下がプログラムです。各フィールドの最後の文字を読み取りません。シーケンス番号は 9 文字ではなく 8 文字、メッセージは 2 バイトではなく 1 バイトで読み取られます。

#include<stdio.h>

typedef struct
{
  char seqno[9];
  char msg[2];
}Header_T;

int main()
{
  char buf[64]={'\0'};
  FILE *fp;
  int i = 0;
  Header_T hdr1;
  int skipbytes = 15;

  fp=fopen("asdf", "r");
  if (fp == NULL)
  {
    printf("FILE OPEN ERROR\n");
  }
  printf("--sequence--msg--\n");
  while( fgets( buf, sizeof(buf), fp ) != NULL )
  {
    i=skipbytes;
    snprintf(hdr1.seqno, 9, "%s", (buf+i));
    i+=sizeof(hdr1.seqno);
    snprintf(hdr1.msg, 2, "%s", (buf+i));
    i=0;

    printf("--%s--%s--\n", hdr1.seqno, hdr1.msg);
    memset(buf, '\0', 64 );
  }
fclose(fp);
return 0 ;
}

ファイルの内容の一部は次のとおりです

201301082323458000000001H QB234
201301082323558000000002J QB234
201301082323658000000003N QB234
201301082323758000000004JRQB234
201301082333458000000010JSQB234

したがって、期待される出力は

--sequence--msg--
--000000001--H --
--000000002--J --
--000000003--N --
--000000004--JR--
--000000010--JS--

しかし、代わりに私は次のように出力を得ています

--seqno--msgtype--
--00000000--H--
--00000000--J--
--00000000--N--
--00000000--J--
--00000001--J--

誰でもこの動作とその修正方法を説明できますか?

snprintfの代わりに、for ループの文字ごとの割り当てを使用して同じプログラムを試してみましたが、プログラムは正常に動作します。しかし、そのためには、構造内のバイト アラインメントのためにいくつかのフィラーを追加する必要があります。

pragma pack()も使用してみましたが、違いはありません。

ubuntu 64ビットマシンでgcc 4.4.3を使用しています

4

4 に答える 4

1
#include<stdio.h>

typedef struct {
    char seqno[9+1];//+1 for EOS('\0')
    char msg[2+1];
} Header_T;

int main(void){
    char buf[64]={'\0'};
    FILE *fp;
    Header_T hdr1;

    fp=fopen("asdf", "r");
    if (fp == NULL) {
        printf("FILE OPEN ERROR\n");
        return 1;
    }
    printf("--sequence--msg--\n");
    while( fgets( buf, sizeof(buf), fp ) != NULL ){
        sscanf(buf, "%*15c%9c%2c", hdr1.seqno, hdr1.msg);
        hdr1.seqno[sizeof(hdr1.seqno)-1] = hdr1.msg[sizeof(hdr1.msg)-1] = '\0';
        printf("--%s--%s--\n", hdr1.seqno, hdr1.msg);
        //memset(buf, '\0', 64 );
    }
    fclose(fp);
    return 0 ;
}
于 2013-08-04T08:17:16.850 に答える
0

この anwser は、上記の 2 つの anwser の後にあります。これらはすべて、適切な提案を提供します。私はそれらをつなぎ合わせただけです。

まず、次を使用します。

typedef struct
{ char seqno[10];
  char msg[3];
}Header_T;       //so we have the memory for '\0'

次に、次を使用します。

   while( fgets( buf, sizeof(buf), fp ) != NULL )
   {
        i=skipbytes;
        snprintf(hdr1.seqno, 10, "%s", (buf+i));//here we read 9 number and a '\0'
        i+=sizeof(hdr1.seqno) -1;               //the  '\0' is not part of buffer.
        snprintf(hdr1.msg, 3, "%s", (buf+i));   //also for '\0'
        i=0;

        printf("--%s--%s--\n", hdr1.seqno, hdr1.msg);
        memset(buf, '\0', 64 );
   }
于 2013-08-04T07:31:18.897 に答える