vectorに格納されているデータをすべて
一度のファイル書き込みで出力したいです。
以下の場合だと、期待通りの出力をしてくれません。
(abcdefのみが出力されます。)
C++
1int main() 2{ 3 const char* pstr = "abcdef"; // 配列 4 std::vector<const char*> vstr; // ベクター配列 5 std::fstream outfile; // 出力先のファイル 6 7 for (int i = 0; 6 > i; i++) 8 { 9 // 文字列格納 10 vstr.push_back(pstr); 11 } 12 13 // 正常に格納できているか確認 14 for (const auto& i : vstr) 15 { 16 std::cout << i << std::endl; 17 } 18 19 outfile.open("適切なファイルパス", std::ios::out); 20 outfile.write(vstr[0], (vstr.size() * sizeof(char))); 21} 22
書き出したいイメージ
abcdef
abcdef
abcdef
abcdef
abcdef
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答3件
0
うーん、どうしても一度の書き込みにしたいのはなんででしょうかね?一番シンプルなのは一度の書き込みにこだわるのをやめるという選択肢です。それができないというのは、例えばWebDAVとかで物理的に極めて遠い場所をマウントしていてレイテンシーが無視できず、かつ通信量ではなく通信回数で課金額が決まるような場所に書き出すとかそういう話ですかね?そんなのあるのか知らんけど。
そういう場合は一度std::stringstream
に書き出して、その組立てた文字列を取得し、それを書き出すという手段が考えられます。
ただし、上記のような極めて過酷で特殊で存在するかも怪しいような状況が発生していな限り、つまりほとんどすべての状況で速度的にも書くコード量的にも消費メモリー量的にも不利です。こんなコードが必要となる現状そのものをまずはどうにかすることを強く推奨します
もう一度いいますが、無理に一度で書き出そうとすることは速度的にもその他ありとあらゆる観点で不利です
cpp
1#include <cstdio> 2#include <sstream> 3#include <vector> 4int main() 5{ 6 const char* pstr = "abcdef"; // 配列 7 std::vector<const char*> vstr; // ベクター配列 8 9 for (int i = 0; 5 > i; i++) 10 { 11 // 文字列格納 12 vstr.push_back(pstr); 13 } 14 std::stringstream ss; 15 for (const auto& i : vstr) 16 { 17 ss << i << std::endl; 18 } 19 const auto out = ss.str(); 20 const char* out_path = "/path/to/file"; 21 const auto fp = std::fopen(out_path, "wb"); 22 if (nullptr == fp) return 1; 23 std::fwrite(out.data(), out.size(), 1, fp); 24 std::fclose(fp); 25}
本当に大事なことなのでもう一度いいますが、無理に一度で書き出そうとすることは速度的にもその他ありとあらゆる観点で不利です
投稿2020/08/18 04:18
総合スコア5852
0
tyapapaさん
std::ofstreamでは<<演算子を
使うと簡潔にかけます。
下記に修正したコード載せときます。
c++
1#include <iostream> 2#include <vector> 3#include <fstream> 4 5int main() 6{ 7 const char* pstr = "abcdef"; // 配列 8 std::vector<const char*> vstr; // ベクター配列 9 std::fstream outfile; // 出力先のファイル 10 11 for (int i = 0; 5 > i; i++) 12 { 13 // 文字列格納 14 vstr.push_back(pstr); 15 } 16 17 // 正常に格納できているか確認 18 for (const auto& i : vstr) 19 { 20 std::cout << i << std::endl; 21 } 22 23 outfile.open("./out.txt", std::ios::out); 24 for(const auto& i:vstr)outfile << i << std::endl; 25 outfile.close(); 26} 27 28
追記
下記解説誤った解説の疑いあり(yumetodoさんより)
writeを用いた
一括書き込みを行うコード
まず私の環境では元コードをコンパイルして
実行するとファイルは生成されましたが
abcdefとしか記載されていませんでした。
その理由は恐らく
元コードではwriteメソッドの第一引数で
vstr[0]を指定しており、
そのvstr[0]はpstrが格納されています。
もっと詳しく説明しますとそのpstrの文字aの番地です。
そしてそのアドレスから6番目のアドレスに終端文字が入っているので
出力されるファイルにはabcdefしか記載されないということです。
そこで下記のようにメモリ上に一列に終端文字を改行コードに置き換えた
メモリを作ることができればwriteメソッドで一括書き換えできるかと思います。
c++
1#include <iostream> 2#include <fstream> 3#include <vector> 4#include <cstring> 5 6int main() 7{ 8 const char* pstr = "abcdef"; 9 10 // もともとpstrの番地を格納したvectorでしたが 11 // a,b,c,d,e,f,\n,a,b,c,d,e,f,\n...と並べたメモリを作成するためchar型を格納するvectorに変更 12 std::vector<char> vstr; 13 std::fstream outfile; 14 15 for (int i = 0; 6 > i; ++i){ 16 for(int j=0; j<std::strlen(pstr); ++j){ 17 vstr.push_back(pstr[j]); 18 } 19 vstr.push_back('\n'); 20 } 21 22 for (const auto& i : vstr)std::cout << i ; 23 24 outfile.open("./out.txt", std::ios::out); 25 outfile.write(&vstr[0], vstr.size());//一括書き込み 26} 27
投稿2020/08/18 01:38
編集2020/08/18 05:53
退会済みユーザー
総合スコア0
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

退会済みユーザー
2020/08/18 04:13
2020/08/18 05:26 編集

退会済みユーザー
2020/08/18 05:45 編集
2020/08/18 06:02
2020/08/18 06:05

退会済みユーザー
2020/08/18 07:19 編集
2020/08/18 10:52 編集

退会済みユーザー
2020/08/18 17:13

0
ベストアンサー
outfile.write((char*)&vstr[0], (vstr.size() * sizeof(char)));
書いていることが滅茶苦茶であると見える.
vstrの要素の型は何か?等を鑑みて,このコードが何をしようとしているのかを考えてみてはどうか.
投稿2020/08/18 01:28
総合スコア12151
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。