0

重複の可能性:
c++-文字列のprintfはぎこちない印刷

ファイルにいくつかの文字列を書きたいのですが。文字列は

37 1 0 0 0 0
15 1 0 0 0 0
33 1 0 0 0 0
29 1 0 0 0 0
18 1 0 0 0 0
25 1 0 0 0 0

まず、各行を文字列配列の要素として格納し、次に同じ文字列配列を呼び出して、その要素をファイルに書き込みます。

#include <stdio.h>
#include <vector>
#include <string>
using namespace std;

int writeFile() {

  char line[100];
  char* fname_r = "someFile_r.txt"
  char* fname_w = "someFile_w.txt"; 
  vector<string> vec;

  FILE fp_r = fopen(fname_r, "r");
  if(fgets(line, 256,fp_r) != NULL)   {
     vec.push_back(line);
  }

  FILE fp_w = fopen(fname_w, "w");
  for(int j = 0; j< vec.size(); j++) {
    fprintf(fp_w, "%s", vec[j]); // What did I miss? I get funny symbols here. I am expecting an ASCII
  }

  fclose(fp_w);
  fclose(fp_r);
  return 0;
}
4

2 に答える 2

7

フォーマット指定子"%s"は、ではなく、Cスタイルのヌル終了文字列を想定していますstd::string。への変更:

fprintf(fp_w, "%s", vec[j].c_str());

これはC++であるため、ofstream代わりにタイプセーフでstd::string入力として受け入れるものを使用することを検討する必要があります。

std::ofstream out(fname_w);
if (out.is_open())
{
    // There are several other ways to code this loop.
    for(int j = 0; j< vec.size(); j++)
        out << vec[j];
}

同様に、ifstream入力に使用します。投稿されたコードには、潜在的なバッファオーバーランがあります。

char line[100];
...
if(fgets(line, 256,fp_r) != NULL)

line100最大文字数を格納できますが、fgets()は保持できると述べています256。を使用すると、次std::getline()のように入力されるため、この潜在的な危険が排除されますstd::string

std::ifstream in(fname_r);
std::string line;
while (std::getline(in, line)) vec.push_back(line);
于 2012-08-29T09:52:54.353 に答える
0

この場合、vec[j]はstd::stringオブジェクトです。ただしfprintfscスタイルのnullで終了する文字列が必要です。

for(int j = 0; j< vec.size(); j++) {
    fprintf(fp_w, "%s", vec[j]); 
}

必要なのは、std::stringからcスタイルの文字列へのポインタを取得することだけです。c_str次の方法を使用して可能です。

for(int j = 0; j< vec.size(); j++) {
    fprintf(fp_w, "%s", vec[j].c_str()); 
}

いずれにせよ、C++とCコードを混在させます。それは醜いです。std::fstreamの使用が優れています。

于 2012-08-29T09:56:26.500 に答える