fprintf、字符串和矢量

fprintf, strings and vectors

本文关键字:字符串 fprintf      更新时间:2023-10-16

可能重复:
字符串上的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;
}

格式说明符"%s"需要以C样式null结尾的字符串,而不是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)

line最多可以存储100个字符,但fgets()声明它可以保存256。使用std::getline()在填充std::string:时消除了这一潜在危险

std::ifstream in(fname_r);
std::string line;
while (std::getline(in, line)) vec.push_back(line);

在这种情况下,vec[j]是std::string对象。但带有sfprintf需要以c样式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更好。