• ベストアンサー

Unicodeのファイル読み込みがうまくいきません。。

下のようなコードで読もうとしているんですが、どうしても文字化けしてしまいます。原因が何なのかさっぱりわかりません。。 分かる方どうかお願いします!開発環境はVC++.NETです。 FILE* fin; wchar_t c; CString ss; if( (fin = fopen( "temp.txt", "r" )) == NULL ){ AfxMessageBox("temp.txtファイルオープンエラー"); exit(1); } fgetws( &c, 2, fin ); ss += c; AfxMessageBox(ss);

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

fgetwsを呼び出す前に、setlocale(LC_CTYPE, "");を実行してください。 それともう一点、cは1文字しか格納できないのに、サイズに2を指定しているのは間違いです。

exmotions
質問者

お礼

上記問題解決しました。直接int値入れました、、、が、、 解決しません。。

exmotions
質問者

補足

回答ありがとうございます。 最初はサイズ1を指定していたんですが、 2にしないとなぜかうまく動かないので。。 マルチバイト文字のせいでしょうか? >fgetwsを呼び出す前に、setlocale(LC_CTYPE, "");を実行してください。 必要な物はインクルードしたんですが、LC_CTYPEが未定義識別子になってしまいます。。

その他の回答 (4)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.5

もし、UTF-16のファイルを読もうとしているのであれば、fgetwsやfgetwcを使うのは不適当です。これらの関数は、あくまでも多バイト文字で格納されたファイルを読み込むためのものだからです。 UTF-16を扱いたいのであれば、バイナリモードで読み込む必要があります。

exmotions
質問者

お礼

ご回答ありがとうございます。 文字コードはUnicodeです。

exmotions
質問者

補足

皆様ご助力ありがとうございました。 なんとか解決することができました。 お返事が遅くなって大変申し訳ないです。 これにて質問を締め切らせて頂きます。

  • buihyaku
  • ベストアンサー率29% (97/326)
回答No.4

参考情報ですが、16ビットユニコードテキストは先頭にBOMと呼ばれる識別子が挿入されます。 これはビッグエンディアンとリトルエンディアンを区別するためのものでFFEFまたはFFFEのいずれかになります。 http://www.atmarkit.co.jp/aig/01xml/bom.html 読み込んだデータの先頭にでてきている" FF FE "はこのBOMデータだとおもいますので読み飛ばして処理されるとよいかとおもいます。

exmotions
質問者

お礼

ご回答ありがとうございます。 最初の2バイトはデータとは関係ないんですね。。 ありがとうございます!

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.3

> 最初はサイズ1を指定していたんですが、 > 2にしないとなぜかうまく動かないので。。 fgetwsは文字列を読み込む関数だからです。文字を読み込むのであれば、fgetwcを使うとよいでしょう。 > 必要な物はインクルードしたんですが、LC_CTYPEが未定義識別子になってしまいます。。 <locale.h>をインクルードしましたか?

exmotions
質問者

補足

夜分遅くにほんとうにありがとうございます。 >fgetwsは文字列を読み込む関数だからです。文字を読み込むのであれば、fgetwcを使うとよいでしょう。 こっちの方が引数が少なくて良いですね! ><locale.h>をインクルードしましたか? しましたが、未定義のままでした。強引に整数入れて解決しましたが、原因はよく分かりません(汗 文字は相変わらずですが、少し進展?がありました。 プロジェクトの設定で文字コードを"Unicodeを使用する"にしたところ、 バイナリのFFがyの上にちょんちょんがついた文字でダイアログに出てきました。 CStringが、なにか悪さしてるんでしょうかねぇ。。。

  • xcrOSgS2wY
  • ベストアンサー率50% (1006/1985)
回答No.1

ファイル内のバイナリデータと、読み込み後の変数に格納されたバイナリデータを比較し、変数への格納自体はプログラムの意図どおり成功しているのか、それとも変数への格納自体に失敗しているのかをまず補足願います。

exmotions
質問者

補足

ご回答ありがとうございます。 バイナリエディタで自動変数と比較したところ、 数値は合っていました。 FF FE 3C → 255 254 60 でした。ということはCStringへの代入がおかしいという事なんでしょうか。。

関連するQ&A

  • 文字列の比較について

    99としか書いてないファイルxxx.txtが有り、以下のようにして読み込みました。 char aaa[256]; if((fin=fopen("c:\\xxx.txt","r"))==NULL){ AfxMessageBox("読み込みファイルオープン出来ません"); return TRUE; } while((fgets(aaa,256,fin))!=NULL){ } fclose(fin); そしてstrcmpで比較したところ、1が返り等しくないと判定されます。 strcmp(aaa,"99") どうすれば等しいと判定できるようになりますか?

  • コマンドラインから引数を渡すことについて

    ----------------------------------------------- #include<stdio.h> #include<stdlib.h> int main(int argc,char *argv[ ]) { FILE *fin,*fout; char ss[256]; if(argc != 3){ printf("引数の数が違います\n"); exit(1); } if((fin=fopen(argv[1],"r"))==NULL){ printf("入力ファイルをオープンできません\n"); exit(1); } if((fout=fopen(argv[2],"w"))==NULL){ printf("出力ファイルをオープンできません\n"); exit(1); } while(fgets(ss,256,fin)!=NULL){ fputs(ss,fout); } fclose(fin); fclose(fout); return 0; } ----------------------------------------------- 以上のプログラム名は「tcopy.cpp」でコマンドプロンプトから実行し、ファイルをコピーするという事を行っていきます。 「aaa.txt」と「bbb.txt」の2つを用意し、「aaa.txt」の内容、 abcdef ABCDEF 012345 を「bbb.txt」にコピーしていきます。 そこで疑問なのですが、ファイルをコピーする際、コマンドプロンプトから、 >tcopy aaa.txt bbb.txt と打ち込むとコピー出来るようであり、「tcopy」、「aaa.txt」、「bbb.txt」が引数になるという事なのですが、何故この3つが引数になるのかという事と、 int main(int argc,char *argv[ ]) のargcに引数が何故代入されるかが分かりません。 後、「aaa.txt」と「bbb.txt」がargv[1]とargv[2]に何故対応しているかが分かりません。 教えていただければ嬉しいです。

  • UNICODEファイルが文字化けする

    どうしてもうまくいかず質問致します。 Visual Studio2008のMFCで、下記のコードでUnicodeファイルを読み込むと、文字化けします。  なぜでしょうか? 文字セットは、Unicodeにしています。 ログを調べているとsetlocaleや_wsetlocaleを使うとうまくいっているようですが、この環境では 解決しません。 CFileDialog seldel(TRUE, NULL,NULL, OFN_HIDEREADONLY,NULL); if(seldel.DoModal()==IDOK) { CString cpath=seldel.GetPathName(); CStdioFile cFile; cFile.Open(cpath,CFile::modeRead | CFile::shareDenyNone);// == FALSE) CString cs, cs_all; while(cFile.ReadString(cs)==TRUE) { cs_all+=cs; } ::AfxMessageBox(cs_all); } どうぞよろしくお願い致します。

  • Cで二次元配列の読み込み

    はじめまして。 hiraです。 今非常に基本的であろうことに悩んでいます。まだまだプログラムを始めたところなのでうまくいきません。 内容は・・・ あるファイルを読み込んで、二次元の配列に格納していく。 です。 具体的には test.txtというファイルがあり、中身は数字の二次元配列です。 カンマやtabで区切られています。配列の大きさ、数字の桁数などはファイルによって違います。 そのファイルを読み込んで、配列に格納したいと考えています。 今は一列を読み込むことには成功しています。そこからどのようにして分けて言ったらいいのか・・・ご教示お願いします。 もしくは、もっと違う方法で読み込む方法があればよろしくお願いします。 #include <stdio.h> #include <stdlib.h> int main(void) { FILE *fin; char array[256]; char buf[256]; fin=fopen("test.txt","r"); if(fin == NULL){ printf("%sがオープンできません\n",fin); exit(1); } while(fgets(buf,256,fin) != NULL) {           ここが問題・・・ } fclose(fin); return 0; }

  • fprintfで出力するファイルのパス指定について

    cで以下のコードを書いています。 file.txtを任意の場所に作りたいのですが どうすればいいのでしょうか。 fopen("c:\file.txt", "r"))と書くとエラーになって しまいました。 void main(void) { FILE *fp; if ((fp = fopen("file.txt", "r")) == NULL) { fprintf ( stderr, "err\n" ); exit (2); } fprintf(fp,"%s\n",a);; fclose(fp); }

  • MATLABのファイル読み込みに関して

    こんにちは,今回MATLABでのファイル読み込みに関して質問したいことがあり書き込みました 現在in_1-C110.txt,in_1-C120.txt,......in_1-C190.txt'というファイルがあり,これらのファイルをまとめて読み込もうとして以下のようなコードを記述しました for a=1:9 %ファイルを読む fin=fopen(['in_1-C1' a '0.txt'],'r');     %a A=fscanf(fin,'%f %f %f %f %f %f %f',[7 inf]); fclose(fin); (略) end このように,ファイル名の最初と最後は共通なので,異なる部分のみをループさせて連続して読もうとしています ところが,この方法だとInvalid fid.と出てしまいます 調べてみると、意図したものでは%aのところが in_1-C110.txt in_1-C120.txt となるはずだったのですが,fscanfを抜いてこのファイル名のところだけ書き出すようにしてみると in_1-C1(変な文字)0.txt in_1-C1(変な文字)0.txt といったような変数の部分が文字化けを起こしていることがわかりました. したがって,ファイルが読めない原因がこれにあるのだと推察したのですが,解決方法がまったくわからない状態です この問題を解決する方法がわかる方がおられましたら,教えていただけないでしょうか?

  • 新規でファイルを作成したい

     お世話になっております。  PHPで新規でファイルを作成する方法がうまくいかないのでおしえてください。  fopen関数で、ファイルを開こうとするとき解説書にあるように、「ファイルがなければ新規で作成」というモードを使用しているのですが、このファイルが作成されません。  新規でファイルを作成するモードは、"w" "a" "a+"の筈ですが…。 $temp_file_open = fopen("temp.txt", "w"); flock($temp_file_open, LOCK_EX); $temp_return = fputs($temp_file_open, "$name\n"); flock($temp_file_open, LOCK_UN); fclose($temp_file_open);  このような形で単純に書いているのですが、なかなかうまく行きません。Perlではumaskの設定などが必要ですが、PHPでも必要なのでしょうか?  もし足りない点、または初心者が陥りやすい点を指摘していただけるとありがたいです。

    • ベストアンサー
    • PHP
  • ファイルの入出力を行って文字を変換する

    入力するファイルにa~zを記入しておき、 出力するファイルにaなら1、bなら2、zなら26に変換させたいのですがどうしたらよいでしょうか? #include <stdio.h> #include <string.h> #define DELIMITER "/ ," /* 区切り文字 */ int main(void) { FILE *fin,*fout; int count=0; int i; char s[256], s2[256]; char alpha[]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'}; int kazu[]={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26}; char *taken; char *strch[50]; if( (fin=fopen("file1.txt","r"))==NULL) { printf("入力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } if( (fout=fopen("file2.txt","w"))==NULL) { printf("出力ファイルがオープンできません\n"); exit(EXIT_FAILURE); } while(fgets(s,256,fin)!=NULL) { while (token != NULL) { strch[count]=token; token = strtok(NULL, DELIMITER); count++; } memset(s2, NULL, sizeof(s2)); fprintf(fout,"%d\n",s2); } fclose(fin); fclose(fout); return 0; }

  • 標準出力をDOS窓を開かずにファイルに書き込む方法

    VC++(Console Appli)です。 あるコマンドの標準出力結果をファイルに吐き出す方法として、 単純には、 system("cmnd > C:\\temp.txt"); とやれば実現できますが、このとき、一瞬ですが、DOS窓の黒枠が表示されます。 このDOS窓を出さないで済む方法があれば教えてください。 標準出力を何らかの方法で受け取って、 ------------------------------------------------- CString str; CStdioFile file;   :  cmndの標準出力結果をstrへ内部的に受け取らせる。   : file.Open(_T("c:\\temp.txt"), CFile::modeWrite); file.WriteString(str); file.Close(); ------------------------------------------------- などで簡単に出来れば良いのですが・・よろしくお願いします。

  • fortran77で複数のファイルの読み込み

    fortran77で複数のファイルの読み込み 現在fortran77のプログラムを勉強しております。 ファイルが複数あり、すべてのファイルを読み込みたいのですが、ファイルの数がたくさんあるため、プログラムの行数が多くなってしまいます。 do ループで次々とファイルを開くプログラムを考えているのですが、思いつきません。 どなたか考え方でもいいので、教えてください。 ちなみに私が考えたプログラムは、 open(10,file='C:\FORTRAN\100.txt',status='old') open(11,file='C:\FORTRAN\121.txt',status='old') open(12,file='C:\FORTRAN\144.txt',status='old') open(13,file='C:\FORTRAN\169.txt',status='old') open(14,file='C:\FORTRAN\196.txt',status='old') open(15,file='C:\FORTRAN\225.txt',status='old') ・・・。 これを do ループで次々に開くことを考えると、 character*3 A(10) do 100 i=1,10 A=i*i open(i,file='C:\FORTRAN\A.txt',status='old') 100 continue ・・・ みたいな感じです。 ' 'の中の一部だけを変えたい場合のcharacter 文の使い方がいまいちよく分かりません。

専門家に質問してみよう