趣味でC++やっています。Qtについてですが、
テキストファイルの書き込みに関して質問します。( 改行については一応解決したっぽいのでいいですが、後述の「なぜか別のソフトで認識できない」問題が残っています。 それについてです。 )
(※ 長文になります)
C++
1namespace Test{ 2 namepsace TextFile{ 3 void bool write( const QString &filepath, const QString &title ){ 4 QFile file( filepath ); 5 if( !file.open( QIODevice::WriteOnly ) ) return false; 6 QTextStream ts( &file ); 7 ts.setCodec( QTextCodec::codecForName( "UTF-8" ) ); 8 ts << "[INFO]\n\r"; 9 ts << (QString("TITLE=") + title + QString("\n\r")); 10 ts << (QString("TITLE=") + title + QString("\n\r")); 11 file.close(); 12 return true; 13 } 14 } 15} 16 17// 呼び出し元として 18if( Test::TextFile::write( "definition.ini", "あいうえお" ) ) ... // OKなら印字するなりする 19
としました。
で生成されたテキストファイル ( 上記なら iniファイル ) をWindows付属のメモ帳で開くと
本来なら
[INFO] TITLE=あいうえお TITLE=あいうえお
となっているべきですが、なぜか
[INFO]TITLE=あいうえおTITLE=あいうえお
と改行がなされていません。
試した方法1: ts << "[INFO]\n";
試した方法2: ts << "[INFO]" << "\n" << flush;
試した方法3: ts << "[INFO]" << "\n\r" << flush;
試した方法4: ts << "[INFO]\n\r";
...
試した方法5: // file.open( QIODevice::WriteOnly | QIODevice::Text ) で開き、その他の設定は同じとして ts << "TITLE=" << title << "\n";
とやってみると方法1~4はダメでした (結果が最初と同じ)が、
方法5でやってみるとできました。(= メモ帳で開いても改行されていた。 )
ですが、なぜか他のソフト(自分が開発した)では文字化けするみたいです。
メモ帳で開いて何かしらのデータを書き込んで上書き保存をすると普通に使えました。
例えば
オリジナルだと
[INFO] TITLE=hello TITLE=hello
となっているのを"abc"を追加して
[INFO] TITLE=hello TITLE=hello abc
とすると(生成したiniファイルが)普通に使えました。
やろうとしていたことは、
(予定としては)自分用に、ソフトA (自作) を zipファイルに圧縮して ソフトB (自作) に同梱して
ソフトBに情報 ( ファイルの生成場所等 ) をEDITに相当するQLineEditに渡して
ソフトA用のzipファイルをデスクトップ (任意) に解凍して
ソフトA用のiniファイル ( 定義ファイル ) を解凍先と同じディレクトリに生成。
...という風に、ソフトAを使いやすくする感じです。( __生成したいファイルと生成器みたいな感__じでしょうかね。 )
でも方法5だとなぜか文字化けするようで、ソフトAがうまく動かないです。
ソフトAは QSettingsを継承して使いやすくした IniFileHandler::FileReaderクラス (自分用) を使ってiniファイルを読み込みます。
ソフトBは生成器みたいな感じです。
で、悩んだ末、iniファイルとしてQSettingsを使っているのだからQSettingsで書けばいいんじゃないか。
と思い、IniFileHandler::FileReaderの書き込み版である (QSettingsを継承しているものとして) IniFileHandler::FileWriter で書き込んでみました。
すると問題が解決しました。
試した方法6: QSettingを継承したクラスで生成する方法に切り替える
ですが、テキストファイルとして生成したはずの方法5だとテキストファイルとしては認識されていないのか、
ソフトAでは使えなかったのでどうしたものかと...
今回はいいですが、後で、例えばエクセルのために CSVファイルを生成する...のように自分が組んだもの、そうでないもの関係なく、
他のソフトのためにテキストファイル( *.txt )を生成して外部ソフトが読み込めるようにするソフトを作る時とかに
また問題になりそうなので、ここで解決したいなぁと。
要約すれば、「自ソフトだけじゃなくて他のソフトでもテキストファイルとして認識し、使用することができるように生成する方法」です。
今、外出先なのですぐには試せませんが...
[情報]
言語: C++
コンパイラ: MinGW
Qt: Qt 5.6 (LGPL)
[追記及び解決したことを提示]
解決しました。Chironianさんの回答が解決への糸口になったのでChironianさんをBAとするためにここに
解決した方法を書いておきます。( 似たような問題に直面した方のために。 )
私の解決方法は、
C++由来のstd::ofstreamをコンポジションしてクラス化する。
そのクラスは引数としての文字列はQStringで受ける。
メンバ関数やコンストラクタ内で QString -> char* に変換する処理 ( QString -> std::wstring -> std::string -> char* )
をして std::ofstream::operator<< に渡す。
例:
C++
1// MyLib::toString() は QString -> std::wstring -> std::string と変換する関数だとする。 2namespace IoFile{ 3 class FileWriter{ 4 public: 5 FileWriter( const QString &filepath ){ 6 ofs.open( MyLib::toString( filepath.toStdWString() ).c_str() ); 7 } 8 9 ~FileWriter(){ ofs.close(); } 10 11 void write( const QString &text = QString("\n") ){ 12 if( text.compare( "" ) == 0 ){ ofs << endl; return; } 13 ofs << MyLib::toString( text.toStdWString() ).c_str(); 14 } 15 protected: 16 std::ofstream ofs; 17 }; 18} 19 20
C++のSTL使うぐらいならQt側のを使え...って言われるぐらいだから、普通にやり方があるんじゃないかなぁ...と思ったので。
お騒がせしてすみません。
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/09/03 04:26
2018/09/03 06:37
2018/09/03 06:44
2018/09/05 02:02