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

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

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

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

Q&A

解決済

1回答

6595閲覧

C言語 再定義されています。異なる基本型です。エラー

kokok

総合スコア145

C

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

0グッド

0クリップ

投稿2019/08/10 05:21

c

1 2#include <stdio.h> 3#include <stdlib.h> 4#include <string.h> 5#pragma warning(disable: 4996) 6 7#define H_PRT 0x02// ヘッダ印字オプション 8#define C_PRT 0x01// 文字印字オプション 9#define ROW 16 // 1行に表示する文字 10#define TEXTBUF 16 //テキストファイル用のバッファ 11#define FILE_ERR 10// 12#define OPT_ERR 10 13//プロトタイプ宣言 14void dump(unsigned char* staddr, int dsize, opts_t* opts); 15//オプション 16typedef struct { 17 18 char* infilename; 19 char prt_charflag; 20 char prt_headerflag; 21 char prt_help; 22 int offsetval; 23 int filecheck; 24 int optcheck; 25} opts_t; 26 27//オプションの解析 28int opts_analisys(int argc, char* argv[], opts_t* opts) { 29 30 int cnt; 31 int err = 0; 32 for (cnt = 1; cnt < argc; cnt++) { 33 34 if (*argv[cnt] == '/') { 35 36 switch (*(argv[cnt] + 1)) { 37 38 case'H': 39 case'h': 40 41 opts->prt_headerflag = 0; //16行毎にヘッダーの出力 prt_headerflag; = 0 42 43 break; 44 case 'c': 45 case 'C': 46 47 opts->prt_charflag = 1; //ダンプのあとに文字を表示(デフォルトは= 1 prt_charflag; = 1 48 49 break; 50 case 'o': 51 case 'O': 52 opts->offsetval = 1; 53 54 break; 55 56 case '?': 57 opts->prt_help = 1; 58 break; 59 60 default: //オプションが無いとき、エラー 61 62 opts->optcheck = OPT_ERR; 63 err = OPT_ERR; //opt err 64 65 break; 66 } 67 } 68 69 if (opts->infilename == NULL) { 70 opts->infilename = argv[cnt]; //ファイル名をopts.infilename へ 71 } 72 else { 73 74 opts->filecheck = FILE_ERR; 75 err = FILE_ERR; 76 77 return err; 78 } 79 } 80 81 return err; 82} 83 84int main(int argc, char* argv[]) { 85 86 87 char bin_data[TEXTBUF]; // テキストファイル読み込み用 88 int readnum; 89 opts_t opts; 90 int result; 91 92 93 opts.infilename; 94 opts.prt_charflag ; 95 opts.prt_headerflag; 96 opts.prt_help ; 97 opts.offsetval ; 98 opts.filecheck ; 99 opts.optcheck ; 100 101 102 103 FILE* file; 104 105 result = opts_analisys(argc, argv, &opts); 106 107 108 //if(ファイルエラー   または  オプションで?) 109 if (((result && opts.filecheck) != 0)||((result && opts.optcheck)!= 0) || (opts.prt_help == 1)) { 110 111 if ((result & opts.filecheck) != 0) { 112 fprintf(stderr, "ファイル指定が2つあります"); 113 } 114 if ((result & opts.optcheck) != 0) { 115 116 fprintf(stderr, "オプション指定が間違っています"); 117 } 118 if (opts.prt_help == 1) { 119 fprintf(stderr, "構文: mydump[<opts>] [<inpath>] [<opts>]\n機能: ファイルやデバイスの内容を16進で表示する\nオプション:\n/ o[=]<hex> オフセットアドレスの指定(省略の場合は0000)\n/ h 16行毎にヘッダーの出力(デフォルトは = 0)\n / c   ダンプのあとに文字を表示(デフォルトは = 1)\n / ?   使用方法の表示(このメッセージを表示)"); 120 121 } 122 return; 123 } 124 125 if (opts.infilename != 0) { 126 127 //fseek(*file, opts.offsetval, SEEK_CUR); 128 129 file = fopen(opts.infilename, "rb"); 130 } 131 else { 132 file = stdin; 133 return; 134 } 135 136 while (readnum = fread(bin_data, sizeof(unsigned char), TEXTBUF, file) > 0) { 137 138 dump(bin_data, readnum, &opts); 139 } 140 141 if (opts.infilename != NULL){ 142 fclose(file); //ファイルが開かれたらクローズ 143 } 144} 145//印刷 146void dump(unsigned char* staddr, int dsize, opts_t *opts) { 147 148 int startcnt = 0;// ダンプするバイト数のカウント 149 int bytecnt; // 16回ループさせる 150 int savecnt; 151 static int address = 0; //アドレスの表示 152 static int onhold = 0; //文字出力が最後のバイトだった時の一時保留 153 154 static int headercnt = 0; 155 156 char addrhead[] = "Addr"; 157 char hexa[] = "0 1 2 3 4 5 6 7 8 9 A B C D E F"; 158 char charprint[] = "0 2 4 6 8 A C E"; 159 160 while (startcnt < dsize) { 161 162 if (onhold != 0) { //前回最後が漢字だった場合、漢字を出力して改行 163 164 printf("%c%c\n", onhold, staddr[startcnt]); 165 } 166 167 //初回ヘッダー表示 opt & H_PRT == 0だった時は16行毎にヘッダー表示 168 if ((headercnt == 0) || ((opts->prt_headerflag & H_PRT) == 0) && (headercnt % ROW == 0)) { 169 //16行毎にヘッダー 170 171 printf(" %s %s ", addrhead, hexa); 172 173 174 if ((opts->prt_charflag & C_PRT) != 0) { //opt が文字表示の場合 文字ヘッダー表示 175 176 printf("%s", charprint); 177 } 178 179 printf("\n"); 180 printf("-------- ---- ---- ---- ---- ---- ---- ---- ----"); 181 182 if ((opts->prt_charflag & C_PRT) != 0) { ////opt が文字表示の場合 文字罫線表示 183 printf(" ----------------"); 184 185 } 186 printf("\n"); 187 } 188 189 headercnt++; 190 191 printf("%08x ", address); 192 193 savecnt = startcnt; 194 for (bytecnt = 0; bytecnt < ROW; bytecnt++) { 195 196 if (startcnt < dsize) { 197 printf("%02x", staddr[startcnt]); //16進数で出力 198 } 199 else { 200 printf(" "); 201 } 202 if (startcnt % 2 != 0) { 203 printf(" "); 204 } 205 startcnt++; 206 } 207 208 //文字の出力 209 210 if ((opts->prt_charflag & C_PRT) != 0) { //optで文字表示の場合 表示 211 212 startcnt = savecnt; 213 printf(" "); 214 215 for (bytecnt = 0; bytecnt < ROW; bytecnt++) { 216 217 if (onhold != 0) { //前回最後が漢字だった場合 次の行の最初にスペースと初期化 218 219 printf(" "); 220 onhold = 0; 221 bytecnt++; 222 startcnt++; 223 } 224 225 if (startcnt < dsize) { 226 227 //漢字だった場合 228 if ((staddr[startcnt] >= 0x81 && staddr[startcnt] < 0xa0) || (staddr[startcnt] >= 0xe0 && staddr[startcnt] < 0xfd)) { 229 230 if (bytecnt < ROW - 1) { //最後のバイトでなければ 231 232 printf("%c%c", staddr[startcnt], staddr[startcnt + 1]); 233 startcnt++; 234 bytecnt++; 235 } 236 else {//漢字で最後のバイトの場合、保留 237 238 onhold = staddr[startcnt]; 239 } 240 } 241 else { 242 243 if ((staddr[startcnt] >= 0x20 && staddr[startcnt] < 0x7f) || (staddr[startcnt] >= 0xa0 && staddr[startcnt] < 0xe0)) { 244 245 printf("%c", staddr[startcnt]); 246 } 247 else { 248 printf(""); 249 } 250 } 251 } 252 else { 253 printf(" "); 254 } 255 256 startcnt++; 257 } 258 if (onhold == 0) { //最後が漢字でなければ改行 259 printf("\n"); 260 } 261 } 262 else { //optが文字表示ではない場合 改行 263 264 printf("\n"); 265 } 266 address += ROW; //addressを出力しただけ足す 267 } 268} 269 270

上記のコードを実行すると
dump関数を呼び出すところで

警告 C4013 関数 'dump' は定義されていません。int 型の値を返す外部関数と見なします。

dump関数の方で

エラー C2371 'dump': 再定義されています。異なる基本型です。
と出てしまいます。
原因が分からなかったのでアドバイス頂けると助かります。

c

1while (readnum = fread(bin_data, sizeof(unsigned char), TEXTBUF, file) > 0) { 2 3 dump(bin_data, readnum, &opts); 4 }

c

1void dump(unsigned char* staddr, int dsize, opts_t *opts) { 2

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

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

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

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

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

guest

回答1

0

ベストアンサー

プロトタイプ宣言を構造体定義の後ろに持ってこよう

投稿2019/08/10 05:34

y_waiwai

総合スコア87774

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

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

kokok

2019/08/10 05:43

ありがとうございます。
y_waiwai

2019/08/10 08:03

なぜこのようなエラーが出たのかを考えてみてくださいねっ
kokok

2019/08/10 12:37

調べ方が下手で理由が分かりませんでした。 opts_t の型 が分からないとかでしょうか?
y_waiwai

2019/08/10 12:50

そのとおりです C言語というのは単純な言語仕様で、ソースコードの上から順に解釈していく、という方式を取ります # C#なんかだと、どこで宣言してよーがファイル別れてよーが探してきてくれますが 元コードだと、プロトタイプ宣言の時点で構造体の定義がなされてないので、ワーニングが出て宣言はデフォルトの型を持つものとして解釈されてしまい、あとの関数定義で型が違う!とエラーになってしまいます
kokok

2019/08/10 13:36

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問