*

MFCプログラミング(1):CFileまたはCStdioFileクラスを使用してファイル出力

公開日: : C++, MFC, Windows, 開発

どもです。
突然ですが、仕事でMFCを使用することになりました。
MFCはこれまで触ったことがなかったので、色々とお勉強をしながら開発を進めています。
その中で、少し(あるいは少しどころではなく)ハマったことを書いていきます。

さっそく今回は、「ファイルへの出力」でハマった内容について書きます。

1.背景(簡単に)

入力内容をCSV形式でファイルに出力する、という機能を実装する際にハマりました。
CString型で出力したいデータを作成してファイルに書き出す、という単純な処理なので油断していました。

2.内容

CString型で出力するデータを作成しているので、最初は「CStdioFile」クラスの「WriteString」メソッドを使用して出力しようとしました。
しかし、実際に出力したファイルをテキストでディタなどで開いてみると、「余計な改行」が付与されて出力されました。
調べてみると、CString型のデータの中には含まれていない「ラインフィード(0x0A)」が付与されていました。
この「ラインフィード(0x0A)」ですが、どうやら「CStdioFile」クラスが自動で付与するものらしいです。
MSDNによれば、「CStdioFile」クラスは、

「ラインフィードをテキストモードでCStdioFileオブジェクトに書き込むと、バイトペア(0x0D 0x0A)がファイルに送信される」
MSDN

という仕様とのことです。
そのため、出力したいCString型の末尾に付与した改行コード(0x0D 0x0A)の「0x0A」が「0x0D 0x0A」に置換され、結果として「0x0D 0x0D 0x0A」が出力されていました。
この1つ目の「0x0D」が、出力ファイルでは「余計な改行」と見えていたのです。

3.対応

3.1.策1:改行コードを変更する

出力する文字列の末尾に付加する改行コードを「0x0D 0x0A」から「0x0A(のみ)」に変更する、という方法です。
実装、及び使用するクラスとか色々考えると、最も適切な方法です。

ところが、実装している機能では、行の末尾以外にも改行コードがあり、かつ行末の改行コードと区別するために、途中の改行コードを「0x0A」としています。
採用した場合、途中の改行コードと末尾の改行コードの区別ができなくなります。
そのため、この方法は採用できません。
(CSVの仕様を考えると色々ダメですが、そこはツッコんではいけません。)

3.2.策2:CFileクラスを使用する

ファイル出力に使用するクラスを、CFileクラスに変更する、という方法です。
CFileクラスには、CString型をそのまま出力するメソッドは用意されていません。
用意されているのは、

というメソッドです。(MSDN)

このメソッドを使用して、ファイルにデータを出力します。
そのため、CString型から文字列情報を取得、さらにそのサイズ(バイト)を計算しなければなりません。
(※間違っても、出力するCString型のポインタをconst void*にキャストする、ということはしてはいけません。)
具体的には、下記のようなコードになるかと思います。

※DataSrcとCsvFilePathは適宜設定します。

4.まとめ

今回は、MFCで文字列をファイルに出力しようとした際にハマった内容について書きました。
CFile、CStdioFile、あるいはそれ以外について、きちんと仕様を理解していれば、ハマらない内容でした…。

関連記事

toppers

C言語でEV3開発(24)-APIの実行時間を測定してみた。

どもです。 今回、以前から気になっていた、開発環境/プラットフォームであるTOPPERS HRP2

記事を読む

iot_at_home_eye_catch

IoT開発(2)-ESP-WROOM-02で気温測定

どもです。 この記事は、IoT開発(1)-ESP-WROOM-02のセットアップからの続きです

記事を読む

iot_raspberrypi_gateway_001_eye_catch

IoT開発(12)
RaspberryPiをIoTゲートウェイにする(V)
nginxとuWSGIの連携

どもです。このエントリは、以下のエントリの続きです。 IoT開発(6) RaspberryPiをI

記事を読む

google_test

C言語でEV3開発(6)

どもです。 今回のエントリーは、前回のエントリーの続き、google testでの単体テスト環境に

記事を読む

raspberry-pi

ライブラリでRasPiのピンにアクセス(3)-SPIのインターフェース追加(その2)

どもです。 今回のエントリも、前回に引き続き、RaspberryPiのピンをより簡便に使用でき

記事を読む

RasPi_Qt

QtでRaspberryPi/GUI開発(8):pigpioを使用したチャタリング対策の問題の対策

どもです。 だいぶ、間が空いてしまいました。 久しぶりの更新です。 前回のエントリーで、「

記事を読む

no image

Objective-CからC++コードを呼び出す

どもどもです。 今回は、突然ながらMacに関係する投稿です。 ソフト関係のことを勉強していて

記事を読む

no image

C言語でEV3開発(8)-opOUTPUT_POWERコマンド

どもです。 今回のエントリーでは、EV3でモーターを動かします。 なお、今回のエントリーでも

記事を読む

toppers

C言語でEV3開発(19)-コマンド通信処理でEchoBackしてみた

どもです。 前回は、Bluetoothの接続状態の変化に伴う、状態遷移について書きました。 今回

記事を読む

raspberry-pi

QtでRaspberryPi/GUI開発(1):ためしに時計を作ってみた

どもです。 また更新の間隔が空いてしまいました。 久しぶりの更新です。 前回のエントリーで

記事を読む

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

arduino_relay_switch_002_ae_g5v_drv_eye_catch
Arduinoでリレースイッチ(2)-AE-G5V-DRV

どもです。 前回の記事では、「フォトカプラリレー」を使用したLチ

tlp222af_001_eye_catch
Arduinoでリレースイッチ(1)-TLP222AF

どもです。 つい先日、やっとのことでリレースイッチを手に入れるこ

c_sharp_eye_catch
外部からMariaDbにアクセスする(2)-C#からMariaDbにアクセスする。

どもです。 前回のエントリで、外部からMariaDbにアクセスす

c_sharp_eye_catch
外部からMariaDbにアクセスする(1)-データベースの設定

どもです。 今回は、Linux上のMariaDbにWindows

think_about_utest
middle_unit
最小…よりも(ほんの)少し大きいテストフレームワーク

どもです。 今回は、単体テストのフレームワークについて書きます。

→もっと見る

PAGE TOP ↑