C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[6]: WriteFileで書き込んだ文字列が文字化け


(過去ログ 171 を表示中)

[トピック内 7 記事 (1 - 7 表示)]  << 0 >>

■98408 / inTopicNo.1)  WriteFileで書き込んだ文字列が文字化け
  
□投稿者/ ばんじ (1回)-(2021/11/13(Sat) 21:07:15)

分類:[C/C++] 

WriteFileで書き込んだ文字列が文字化けしてしまいます。
どうすればよろしいでしょうか?よろしくお願いします。

開発環境:visual studio 2019

const char TestData[NUMWRITES][TESTSTRLEN] =
{
"TestData0\n",
"TestData1\n",
"TestData2\n",
"TestData3\n",
"TestData4\n",
"TestData5\n",
"TestData6\n",
"TestData7\n",
"TestData8\n",
"TestData9\n"
};

int main(int argc, char* argv[])
{
BOOL fSuccess = FALSE;

HANDLE hFile = CreateFile(TEXT("datafile.txt"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
0,
NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed (%d)\n", GetLastError());
return (1);
}

DWORD dwNumBytesWritten = 0;

for (int i = 0; i < NUMWRITES; i++)
{
fSuccess = WriteFile(hFile,
TestData[i],
TESTSTRLEN,
&dwNumBytesWritten,
NULL); // sync operation.
if (!fSuccess)
{
printf("WriteFile failed (%d)\n", GetLastError());
return (2);
}
}

引用返信 編集キー/
■98409 / inTopicNo.2)  Re[1]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ とっちゃん (743回)-(2021/11/13(Sat) 23:30:04)
No98408 (ばんじ さん) に返信
> WriteFileで書き込んだ文字列が文字化けしてしまいます。
> どうすればよろしいでしょうか?よろしくお願いします。
>
ソースコードを見る限りではおかしそうなところは見受けられません。

具体的にどういう形で文字化けしているのでしょうか?
バイナリエディタで(VSでファイル開くから開くボタンの右側にある▼部分を押してドロップダウンメニューを開いて
「ファイルを開くアプリケーションを選択」を選んでファイルを開いてダイアログの一番下のほうにある
バイナリエディタで開くとファイルをバイナリで読むことができます。

意図した値(戦闘がTなので、0x54かどうかなど)か同課を確認してみてください。

プログラムは、このままではビルドが通せない(未定義の値があるため)ので判断がつきかねます。
文字化けの判断がつきかねます。

あと、本題とは直接関係ないですが、CreateFile/WriteFile API はバイナリモードでの操作になるので
テキストファイルとして書込みしたいのであれば、改行は「"\r\n"」です。


引用返信 編集キー/
■98410 / inTopicNo.3)  Re[2]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ ばんじ (2回)-(2021/11/14(Sun) 00:07:15)
No98409 (とっちゃん さん) に返信
> プログラムは、このままではビルドが通せない(未定義の値があるため)ので判断がつきかねます。
> 文字化けの判断がつきかねます。
>
> あと、本題とは直接関係ないですが、CreateFile/WriteFile API はバイナリモードでの操作になるので
> テキストファイルとして書込みしたいのであれば、改行は「"\r\n"」です。

とっちゃん さんにご指摘いただいたCarriage Returnを追記したら文字化けが直りました。
ありがとうございます!
しかし、2行目以降の先頭にスペースが入るようになってしまいました。
ビルドできる形でコードを張り付けなおします。よろしくお願いします。

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define NUMWRITES 10
#define TESTSTRLEN 12

const char TestData[NUMWRITES][TESTSTRLEN] =
{
"TestData0\n",
"TestData1\n",
"TestData2\n",
"TestData3\n",
"TestData4\n",
"TestData5\n",
"TestData6\n",
"TestData7\n",
"TestData8\n",
"TestData9\n"
};

int main(int argc, char* argv[])
{
BOOL fSuccess = FALSE;

HANDLE hFile = CreateFile(TEXT("datafile.txt"),
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
CREATE_NEW,
0,
NULL);

if (hFile == INVALID_HANDLE_VALUE)
{
printf("CreateFile failed (%d)\n", GetLastError());
return (1);
}

DWORD dwNumBytesWritten = 0;

for (int i = 0; i < NUMWRITES; i++)
{
fSuccess = WriteFile(hFile,
TestData[i],
TESTSTRLEN,
&dwNumBytesWritten,
NULL); // sync operation.
if (!fSuccess)
{
printf("WriteFile failed (%d)\n", GetLastError());
return (2);
}
}
return (0);

引用返信 編集キー/
■98412 / inTopicNo.4)  Re[3]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ とっちゃん (744回)-(2021/11/14(Sun) 01:29:11)
No98410 (ばんじ さん) に返信

> とっちゃん さんにご指摘いただいたCarriage Returnを追記したら文字化けが直りました。
> ありがとうございます!
> しかし、2行目以降の先頭にスペースが入るようになってしまいました。
> ビルドできる形でコードを張り付けなおします。よろしくお願いします。
>
張り付けたプログラムは、\r\n になっていませんが?

先頭にスペースとありますが、スペースは、0x20というバイトデータだと思いますが
具体的にはどんな値になっているでしょうか?バイナリエディタで確認していますか?

一応…TESTSTRLEN の長さが12 と定義されていますが、
張り付けたプログラムの文字列の長さは 10+1(\0分)で
可読文字部分は10です。

一度文字列の長さを確認してみることをお勧めします。
WriteFileに渡しているバッファ長(TESTSTRLENの値)が同じかどうか確認してみてください。

WriteFile の直前で
printf( "len=%d\n", strlen( TestData[n] ) );
と入れてみると良いでしょう。

引用返信 編集キー/
■98413 / inTopicNo.5)  Re[4]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ ばんじ (3回)-(2021/11/14(Sun) 02:15:15)
No98412 (とっちゃん さん) に返信
> 張り付けたプログラムは、\r\n になっていませんが?
大変失礼しました。修正前のを張り付けていました。
実際のコードは\r\nはついていますので"TestData0\r\n"...と思って読んで頂けると助かります。
なのでTESTSTRLENは12であっているかと。

> 先頭にスペースとありますが、スペースは、0x20というバイトデータだと思いますが
> 具体的にはどんな値になっているでしょうか?バイナリエディタで確認していますか?

バイナリエディタで確認するとTestData0の後に0x0D 0x0A 0x00で、
\r\nの後にnullがあるだけです。nullの後にまた0x54...です。
0x20はありません。

> WriteFile の直前で
> printf( "len=%d\n", strlen( TestData[n] ) );
> と入れてみると良いでしょう。

バッファ長はlen=11となっています。
よろしくお願いします。
引用返信 編集キー/
■98414 / inTopicNo.6)  Re[5]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ Azulean (1209回)-(2021/11/14(Sun) 08:17:20)
No98413 (ばんじ さん) に返信
> バイナリエディタで確認するとTestData0の後に0x0D 0x0A 0x00で、
> \r\nの後にnullがあるだけです。nullの後にまた0x54...です。
> 0x20はありません。

WriteFile は「文字列」を書くのではなく、「バイト列」を書くものです。
C 言語(や C++) における文字列リテラルの末尾には 0x00 = '\0' が置かれているので、0x00 を書き込まないようにしましょう。
具体的には WriteFile に渡す、「書き込む長さ」を調整してください。
引用返信 編集キー/
■98415 / inTopicNo.7)  Re[6]: WriteFileで書き込んだ文字列が文字化け
□投稿者/ ばんじ (4回)-(2021/11/14(Sun) 11:07:42)
No98414 (Azulean さん) に返信
> WriteFile は「文字列」を書くのではなく、「バイト列」を書くものです。
> C 言語(や C++) における文字列リテラルの末尾には 0x00 = '\0' が置かれているので、0x00 を書き込まないようにしましょう。
> 具体的には WriteFile に渡す、「書き込む長さ」を調整してください。

結局、文字列の\rを外して元の文字列"TestData0\n"に戻して、
WriteFile に渡した時の[TESTSTRLEN]を-1したらスペースが消え、文字化けもなくなりました。

WriteFile(hFile, TestData[i], TESTSTRLEN-1, &dwNumBytesWritten, NULL);

ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -