txtファイルから2バイト文字込の文字列を格納したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
wasawasa
記事: 94
登録日時: 11年前

txtファイルから2バイト文字込の文字列を格納したい

#1

投稿記事 by wasawasa » 11年前

txtファイルからデータを取り込んで変数を初期化する関数として下記のような記述を書いたところ、79行目の記述でTileSet[n].nameに格納されるはずの2バイト文字を含む文字列が正常に代入されませんでした。恐らく48~75行目のtextcにtxtファイルの文を読み込む過程でおかしな事が起きているのだろうと思うのですが、その原因が分かりません。
何故文字列が正常に代入されないのか、どうしたら格納できるようになるのかどなたかご指摘をお願いします。
また、'\r'を読み込むことによる誤動作を防ぎたくて60~64行目の記述を加えたのですが、この部分を反映させるとtextc[0]が0になってしまうようなのでコメントアウトしています。こちらの理由もよろしければ一緒によろしくお願いします。

コード:

#define NameMaxSize 32//名前の最大文字数
#define NomalTipsMax 304//1枚のノーマルタイルセットのタイルの最大数

#define TileSetMax 4//タイルセットの種類
#define MapKindMax 5//マップの数

#define NAME_INICASE 0
#define ATILE_INICASE 1
#define NTILE_INICASE 8
#define PANORAMA_INICASE 9
#define FOGPIC_INICASE 10
#define FOGALP_INICASE 11
#define FOGBLE_INICASE 12
#define FOGZOM_INICASE 13
#define FOGSX_INICASE 14
#define FOGSY_INICASE 15
#define ATILEPRI_INICASE 16
#define NTILEPRI_INICASE 23

struct TileSetData{
	char name[NameMaxSize];//名前
	int ATileID[7];//オートタイルID
	int NTileID;//ノーマルタイルID
	int fog_alpha;//α値
	int fog_blend;//合成方法(0:通常,1:加算,2:減算)
	int fog_zoom;//拡大率
	int fog_sx,fog_sy;//スクロール速度
	int Apri[7];//オートタイルプライオリティ
	int Npri[NomalTipsMax];//ノーマルタイルプライオリティ
};
struct TileSetData TileSet[TileSetMax];
int panoramapic[MapKindMax];//パノラマ画像
int fogpic[MapKindMax];//フォグ画像

void TileSet_ini(){
	//txt読み込み用
    int file,i,n=0,m=0,ed=0;
    int text[NameMaxSize];
    char textc[NameMaxSize];
	//画像取り込み用
	char FPass1[] = "./Data/Pics/Fogs/";
	char FPass2[] = "./Data/Pics/Panoramas/";
	char Exten[] = ".png";
	char pass[64];
	//ファイル取り込み
	file = FileRead_open( "./Data/Txt/TileSetData.txt" ) ;
	if(file==NULL){printfDx("read error\n");return;}
	while(1){
		//ファイル読み込み
        for(i=0;i<NameMaxSize;i++){
            text[i] = FileRead_getc(file);
            textc[i] = text[i];
			//'/'なら改行
            if(textc[i]=='/'){
				while(FileRead_getc(file)!='\n'){
					i=-1;
					continue;
				}
			}
			/*//'\r'はスルー
			if(text[i]=='\r' ){
				i=-1;
				continue;
			}*/
			//コンマか改行なら読み込み停止
            if(text[i]==',' || text[i]=='\n'){
				textc[i]='\0';
				break;
			}
			//文章が終わったら関数終了
            if(text[i]==EOF){
				ed=1;
				break;
			}
        }
		if(ed==1){FileRead_close(file);break;}
		//取り込んだ文字列をデータとして格納
		if(m==NAME_INICASE){
			strcpy(TileSet[n].name,textc);
		}
		else if(m>=ATILE_INICASE && m<NTILE_INICASE){
			TileSet[n].ATileID[m-ATILE_INICASE] = atoi(textc);
		}
		else if(m==NTILE_INICASE){
			TileSet[n].NTileID = atoi(textc);
		}
		else if(m==PANORAMA_INICASE){
			if(strcmp(textc,"nil")==0){panoramapic[n]=MakeGraph( 640 , 480 ) ;}
            else{
                strcpy(pass,FPass2);strcat(pass,textc);strcat(pass,Exten);
                panoramapic[n] = LoadGraph(pass);
                memset(pass, 0, sizeof(pass));
            }
		}
		else if(m==FOGPIC_INICASE){
            if(strcmp(textc,"nil")==0){fogpic[n]=MakeGraph( 640 , 480 ) ;}
            else{
                strcpy(pass,FPass1);strcat(pass,textc);strcat(pass,Exten);
                fogpic[n] = LoadGraph(pass);
                memset(pass, 0, sizeof(pass));
            }
		}
		else if(m==FOGALP_INICASE){
			TileSet[n].fog_alpha = atoi(textc);
		}
		else if(m==FOGBLE_INICASE){
			TileSet[n].fog_blend = atoi(textc);
		}
		else if(m==FOGZOM_INICASE){
			TileSet[n].fog_zoom = atoi(textc);
		}
		else if(m==FOGSX_INICASE){
			TileSet[n].fog_sx = atoi(textc);
		}
		else if(m==FOGSY_INICASE){
			TileSet[n].fog_sy = atoi(textc);
		}
		else if(m>=ATILEPRI_INICASE && m<NTILEPRI_INICASE){
			TileSet[n].Apri[m-ATILEPRI_INICASE] = atoi(textc);
		}
		else if(m>=NTILEPRI_INICASE && m<NTILEPRI_INICASE+NomalTipsMax){
			TileSet[n].Npri[m-NTILEPRI_INICASE] = atoi(textc);
			if(m==NTILEPRI_INICASE+NomalTipsMax-1){
				m=0;
				n++;
				continue;
			}
		}
        m++;
	}
}

アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: txtファイルから2バイト文字込の文字列を格納したい

#2

投稿記事 by h2so5 » 11年前

57行目のcontinueは55行目に戻るだけなので意味がないですね。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: txtファイルから2バイト文字込の文字列を格納したい

#3

投稿記事 by softya(ソフト屋) » 11年前

前回の「デバッガで確認しましょう」に返事がなかったのですがちゃんと使われていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

wasawasa
記事: 94
登録日時: 11年前

Re: txtファイルから2バイト文字込の文字列を格納したい

#4

投稿記事 by wasawasa » 11年前

>h2so5さん
ご指摘ありがとうございます。下記のように訂正しました。

コード:

				while(FileRead_getc(file)!='\n');
				i=-1;
				continue;
>softyaさん
ご返事遅れてすみません。
気になる場所にブレークポイントを設定して変数を確認するという事はやっています。
それがデバッガでの確認作業といえないならやっていないと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: txtファイルから2バイト文字込の文字列を格納したい

#5

投稿記事 by softya(ソフト屋) » 11年前

> 気になる場所にブレークポイントを設定して変数を確認するという事はやっています。

h2so5さんの指摘したcontinueとかステップ実行すると見つかる問題だと思うのですが、ステップ実行されていないのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

wasawasa
記事: 94
登録日時: 11年前

Re: txtファイルから2バイト文字込の文字列を格納したい

#6

投稿記事 by wasawasa » 11年前

>softya
ステップ実行について調べてみました。
こういう機能がある事を知りませんでした。次から活用していきたいと思います。

それで、この機能を使って文字列の格納処理を見てみたところ、51行目と52行目の処理を1回目に実行した時点で既に変な文字が格納されている事が分かりました。
2バイト文字であってもFileRead_getc関数で1バイトずつ格納していけば文字として正しい値になる筈だと思うのですが……
それともtextとtextcの方に何か問題があるのでしょうか?

かずま

Re: txtファイルから2バイト文字込の文字列を格納したい

#7

投稿記事 by かずま » 11年前

wasawasa さんが書きました: txtファイルからデータを取り込んで変数を初期化する関数として下記のような記述を書いたところ、79行目の記述でTileSet[n].nameに格納されるはずの2バイト文字を含む文字列が正常に代入されませんでした。恐らく48~75行目のtextcにtxtファイルの文を読み込む過程でおかしな事が起きているのだろうと思うのですが、その原因が分かりません。
2バイト文字を含む文字列とは具体的に何ですか?
textc に入った値は何ですか? 16進のバイト列でお願いします。
wasawasa さんが書きました: また、'\r'を読み込むことによる誤動作を防ぎたくて60~64行目の記述を加えたのですが、この部分を反映させるとtextc[0]が0になってしまうようなのでコメントアウトしています。こちらの理由もよろしければ一緒によろしくお願いします。
i = -1; で continue; すると、for の i++ で i が 0 になり、
次の入力文字 '\n' により textc[0] は '\0' になります。
i = -1; ではなく、i--; にしてみてください。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: txtファイルから2バイト文字込の文字列を格納したい

#8

投稿記事 by softya(ソフト屋) » 11年前

2バイト文字の1バイト目だけ格納した状態なら変だと思います。
16進数の数値レベルで変な値なのでしょうか?
ここにコピペしてみてください。
※ デバッガの使いかたの練習を兼ねております。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

wasawasa
記事: 94
登録日時: 11年前

Re: txtファイルから2バイト文字込の文字列を格納したい

#9

投稿記事 by wasawasa » 11年前

>かずまさん
60~64行目の記述のご指摘ありがとうございます。
i = -1; をi--;に変更したところ、TileSet[n].name[0]から無事に文字列が格納されるようになりました。ありがとうございます。

そして51行目と52行目でtextcに格納される文字列についてですが、
格納しようとした文字列は「森の町 外観」、
1回目の51行目の処理でtext[0]に格納された数値は0xffffffe6、52行目の処理でtextc[0]に格納された数値は0xe6 '・'、
2回目の51行目の処理でtext[1]に格納された数値は0xffffffa3、52行目の処理でtextc[1]に格納された数値は0xa3 '」'、
ここまでのtextcで表現される文字列が
「0x013dfb50 "譽フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ・」フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ"」
となっており、1文字目に入っている漢字に全く覚えがなかったため変な値として判断しました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: txtファイルから2バイト文字込の文字列を格納したい

#10

投稿記事 by softya(ソフト屋) » 11年前

私のところでは0x90,0x58の順で格納されます。

環境
TileSetData.txはshift-jisコードです。プロジェクトはマルチバイト文字に設定、VS2008使用。Windws7 64bitです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
へにっくす
記事: 634
登録日時: 13年前
住所: 東京都

Re: txtファイルから2バイト文字込の文字列を格納したい

#11

投稿記事 by へにっくす » 11年前

wasawasa さんが書きました:ここまでのtextcで表現される文字列が
「0x013dfb50 "譽フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ・」フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ"」
となっており、1文字目に入っている漢字に全く覚えがなかったため変な値として判断しました。
C言語では変数を宣言する際、下記のように初期化しないと、上のように不定の値が入っています。
全く覚えがない値が入ってる=初期化していない!!と覚えてください。

コード:

char textc[NameMaxSize] = {0}; // 全部0で埋める
written by へにっくす

かずま

Re: txtファイルから2バイト文字込の文字列を格納したい

#12

投稿記事 by かずま » 11年前

"森の町 外観" という文字列は、文字コードが
Shift-JIS だと、90 58 82 cc 92 ac 20 8a 4f 8a cf。
UTF-8 だと、e6 a3 ae e3 81 ae e7 94 ba 20 e5 a4 96 e8 a6 b3。
スペースは シングルバイト文字で、20 です。
UTF-8 では、漢字やひらがなが 3バイトです。

ファイルの先頭 2バイトが e6 a3 だということは、そのファイル
の文字コードは、UTF-8 です。
どうやって作りましたか?

nkf などのツールを使ってコード変換してみてください。

なお、メモ帳(notepad.exe)は、コードの自動判定をしているようで
どちらのファイルも開けるようです。
名前を付けて保存するときに、文字コードの指定ができます。
ANSI にすると、Shift-JIS (cp932)。
UTF-8 にすると、UTF-8 です。

wasawasa
記事: 94
登録日時: 11年前

Re: txtファイルから2バイト文字込の文字列を格納したい

#13

投稿記事 by wasawasa » 11年前

皆さん返信ありがとうございます。
かずまさんのご指摘を受けて気になったのでtxtファイルの生成方法を調べた結果、txtファイル自体に問題がある事が分かりました。
txtファイルはrgssというrubyを拡張して作られた言語によるプログラムで生成しており、rgssがデフォルトの設定で取り扱っている文字コードがutf-8であったためにtxtファイルの文字コードがutf-8になってしまったという事が分かりました。なので、rgssで取り扱う文字コードをShift-JISに変更する方法を調べてみたいと思います。
これ以上の質問はこの掲示板の意向に反してしまうと判断し、このトピックを解決済みとしたいと思います。
皆さん、数々のアドバイスをありがとうございました。

閉鎖

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