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

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

新規登録して質問してみよう
ただいま回答率
85.50%
C

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

Q&A

解決済

3回答

4644閲覧

C言語 Sレコードをバイナリ変換

kokok

総合スコア145

C

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

0グッド

0クリップ

投稿2019/08/22 05:41

c

1#include <stdio.h> 2#include <stdlib.h> 3#pragma warning(disable: 4996) 4 5#define ROWREADMAX 256 //一行の読み込み最大文字数 6#define BUFFER 1024 7#define ADDRESSBYTE2 2 8#define ADDRESSBYTE3 3 9#define ADDRESSBYTE4 4 10#define FILE_OPEN_ERR 0x01 //ファイルオープンエラー 11#define FILE_SPECIFIED_ERR 0x02 // ファイル指定エラー 12#define OPT_ERR 0x04 //オプションエラー 13//オプション 14typedef struct { 15 16 char* infilename; 17 char* outfilename; 18 char input_flag; 19 char output_flag; 20 char help_flag; 21 22} opts_t; 23 24//プロトタイプ宣言 25analysis_srecord_change_binary(char readline[], FILE* wfile); 26srecord_change_binary(char* ascdata); 27 28 29//オプションの解析 30int opts_analisys(int argc, char* argv[], opts_t* opts) { 31 32 33 int err = 0; 34 int cnt; 35 FILE* file; 36 37 for (cnt = 1; cnt < argc; cnt++) { //引数の数ループ 38 if (*argv[cnt] == '/') { //引数の最初の文字が/なら 39 40 switch (*(argv[cnt] + 1)) { 41 42 case'r': 43 case'R': 44 45 if ((file = fopen(opts->infilename, "r")) != NULL) { //ファイルがあれば 46 } 47 else { //ファイルがなければ 48 err |= FILE_OPEN_ERR; 49 } 50 51 break; 52 case 'i': 53 case 'I': 54 55 if (*(argv[cnt] + 2) == '=') { //オプションに= があった場合 56 57 opts->infilename = argv[cnt] + 3; 58 } 59 else { 60 opts->infilename = argv[cnt] + 2; 61 } 62 63 break; 64 case 'o': 65 case 'O': 66 67 if (*(argv[cnt] + 2) == '=') { 68 opts->outfilename = argv[cnt] + 3; 69 } 70 else { 71 72 opts->outfilename = argv[cnt] + 2; 73 } 74 75 break; 76 case '?': 77 78 opts->help_flag = 1; 79 80 break; 81 82 default: //オプションが無いとき、エラー 83 84 err |= OPT_ERR; 85 break; 86 } 87 } 88 89 if (opts->infilename == NULL) { 90 91 opts->infilename = argv[cnt]; //引数の一つ目のファイル名はインプットファイル 92 } 93 else if (opts->outfilename == NULL) { 94 opts->outfilename = argv[cnt]; //引数の二つ目のファイル名はアウトプットファイル 95 } 96 else { 97 98 err |= FILE_SPECIFIED_ERR; //ファイル指定エラーのビットを立てる 99 } 100 } 101 return err; 102} 103int main(int argc, char* argv[]) { 104 105 opts_t opts; 106 char readline[BUFFER]; 107 int result = 0; 108 109 FILE* wfile; 110 FILE* file; 111 112 //構造体の初期化 113 opts.infilename = NULL; 114 opts.outfilename = NULL; 115 //opts.input_flag = stdin; 116 //opts.output_flag = stdout; 117 opts.help_flag = 0; 118 119 120 result = opts_analisys(argc, argv, &opts); //オプションの解析 121 122 if ((result != 0) || (opts.help_flag)) { 123 if (result & FILE_SPECIFIED_ERR) { 124 fprintf(stderr, "ファイル指定が3つ以上あります\n"); 125 } 126 if (result & FILE_OPEN_ERR ) { 127 fprintf(stderr, "ファイルが存在しません"); 128 } 129 if (result & OPT_ERR) { 130 131 fprintf(stderr, "オプションの指定が間違っています"); 132 } 133 if (result & opts.help_flag) { 134 135 fprintf(stderr, "Syntax: srec2bin[<opts>] [[/ i[=]]<inpath>] [[/ o[=]]<outpath>] [<opts>]\n"); 136 fprintf(stderr, "Function : converts S record to binary file\n"); 137 fprintf(stderr, "Options :\n\n"); 138 fprintf(stderr, " / r 出力ファイルが存在するとき、強制的に上書きをする。\n"); 139 fprintf(stderr, " / i[=] 入力ファイルパス(デフォルト = stdin)"); 140 fprintf(stderr, " / o[=] 出力ファイルパス(デフォルト = stdout)\n"); 141 fprintf(stderr, " / ? 使い方の表示\n"); 142 } 143 return; 144 } 145 146 147 if ((wfile = fopen(opts.outfilename, "w")) != NULL){ 148 149 } 150 else { 151 152 fprintf(stderr,"ファイルが開けませんでした"); 153 } 154 155 if (opts.infilename != NULL) { //コマンドラインからファイルの入力があれば 156 157 158 if ((file = fopen(opts.infilename, "r")) != NULL) { //ファイルがあれば 159 160 while (fgets(readline, ROWREADMAX, file) != NULL) { 161 162 analysis_srecord_change_binary( readline,&wfile); 163 printf("\n"); 164 // puts(readline); 165 } 166 167 } 168 else { //ファイルがなければ 169 fprintf(stderr, "ファイルが開けませんでした"); 170 return 0; 171 } 172 } 173 else { 174 file = stdin; 175 } 176 177 if (opts.infilename != NULL) { 178 fclose(file); //ファイルが開かれたらクローズ 179 } 180 if (opts.outfilename != NULL) { 181 fclose(wfile); 182 183 } 184} 185 186 187//Sレコードを解析しバイナリに変換 188 189analysis_srecord_change_binary(char readline[], FILE* wfile) { 190 191 int cnt = 0; 192 char stype; 193 int recsize; //レコード長 194 int addsize; //アドレスの長さ 195 int datasize; //データの長さ 196 unsigned char checksum = 0; 197 static int row = 0; 198 char bindata; 199 200 201 row++; //読み込みが何行目か 202 203 if (readline[cnt] == 'S') { //初めがSなら 204 205 cnt++; 206 207 stype = (readline[cnt]); //タイプを格納 208 209 switch (stype) { //タイプによってアドレスの長さ格納 210 211 case '0': 212 case '1': 213 case '9': 214 215 addsize = ADDRESSBYTE2; 216 cnt++; 217 break; 218 case'2': 219 case'8': 220 221 addsize = ADDRESSBYTE3; 222 cnt++; 223 break; 224 case'3': 225 case'7': 226 227 addsize = ADDRESSBYTE4; 228 cnt++; 229 break; 230 default: 231 fprintf(stderr, "Sレコードではありません"); 232 exit(1); 233 } 234 235 recsize = srecord_change_binary(&readline[cnt]); //レコードサイズを取得 236 237 cnt += 2; 238 checksum += recsize; //チェックサムにレコードサイズの部分を足す 239 240 for (int dcnt = 0; dcnt < addsize; dcnt++) { //アドレスをバイナリに変換してチェックサムに足す 241 242 bindata = srecord_change_binary(&readline[cnt]); 243 244 checksum += bindata; 245 246 cnt += 2; 247 } 248 249 //レコードサイズから(アドレスサイズ+1(チェックサム))を引き、データサイズを算出 250 datasize = recsize - (addsize + 1); 251 252 //cnt += addsize; //カウントをアドレス分進める 253 254 for (int dcnt = 0; dcnt < datasize; dcnt++) { 255 256 bindata = srecord_change_binary(&readline[cnt]); //データをバイナリに変換 257 checksum += bindata; //2バイト進める 258 259 fputc( bindata, wfile); 260 261 //printf("%c", bindata); 262 263 cnt += 2; 264 } 265 266 checksum += srecord_change_binary(&readline[cnt]); //チェックサムをチェックサムに足す 267 268 269 if (checksum != 0xFF) { //チェックサムでデータの確認 270 271 printf("\n"); 272 fprintf(stderr ,"%d行目のデータがおかしいです\n%s",row,readline); 273 } 274 } 275 else { 276 fprintf(stderr, "Sレコードではありません"); 277 } 278} 279 280//Sレコードをバイナリに変換 281 282srecord_change_binary(char *ascdata) { 283 284 unsigned char bin_H; 285 unsigned char bin_L; 286 unsigned char bin_HL; 287 288 bin_H = (*ascdata - '0'); 289 if (bin_H > 9) { 290 bin_H = bin_H - ('A' - ':'); 291 } 292 293 bin_H = bin_H << 4; 294 295 bin_L = (*(ascdata + 1) - '0'); 296 if (bin_L > 9) { 297 298 bin_L = bin_L - ('A' - ':'); 299 } 300 301 bin_HL = bin_H |= bin_L; 302 303 return bin_HL; 304}

コマンドラインから引数をもらい、コマンドラインで渡されたファイルを別のファイルに出力したいと考えております。

上記のコードを実行すると

1:警告
C6387 'opts.outfilename' は '0' である可能性があります: この動作は、関数 'fopen' の指定に従っていません。 srecord

対象行>>if ((wfile = fopen(opts.outfilename, "w")) != NULL){

2:警告
C4047 '関数': 間接参照のレベルが 'FILE *' と 'FILE **' で異なっています。 164行

対象行>> analysis_srecord_change_binary( readline,&wfile);


警告 C4024 'analysis_srecord_change_binary': の型が 2 の仮引数および実引数と異なります。 164行

対象行>> analysis_srecord_change_binary( readline,&wfile);

と3つ警告が出てしまいます。
なかなか、理由が分からなかったのでアドバイス頂けると助かります。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

1:警告
C6387 'opts.outfilename' は '0' である可能性があります:

引数の指定次第では、opts.outfilename がセットされず、NULL のままの可能性がある。

あとは、Bullさんの指摘通り、
analysis_srecord_change_binary()の第2引数は、 FILE * が必要であるが、&wfile なので、 FILE **である。

ちょっと気になったのが、srecord_change_binary() の戻り値の宣言がありません。unsigned char で宣言しましょう。また、戻り値が無い場合は、voidです。

投稿2019/08/22 15:29

pepperleaf

総合スコア6383

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kokok

2019/08/23 00:48

ありがとうございます。 勉強になりました。
guest

0

コードを詳細に見てませんが、二つ目と三つ目の警告は

c

1analysis_srecord_change_binary(readline, wfile);

とすれば消えるはずです。
この警告は致命的なので直さなければなりませんが、最初の警告は余り気にしなくても良いかもしれません。

投稿2019/08/22 13:54

Bull

総合スコア986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C6387 'opts.outfilename' は '0' である可能性があります:

opts.outfilenameがNULLなんでしょう
その他の警告は、出ている文章のとおりなので、それを読んでください

で、C言語のコードを組むのなら、VisualStudioやEclipseなどのデバッグできる環境を整えましょう。
任意のソース業で実行を止め、変数の内容を見たり、1行づつ実行したりできます
そうすれば、当てずっぽでコードを書かなくて済むようになります

投稿2019/08/22 05:45

編集2019/08/22 05:48
y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問