ページ 1 / 1
エクセルで文字列読み込み
Posted: 2014年9月08日(月) 22:34
by namari
http://dixq.net/rp/11.html
を参考に会話イベントをすべてCSVの中に収めたいです。
そのために、上記のアドレスを改変して、以下のように書いたところをデバッガで確認すると、
文字化けした文字列しか取得できていません。
コード:
//load.cpp
(これより前は貼ったアドレスのまま)
switch(num){
case 0: sprintf(happening[happ_num].message[n].mess,"%s",inputc);
case 1:...
//struct.h
typedef struct{
char mess[MESS_MAX];//メッセージ本体
(その他いろいろな変数)
}message_t;
typedef struct{
message_t message[MESSAGE_MAX];//そのメッセージのイベント会話順
}happening_t;
上記アドレスは数字しか取得していないので、多分このコードだと文字列は対象外なのでしょうが、バグが出る理由がイマイチわかりません。
happening[happ_num].message[1]以降で明らかに読み込み場所がずれているので、
happening[happ_num].message[0].mess部分読み込み時に途中で区切ってしまったのでしょうか・・・。
それとも文字型と文字列型がごっちゃになっているとかでしょうか
ちなみにセルに入っている文字列は"ここにはメッセージが表示されます"です。
Re: エクセルで文字列読み込み
Posted: 2014年9月08日(月) 22:58
by みけCAT
文字化けする原因はまだよくわかりませんが、とりあえず本番のコードではきちんとsprintfの後にbreak;を入れていますか?
あと、この場合はsprintfではなくlstrcpyAを使えばいいと思います。
Re: エクセルで文字列読み込み
Posted: 2014年9月08日(月) 23:12
by namari
みけCAT さんが書きました:文字化けする原因はまだよくわかりませんが、とりあえず本番のコードではきちんとsprintfの後にbreak;を入れていますか?
あと、この場合はsprintfではなくlstrcpyAを使えばいいと思います。
あっbreak;は入ってます。コピーし損ねてましたね。
コード:
case 0: lstrcpyA(happening[happ_num].message[n].mess,inputc); break;
こうしてみましたが結果は変わらなかったです・・・。
Re: エクセルで文字列読み込み
Posted: 2014年9月08日(月) 23:20
by みけCAT
試しに以下のコードをgcc 4.8.1でコンパイルし、実行したところ、出力は期待したとおりでしたが、
デバッガ(GDB 7.6.1)で85行目でbreakし、happening[happ_num].message[0].messをprintしたところ、文字化けが確認されました。
デバッガだけに頼らず、printfDxなど他の方法でデータを確認してみてください。
また、問題の切り分けのために、半角(ASCIIに含まれる)文字のみのメッセージでテストしてみてください。
コード:
#include <cstdio>
#include <cstdlib>
FILE* hack_file;
int FileRead_open(const char* fname) {
hack_file = fopen(fname, "r");
if (hack_file == NULL) return 0;
return 1;
}
int FileRead_getc(int) {
return getc(hack_file);
}
void FileRead_close(int) {
fclose(hack_file);
}
void printfDx(const char* str) {
fputs(str, stdout);
}
const int MESS_MAX = 128;
const int MESSAGE_MAX = 1000;
typedef struct{
char mess[MESS_MAX];//メッセージ本体
char hoge[MESS_MAX];
int fuga;
char foo[MESS_MAX];
}message_t;
typedef struct{
message_t message[MESSAGE_MAX];//そのメッセージのイベント会話順
}happening_t;
happening_t happening[1];
const int happ_num = 0;
void load_story(){
int n,num,i,fp;
char fname[32]="test.csv"; //{"../dat/csv/storyH0.csv"};
int input[64];
char inputc[64];
fp = FileRead_open(fname);//ファイル読み込み
if(fp == NULL){
printfDx("read error\n");
return;
}
for(i=0;i<2;i++)//最初の2行読み飛ばす
while(FileRead_getc(fp)!='\n');
n=0 , num=0;
while(1){
for(i=0;i<64;i++){
inputc[i]=input[i]=FileRead_getc(fp);//1文字取得する
if(inputc[i]=='/'){//スラッシュがあれば
while(FileRead_getc(fp)!='\n');//改行までループ
i=-1;//カウンタを最初に戻して
continue;
}
if(input[i]==',' || input[i]=='\n'){//カンマか改行なら
inputc[i]='\0';//そこまでを文字列とし
break;
}
if(input[i]==EOF){//ファイルの終わりなら
goto EXFILE;//終了
}
}
switch(num){
case 0: sprintf(happening[happ_num].message[n].mess,"%s",inputc);break;
case 1: sprintf(happening[happ_num].message[n].hoge,"%s",inputc);break;
case 2: happening[happ_num].message[n].fuga=atoi(inputc);break;
case 3: sprintf(happening[happ_num].message[n].foo,"%s",inputc);break;
}
num++;
if(num==4){
num=0;
n++;
}
}
EXFILE:
FileRead_close(fp);
}
int main(void) {
load_story();
for (int i = 0; i < MESSAGE_MAX; i++) {
if (happening[happ_num].message[i].hoge[0] == '\0') break;
printf("no = %d\n", i);
printf("mess = %s\n", happening[happ_num].message[i].mess);
printf("mess = %s\n", happening[happ_num].message[i].hoge);
printf("fuga = %d\n", happening[happ_num].message[i].fuga);
printf("foo = %s\n", happening[happ_num].message[i].foo);
puts("----------");
}
return 0;
}
※このコードはDXライブラリを使用しません
Re: エクセルで文字列読み込み
Posted: 2014年9月08日(月) 23:36
by namari
>>みけCATさん
>また、問題の切り分けのために、半角(ASCIIに含まれる)文字のみのメッセージでテストしてみてください。
半角文字だけの文字列では読み込まれました!
ユニコードが読めてないんですかね。
文字列のどこかでセルが終了したと誤って読まれてしまっていたとかでしょうかね・・・
Re: エクセルで文字列読み込み
Posted: 2014年9月08日(月) 23:45
by みけCAT
namari さんが書きました:ユニコードが読めてないんですかね。
文字列のどこかでセルが終了したと誤って読まれてしまっていたとかでしょうかね・・・
内容はDXライブラリ(と推測)でCSVファイルを読みこむ話なのに、
タイトルが「エクセルで文字列読み込み」である時点で用語の理解が自分とは同じではない気がしますが、
もし「ユニコード」が文字コードのUnicodeのことであれば、プログラムが理解できていない可能性があります。
読み込むファイルをテキストエディタかnkfなどでShift_JISに変換してから読み込んでみてください。
Re: エクセルで文字列読み込み
Posted: 2014年9月09日(火) 00:02
by namari
すみません。最初に
>happening[happ_num].message[1]以降で明らかに読み込み場所がずれているので、
と書きましたが、これは別の問題でした。一行読み込みを終えるのを
コード:
if(num==18){
num=0;
n++;
}
のままにしていました。
自分の変数数と同じにしたらズレはなくなりました。
文字読み込みの文字化けもなくなりました・・・。
ズレのせいで読み込み位置がおかしかったのでしょう。
文字列の苦手意識のせいかかなり視野が狭まっていたようです。
みけCATさんありがとうございました。
>内容はDXライブラリ(と推測)でCSVファイルを読みこむ話なのに、
>タイトルが「エクセルで文字列読み込み」である時点で用語の理解が自分とは同じではない気がしますが、
csvファイル=エクセルと思ってました・・・。
あとそもそもタイトルの助詞からしておかしいですね。せめてエクセルからですね。