文字をファイルに書き込むと文字化けする

解決


COL  2008-02-19 22:51:26  No: 67552

ファイル入出力について教えてください。
TCHAR name[10]を宣言し、fprintf(fp,"%10c",name)とした所、ファイルには書き込めたんですが文字化けしてしまいました。
どうすれば文字化けせずにファイルに文字を書き込めるのでしょうか?


PATIO  2008-02-19 23:11:36  No: 67553

開発環境を書いてもらわないと何とも書きようがないかと。

あと、プロジェクトを作る時に何を選択してプロジェクトを作ったかも要ります。

プログラムが対して長くないなら全部載せてしまった方が話が早い場合もあります。


PATIO  2008-02-19 23:13:51  No: 67554

あと、右も左も分からない状況でやっているなら
適切な参考書も必要だと思います。

Webでも参考になる所は有りますけれど。
最初のうちは本でじっくり勉強した方が良いと思いますよ


tetrapod  2008-02-19 23:21:40  No: 67555

そりゃそーだろう。複数の間違いがあるからな

TCHAR を出力するなら _ftprintf を使う必要があるだろう
%10c に対応するのは TCHAR だから name を渡しても動作しない
name を渡したいのなら %10s とすべきだろう
UTF-8 文字列をそのまま出力すると SJIS を期待しているエディタでは文字化けする

というわけで「どうなって欲しいのか」で正解は違う。
とりあえず _ftprintf(fp, _T("%10s"), name); で良いかもしれない。
だがそれはCOL氏が期待している内容とは異なるかもしれない


COL  2008-02-19 23:28:39  No: 67556

開発環境…えっと、VC.NETの2003とかでしょうか。
プロジェクトは、DirectX Sample BrowserのEmptyProject C++ (July 2004) を使って作ってます。
プログラムは、
#include "dxstdafx.h"
#include "resource.h"
#include <tchar.h>
TCHAR name[10];
FILE *fp;

OnFrameMoveに
fp = fopen("save1.txt", "a");
if(fp == NULL)
exit(1);

fprintf(fp,"%10c",name);
fclose(fp);
です。


COL  2008-02-20 00:01:02  No: 67557

TCHAR name[10]={'あ','か','さ','た','な'};
  //もし書き込めなかったらファイル作成して書き込む
  fp = fopen("save1.txt", "w");
  if(fp == NULL)
  {
    fp = fopen("save1.txt", "a");
    if(fp == NULL)
    {
      exit(1);
    }
  }

  _ftprintf(fp, _T("%10s"), name); 
  fclose(fp);
とした所、ファイルの中に半角スペースが5つ書かれていました。
また、_ftprintf(fp, _T("%10s"), name)をfprintf(fp,"あいうえお")にした所、ファイルにはちゃんとあいうえおと書かれていました。


Blue  2008-02-20 00:30:56  No: 67558

> TCHAR name[10]={'あ','か','さ','た','な'};
間違っています。

TCHARなら

TCHAR name[10]={_T('あ'),_T('か'),_T('さ'),_T('た'),_T('な')};

TCHAR name[10] = _T("あかさたな");
としないといけませんし、setlocaleで日本語ロケールを設定しないといけません。


シャノン  2008-02-20 01:27:07  No: 67559

> というわけで「どうなって欲しいのか」で正解は違う。

みんな、「TCHARを使う場合はこうすべし」と書いてるけど、本当にTCHARを使うのが適切なの?
もし COL さんが TCHAR というデータの意味を知らないなら、TCHAR じゃなくて char、_ftprintf じゃなくて fprintf を使っておいた方が無難かも。


COL  2008-02-20 02:59:00  No: 67560

皆様、返信ありがとうございます。
シャノン様の言うとおり、TCHARの意味は良く分かってないので、char型にします。

char name[10]={'あ','か','さ','た','な'};

fprintf(fp, "%10s",name);
にした所、5つの半角スペースと、文字化けたものが5文字出ました。
fprintf(fp, "%10c",name);
にした所、10の半角スペースが出ました。
後はtetrapod様の言う、エディタの問題なのでしょうか?


Blue  2008-02-20 03:23:37  No: 67561

'あ'→Shift_JISコードでは2バイト必要
C言語で文字列として扱うには末尾にには '\0'が必要

ということですので、char name[11]としないとおさまりきれません。

また

char name[3] = {'あ'};

とすると、'あ'はchar型ではおさまらないので、

name[0] = (char)'あ';

と扱われ、後ろの1バイトしか格納しません。

char name[] = "あかさたな";

とするか、

char name[11] = {0x82, 0xa0, 0x82, 0xa9, 0x82, 0xb3, 0x82, 0xbd, 0x82, 0xc8, 0x00};

てな感じにするしかなさそう。


Blue  2008-02-20 03:25:08  No: 67562

ちなみに
>TCHAR name[10]={_T('あ'),_T('か'),_T('さ'),_T('た'),_T('な')};
は Unicodeビルドのときにしか使えませんでした。


COL  2008-02-20 03:30:41  No: 67563

char name[] = "あかさたな";
とした所、無事に表示されました!
長々とお付き合いいただき、ありがとうございました!
今後もこの掲示板でお世話になると思いますが、その際はよろしくお願いします。


夏みかん  2008-02-20 03:31:00  No: 67564

> シャノン様の言うとおり、TCHARの意味は良く分かってないので、char型にします。
なら次のリンクでお勉強して下さい。
http://www.ruche-home.net/program/tips/tchar.php

> char name[10]={'あ','か','さ','た','な'};
この指定方法が間違い。

文字列 name に文字列定数を初期値として持たせたいなら
char name[10]="あかさたな";
この1行で良い。

半角文字なら
char name[10]={'C','O','L'};
とすることで "COL" 文字列がセットされたのと同じになる。
でも
char name[10]="COL";
とした方が楽だよ。


だめだし  2008-02-20 03:44:58  No: 67565

>char name[10]="あかさたな";
>この1行で良い。
ヨクネー。
解説が7分前に書いてあるのに。


ゴン  2008-02-20 04:01:03  No: 67566

charの初期化に'あ'とするなんて発想はなかったですね・・・
どのような結果になるかすら想像がつかない。

おそらく'あ'とすると16bitで初期化されていると思うんですけれど、char[0]に代入された時点で8bitに切り詰められるはずですので、文字化けするはずです。

Blueさんが仰ってるようにTCHARなら_T("あいうえお")、charなら"あいうえお"として初期化するほうが無難です。
また、文字列を初期化する際に配列のサイズを指定しなれば、適切なサイズ(NULLターミネータを含んだサイズ)の配列になりますのでこの方がいいのでは?

TCHAR name[] = _T("あいうえお");
char  name[] = "あいうえお";

あと、%sと%cの違いですが簡単に言うと%sは引数を文字コードのポインタとして、%cは文字コードとして扱います。
文字コードとして扱うのにポインタを渡せば文字化けします。


夏みかん  2008-02-20 04:14:44  No: 67567

> ヨクネー。
あっ。本当だ。

char name[11]="あかさたな";
だね。数えてなかった。文字数。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加