• 締切済み

Windowsプログラミングでのテキスト保存について

Windowsプログラミングでのテキスト保存について エディットコントロールに入力された文字列を取得しGlobalAlloc関数などを使いメモリを確保し CreateFile関数、WriteFile関数を使ってテキストファイルを作成するプログラムを書いたのですが マルチバイト文字でコンパイルした場合とUnicode文字でコンパイルした場合とでファイルの中身の 表示結果が異なってしまいます。 例えば ナンバーは 12 34 56 78 です。 日付 00/00 00:00:00(改行)←1行目 ナンバーは 34 56 78 90 です。 日付 00/00 00:00:00(改行)←2行目 とエディットコントロールに入力されていたものをテキストファイルに書き込むと、 Unicode文字でコンパイルしたプログラムの場合 ナンバーは 12 34 56 78 です(改行)などと途中までしか書き込まれていなかったり あるいは2行中初めの1行しか書き込まれていなかったりします。 このプログラムをマルチバイト文字でコンパイルするとエディットコントロールに入力されたとおりに ファイルに書き込まれるようです。コンパイル時どちらも構文エラーはでません。 自分なりに文字の取得方法やメモリ関係やワイド文字関連の事情などをいろいろ試してみたのですが、いまだに解決していません。分かる人がいましたらどうか教えてください。お願いします。 ちなみにエディットコントロールは複数行入力スタイルでEM_SETSEL、EM_REPLACESELで追記されていく、出力のみ可能という設定です。

みんなの回答

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.2

ステップ実行などで、各場所で正しく取得できているか? とか確認された方がよいでしょう。 >WriteFile(hFile,lpszBuf,(DWORD)lstrlen(lpszBuf),&dwAccBytes,NULL); lstrlen()が返却するのは「TCHAR単位での文字数」ですが…。 http://msdn.microsoft.com/ja-jp/library/cc410906.aspx UNICODEで"書き込みテスト"をlstrlen()で取得すると、7「文字」となります。 対して、WriteFile()の第3引数は「書き込み対象のバイト数」です。 "書き込みテスト"から7バイト書き込んだら…正しくないですよね? http://msdn.microsoft.com/ja-jp/library/cc429856.aspx >hMem=GlobalAlloc(GHND,((sizeof(TCHAR))*(nLen)+2)); hMem=GlobalAlloc(GHND,(sizeof(TCHAR)*(nLen+1))); が妥当かと… # 後から見た時、"+2ってなに? 終端コード分なら+1じゃん。"と修正されて不具合盛り込む可能性があります。 >GetWindowText(hEdit1,lpszBuf,nLen+2); 確保したサイズより大きいサイズを渡しています。 # 事前にWM_GETTEXTLENGTHで取得して、終端コード分のメモリも取っているのでオーバーランはしないと思われますが…

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>エディットコントロールに入力された文字列を取得しGlobalAlloc関数などを使いメモリを確保し >CreateFile関数、WriteFile関数を使ってテキストファイルを作成するプログラムを書いたのですが 具体的にどういうコード書いていますか? UNICODE文字セットの場合、APIが返却するのは「文字数」ですが、そのヘン間違えていませんか? dwLength = GetWindowTextLength(hEdit); lpSitring = (LPSTR)GlobalAlloc(GPTR, dwLength + 1); GetWindowText(hEdit, lpSitring, dwLength); WirteFile(hTextFile, lpSitring, dwLength, NULL, NULL); って感じであれば、MBCSではちゃんと動くでしょうがUNICODEではちゃんと動きません。

sonicell39
質問者

補足

nLen=(SendMessage(hEdit1,WM_GETTEXTLENGTH,0,0)); hMem=GlobalAlloc(GHND,((sizeof(TCHAR))*(nLen)+2)); lpszBuf=(_TCHAR*)GlobalLock(hMem); GetWindowText(hEdit1,lpszBuf,nLen+2); OPENFILENAME構造体に必要情報をセット。 if(GetSaveFileName(&ofn)==0) return-1; hFile=CreateFile(szFile,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); WriteFile(hFile,lpszBuf,(DWORD)lstrlen(lpszBuf),&dwAccBytes,NULL); ファイルハンドルを閉じメモリのロック解除と解放。というようなコードです。 私も以前文字列取得時のことを調べたのですが Unicodeの場合はバイト数ではなく文字数が返されるという情報がありました。 Unicodeに対応させたいと思いいろいろ試しているのですが、これまでうまくいっていないという 状況です。この場合Unicodeに対応させるにはどうすればいいのかどうか教えてください。 お願いします。

関連するQ&A

  • MFC:リッチエディットからUnicode文字列を受け取りたい

    MFCのダイアログベースでプロジェクトを作成 ↓ プロジェクトのプロパティで「マルチバイト文字セットを使用する」を「Unicode文字セットを使用する」に変更 ↓ エディットボックスとリッチエディット2.0を適当に配置 ↓ エディットボックスとリッチエディット2.0それぞれにコントロール変数を追加 ↓ InitInstance()内に AfxInitRichEdit2(); を追加 ↓ あとは適当なところでエディットボックスとリッチエディット2.0それぞれにGetWindowText関数を使って、記入内容を取得します。     すると、エディットボックスではUnicodeの文字を入れても文字化けしないのに対し、リッチエディット2.0では文字化けしてしまいます。 例えば“Å”の半角文字を(Unicode紹介サイトからコピペする等して)入力すると、エディットボックスではそのまま“Å”なのに、リッチエディット2.0では“A”になります。   ※入力している段階では“Å”と表示されています。GetWindowText関数で取得すると“A”になってしまいます。     リッチエディット2.0からUnicode文字を正常に受け取れる方法はありませんでしょうか。

  • Windowsプログラミングでのテキスト保存について

    Windowsプログラミングでのテキスト保存について WindowsAPIを使ってプログラミングをしているのですがコントロールに入力されたテキストを 保存するときにWindows付属のメモ帳のように保存ダイアログボックス上で保存文字コードを 選択できるようにしたいのですがやり方わかる人いましたらどうか教えてください。お願いします。

  • テキストをPDFに。

    現在、Macを使用しています。Windowsもあります。 テキストエディット(メモ帳)に入力した文字をPDFにしたいです。 ただ、しかし。 普通にPDFにする方法はMacの場合プリントからPDFを選択すると可能ですが、 一行に42文字とか40文字でPDFにしたい場合、どのようにすると良いのか分かりません。 ひょっとしてテキストエディットで一行一行改行作業が必要なのでしょうか? 永遠とまでは言わないまでも、段落がずっと続いてかなり面倒で文章も多いです。 なにか良い方法はありませんでしょうか?

  • 改行を含まない文字数を取得するには?

    エディットボックスに入力された文字数をGetWindowTextLength関数で取得した時 < 例 >  aaaaああああいいいい と入力した場合 結果は12 aaaa ああああ いいいい    と入力した場合 結果は16 というように同じ文字数なのに改行を含むと改行1につき2文字分多くカウントされてしまいます。 複数行入力されていても改行文字を含まない文字数を取得するにはどうすればいいですか? --- 実行環境 --- Visual Studio 2010 Express WIN32 ユニコードビルド C言語

  • ファイルの入出力でのテキスト モードでの変換について

    今までとりあえずサクサク骨組み作りたいので、短くかけるためマルチバイト文字主体で来たのですが ここらへんでUnicode文字のことが気になってきたので、以下のような関数を基本にしてプロパティやコードをいじったりしつつ入出力を色々試してみたのですが… (エラー時の処理とか省略します。) #include <TCHAR.h> #include <stdio.h> #include <locale.h> #ifdef _UNICODE #define 文字セット "Unicodeを使用" #else #define 文字セット "マルチバイトを使用" #endif void f(){ _tsetlocale(LC_ALL, _T("japanese")); FILE *fp; if ( _tfopen_s( &fp, _T("exp.txt"), _T("wb") ) ) return; _ftprintf( fp ,_T(文字セット)); fclose(fp); } ファイルサイズや出力内容を見てみると、Unicode文字を使う場合、このようにバイナリモードで書き込みをすると、バイト数が、単純にsizeof(wchar_t)*文字数になってしまうようで 気になったので調べてみると、こういうことみたいですね。 http://msdn.microsoft.com/ja-jp/library/c4cy2b8e%28VS.80%29.aspx 最後の方に >Unicode ストリーム入出力関数をバイナリ モードで実行すると、ファイルが Unicode であると想定されるため、入出力時に CR-LF 変換も文字変換も行われません。 と書いてありますが これは、ただしつまり Unicodeを扱う場合でも、結局バイナリモードで出力したらバイナリモードで入力すれば正しい同じデータが得られるし、テキストモードで出力したらテキストモードで入力すれば大丈夫と考えて良いですよね? 言い換えれば、少なくともUnicodeでテキストモードだと、CR-LF 変換と文字変換が行われてしまうということで (少なくともマルチバイトなら文字変換はなしでしょうが) 「文字変換」については今回初めて知りました。 他にはマルチバイト・Unicode問わず、テキストモードを使用すると、何か変換が行われる可能性はあるのでしょうか?

  • エディットボックスの数値をテキストファイルとして保存するには?

    プログラム初心者です。 質問させてください! リソース機能を用いて、親ウインドウのメニューバーから子ウインドウのダイアログを作成するプログラムを作りました。 さらにその子ウインドウ上に、エディットボックスのコントロールを作り、それに入力した数値をこの子ウインドウ上に新に設けたボタン(IDC_BUTTON1)が押された時に、この数値をテキストファイルに上書きして名前をつけて保存という形で保存させたいと思っております。 MFCの機能は使っておりません。 このような機能を実現させるためには、 どのような関数を使えばいいのでしょうか。 コモンダイアログボックスを使ってうまくプログラムを書ければと思うのですが・・・ どなたかご教授よろしくお願いいたします。

  • エディットボックスの改行について

    よろしくお願いいたします。 環境 WIN98 VC++6.0 MFC にて 改行が可能なエディットボックスのデータをテキストファイルに保存すると、エディットボックスと同様に改行されて保存されます。 ファイルからデータを読出し、エディットボックスに表示する場合もちゃんと改行されていて問題ありません。 ここで、エディットボックスが2つあり、それぞれのエディットボックスのデータが2行あったとすると、ファイルには4行保存されます。 次にファイルからデータを読出し、エディットボックスに表示する場合、1個目のエディットボックスのデータが2行と分かっていれば良いのですが、そうでない場合は何行読み出してエディットボックスに表示すれば良いか分かりません。 そこで、1個目のデータを保存する時に、最終行の次の行にendという文字を保存することにしました。 これで、読み出すときはendを目印に必要な行数を読み出せます。 しかしながら、エディットボックスの文字の中にたまたまendが使われるとうまく行きません。 長くなりましたが、このような場合、一般的にはどのようにして対処すれば良いのでしょうか? お分かりの方よろしくお願いいたします。

  • メモ帳で保存した日本語テキストや日本語XMLをJavaで読込、保存。メモ帳での保存文字コードはなにが推奨されるでしょうか?

     Windows9x系ではないWindowsVistaやXP、NT、2000のメモ帳(Unicodeのbig endianは保存できるがおそらくUnicodeのbig endianでのBOMなし保存不可。UTF-8は保存できるがUTF-8でのBOMなし(UTF-8N)の保存不可。Unicodeのlittle endianは保存できるが仕様なので言うまでもないがUnicodeのlittle endianでのBOMなし保存不可。)で保存した日本語テキストや日本語XMLをJavaで読込、保存。メモ帳での保存文字コードはなにが推奨されるでしょうか? やはりJavaのString型に近いUnicode big endianがよいのでしょうか? それともJava側で自動認識してくれるのでしょうか? XMLの場合は1行目でそのXMLファイルが使用している文字コードが何か宣言しますよね。 でもテキストファイルだと文字コードを宣言する場所がないみたいですし・・・(ここでの文字コードを宣言する場所としてはBOMは例外ですよ 念のため) 補足:メモ帳だとUnicode big endianで保存すると必ずBOMが付くみたいです。 メモ帳はLF改行が使えません。CR+LF改行のみ対応です。

    • ベストアンサー
    • Java
  • 複数行のエディットボックスで改行入力

    複数行のエディットボックスで改行入力 MFC ダイアログベースで、簡単なテキストエディタを作成しています。 エディットボックスは固定サイズで、縦横スクロール無しにしています。 上記エディットボックスに、改行の無い2行分の文字列を出力すると自動的に折り返され、 2行で表示されるのですが、そのとき、2行目の行頭でEnterキーを押すと、 カーソル位置で改行し、空行が挿入されます。(計3行分の表示となる) 10文字文の幅のエディットボックスにて、 文字列 "12345678901234567890" をエディットボックスに出力 エディットボックスでは下記の用に表示。 1234567890 1234567890 2行目の先頭でEnterキー押下で3行表示となる 1234567890 (空行) 1234567890 実際には、1行目の終わりに改行コードが挿入されているので 空行ではなく、改行された状態の2行表示としたいのですが、 どのようにすれば、よいでしょうか? よろしくお願いします。

  • 【Excel】テキストが改行位置以外で改行される

    こんにちは HTMLのテキストファイルをテキストファイルウィザードを通して開くと 改行位置ではないところで改行されてしまい困っています。 メモ帳で開くと1行になっています。 そのメモ帳の文字をコピーしてExcelにペーストしても同じでした。 メモ帳で見えない改行コードが入っているのでしょうか? まったく同じような文章でも、改行されてしまう行と改行されない行があります。 改行されないように開くにはどうしたらよいでしょうか。 Excel2013です。

専門家に質問してみよう