16進数のデータをファイルから読込む

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
C言語はじめました

16進数のデータをファイルから読込む

#1

投稿記事 by C言語はじめました » 17年前

 こんばんは。
 貴HPの”if文とfor文、簡単な関数扱いしか知らない人でも簡単に…”の文面を見て力を得ました。
 現在、ゲーム基本編まで読み終え、自分なりにソースをいじくってみたりしながらC言語の勉強をしています。

 今度、各ラウンド毎にマップデータを書き換えて表示するプログラムを組もうと思っています。
 例えば、16×16のマップデータがあるとして、”00,2A,3C,…”のように書いて、それをテキストファイルに
保存しておき、必要に応じて二次元配列(Map[x][y])に読込むというものなのですが…VBほど楽にはいかず困っ
ています。

 とりあえず、”fopen”や”printf”を使ってデータを読込むということはわかるのですが、そこから先が
わかりません。
 テキストデータを16進数で保存しているので、文字列で受け取ってから整数に変換すると思うのですが、VBの
”Val("&h"+変数)”みたいな変換方法はあるのでしょうか?もし、なんらかの関数があるならば教えてください。
よろしくお願いします。

管理人

Re:16進数のデータをファイルから読込む

#2

投稿記事 by 管理人 » 17年前

こんばんは。
HPの方みてくださってありがとうございます^^

ファイルから読み込んだ文字列はもちろん数値に変換できます。

http://www.geocities.jp/ky_webid/c/044.html

こちら参考になると思います。
たとえば10進数でかかれけた整数の文字列を数値に変換するときはatoi関数を使います。
好きな基数に変換できるstrtolもありますので参考にしてください。

また、printfを使ってデータを読み込むという意味がよくわからないのですが、
データはどんな風に入っていますか?
1つのデータがちゃんと1つの配列に1つの文字列として入っていたら変換は簡単です。
もし12,3,45,6,7みたいにデータがまるごと配列にはいってて、それを変換するなら別途処理が必要です。
とりあえず

00,2A,3C....と入っていて、1行単位で丸ごと配列に入っているなら「,」の部分を\0に変換して沢山文字列があるように見せかける方法もあります。
必要ならそちらも紹介します。

フリオ

Re:16進数のデータをファイルから読込む

#3

投稿記事 by フリオ » 17年前

 
 データのフォーマットが固定なら、こんな方法もあります。
#include <stdio.h>

#define MAPSIZE 6

int main(void)
{
	FILE *fp = fopen("test.txt", "r");
	int hex[MAPSIZE][MAPSIZE], i, j;
	
	if(fp == NULL) return 1;
	for(i = 0; i < MAPSIZE; i ++){
		for(j = 0; j < MAPSIZE; j ++){
			fscanf(fp, "%x,", &hex[j]);
			printf("%02x ", hex[j]);
		}
		putchar('\n');
	}
	fclose(fp);
	return 0;
}



test.txt

00,2A,3C,4d,5e,6f
7a,8b,9c,ad,be,cf
d0,e1,f2,03,14,25
36,47,58,69,7a,8b
9c,ad,be,cf,d0,e1
f2,03,14,25,36,47

 

管理人

Re:16進数のデータをファイルから読込む

#4

投稿記事 by 管理人 » 17年前

最初から16進数で受け取ってよく、データの形がフリオさんのおっしゃる通り固定であれば、フリオさんのおっしゃる方法がいいと思いますが、私が書いた方法のサンプル書いたので一応紹介します。
これは特にファイルから読み込むとき以外にも使う方法なので、知ってて損は無いと思います。

文字列というのは、示したアドレスから終端記号が入っている所までをさすということを利用すればこんな使い方が出来ます。
#include <stdio.h>
#include <stdlib.h>

int main(){
	int i=0,j;
	char st[20]="7a,8b,9c,ad,be,cf,";

	while(st!='\0'){
		if(st==',') 
			st='\0';
		i++;
	}

	for(j=0;j<i;j+=3)
		printf("&st[%2d] - %s -> %x\n", j, &st[j], strtol(&st[j], NULL, 16));

	return 0;
}

実行結果

&st[ 0] - 7a -> 7a
&st[ 3] - 8b -> 8b
&st[ 6] - 9c -> 9c
&st[ 9] - ad -> ad
&st[12] - be -> be
&st[15] - cf -> cf




こんな感じで最初入っています。

[0]  [1]  [2]  [3]  [4]  [5]  [6]  [7]  [8]
----------------------------------------------
| 7  | a  | ,  | 8  | b  | ,  | 9  | c  | ,  |
----------------------------------------------
これをコンマを終端記号に置換すると
----------------------------------------------
| 7  | a  | \0 | 8  | b  | \0 | 9  | c  | \0 |
----------------------------------------------
 ↑              ↑             ↑              
こうなります。だから[0],[3],[6]のアドレスを示せばそこから終端記号までの文字列が示せるというわけです。

 

C言語はじめました

Re:16進数のデータをファイルから読込む

#5

投稿記事 by C言語はじめました » 17年前

 こんなにも早く回答をいただけるとは、感激です!!
 回答をみながら、自分が全く見当違いな思い込みをしていることに気が付きました。
 printfはただの表示用関数ですね。
 恥ずかしい!!!!
 今回はデータを16進数で書き、マップの大きさも固定にしているので、フリオさんの回答のように
fscanf関数で書き換えたら動きました。
 管理人さんとフリオさん、ありがとうございました。

管理人

Re:16進数のデータをファイルから読込む

#6

投稿記事 by 管理人 » 17年前

よかったですね。

>マップの大きさも固定にしているので、

別にマップの大きさは固定じゃなくても、大丈夫ですよ。
マップの大きさはがわればMAPSIZEを変えたら大丈夫です。
フリオさんのおっしゃるのは「フォーマットがちゃんと決まっているか」って事だと思います。
つまり、これはデータがあって、コンマがあって、データがあって、コンマがあって、
というぴったりこの通りの記述の仕方じゃないとうまくいかないからです。
まぁ突然コンマがピリオドになることも無いと思うのでこの方法がいいと思いますよ。

フリオ

Re:16進数のデータをファイルから読込む

#7

投稿記事 by フリオ » 17年前

 
 "strtol"を使うならこんな感じでしょうか。
#include <stdio.h>
#include <stdlib.h>

#define MAPSIZE 6
#define STRMAX 256

int main(void)
{
	FILE *fp = fopen("test.txt", "r");
	int hex[MAPSIZE][MAPSIZE], i, j;
	char *head, *end;
	char str[STRMAX];
	
	if(fp == NULL) return 1;
	for(i = 0; fgets(str, STRMAX, fp); i ++){
		head = end = str;
		for(j = 0; *end != '\n' && *end; j ++){
			hex[j] = strtol(head, &end, 16);
			printf("%02x ", hex[j]);
			head = end + 1;
		}
		putchar('\n');
	}
	fclose(fp);
	return 0;
}

 

閉鎖

“C言語何でも質問掲示板” へ戻る