ファイル書き込み時の改行コードについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Mikan

ファイル書き込み時の改行コードについて

#1

投稿記事 by Mikan » 10年前

お世話になっております。みかんと申します。
Windows環境での改行コードについて、質問させていただきます。

現在、VC++を使用してプログラムを作成しています。
プログラムの動作(処理)としては、テキストファイルを読み込んで、
文字列の加工を行ったあとファイルに保存する処理を行います。

読み込むファイルと書き込むファイル形式は、
UTF-8で改行コードはLFの形式となります。
具体的には、CStdioFile クラスを使用して読み書きをしています。

■読み込み
CString line;
CStdioFile file(_tfopen(_T("C:\\utf8.txt"), _T("r, ccs=UTF-8")));
while (file.ReadString(line))


file.Close();

■書き込み
CString line;
CStdioFile file(_tfopen(_T("C:\\uft8-out.txt"), _T("w, ccs=UTF-8")));
file.WriteString(line));
file.Close();

そこで、質問なのですが、
現在、上記CStdioFile クラスを使用してファイルを保存した際、
保存したファイルの改行コードが必ずCR+LF(\r\n)になってしまっています。
できれば、保存するファイルの改行コードも
文字列を読み込んだファイルと同じように改行コードをLFにしたい
と思っています。
もし、保存するファイルの改行コードをLFにする方法(APIなど)がありましたら、
ご教授いただけないでしょうか。

開発環境としては、以下の通りです。

■開発環境
OS:Windows 7
言語:Visual C++ (Visual Studio 2005)

■プログラムの動作環境
OS:Windows XP / Windows Vista / Windows 7 / Windows 8 / Windows 8.1 (x86/x64)

よろしくお願い致します。

ISLe()

Re: ファイル書き込み時の改行コードについて

#2

投稿記事 by ISLe() » 10年前

書き出し側にバイナリモードを指定すれば良いと思います。

CStdioFile file(_tfopen(_T("C:\\uft8-out.txt"), _T("w, ccs=UTF-8")));

CStdioFile file(_tfopen(_T("C:\\uft8-out.txt"), _T("wb, ccs=UTF-8")));

Mikan

Re: ファイル書き込み時の改行コードについて

#3

投稿記事 by Mikan » 10年前

ISLeさん

返信ありがとうございます。
説明不足で申し訳ありません。
私の環境は、マルチバイト(char)環境ではなく、ワイドバイト(WCHAR)の環境となります。

私も当初バイナリーモードで出力すればよいと考え
バイナリーモードにて出力したのですが、
以下のように文字化けしてファイルに出力されました。

■書き込む文字列
ABC
EFG
あいう
えおk

■バイナリーモードで出力した文字列
A A A
B B B
B0D0F0
H0J0K0

■確認したコード
CString line;
line = _T("AAA\nBBB\nあいう\nえおか");
CStdioFile file(_tfopen(_T("C:\\UTF-8-out.txt"), _T("wb")));
file.WriteString(line);
file.Close();

おそらく、ワイドバイト環境のため、正しく出力されなかったものと
考えています。
ワイドバイト環境の場合は、特別な設定が必要なのでしょうか。

ISLe()

Re: ファイル書き込み時の改行コードについて

#4

投稿記事 by ISLe() » 10年前

バイナリモードで出力されているのはVC++のワイド文字の内部表現であるUTF-16で、正しく出力されていないわけではないですね。

ただしバイナリモードだとcssで指定するUNICODE変換も無効になるようです。

改行コードの変換なしにUTF-8で出力するには、
WideCharToMultiByte関数などを使って自前で変換したバイト列をバイナリモードで出力するという手段になりますかね。

ISLe()

Re: ファイル書き込み時の改行コードについて

#5

投稿記事 by ISLe() » 10年前

Unicode文字セットでマルチバイト文字を混在して扱えないという理由で
CStringは使えないし、CStdioFileは(MFCにこだわるなら)CFileを使うように変える必要がありますね。

とりあえず簡単なサンプルコードです。
プロジェクトの文字セットに関係なく、変換元はワイド文字列となるようにしなければいけません。

コード:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <locale.h>
int main(void)
{
	_tsetlocale(LC_CTYPE, _T(""));
	LPCWSTR wide_str = L"ABC\nDEF\nあいうえお\nかきくけこ";
	char out_str[100];
	FILE *fp = _tfopen(_T("uft8-out.txt"), _T("wb"));
	if (fp) {
		int len = WideCharToMultiByte(CP_UTF8, 0, wide_str, -1, out_str, 100, NULL, NULL);
		fwrite(out_str, len-1, 1, fp);
		fclose(fp);
	}
	return 0;
}

Mikan

Re: ファイル書き込み時の改行コードについて

#6

投稿記事 by Mikan » 10年前

ISLe()さん

サンプルコードありがとうございます。
また、ご連絡が遅くなり、申し訳ありません。

WideCharToMultiByte関数などを使って変換する必要がある旨、
理解できました。
教えていただいたように一度変換するか、
一度ファイルに書き込んだ後で、バイナリーモードでバイナリとして
読み込み、¥rを削除してデータを書き込むなどの方法にて
対応したいと思います。

サンプルコードなど親切に教えていただき、
ありがとうございました。
大変助かりました。

閉鎖

“C言語何でも質問掲示板” へ戻る