【问题标题】:C++ Fstream Output doesn't workC++ Fstream 输出不起作用
【发布时间】:2018-01-16 23:25:35
【问题描述】:

谁能告诉我为什么这不起作用?这个东西只是不想将数据写入文件。输入很好。 fout.open("Dats.txt", std::ios::out | std::ios::app); 也不起作用。

std::ifstream fin;
std::fstream fout;

fin.open("Dats.txt");
fout.open("C:/Users/Shantykoff/Documents/visual studio 2017/Projects/Input_Output_fstream_basis/Input_Output_fstream_basis/Dats.txt",
          std::ios::out | std::ios::app);

有问题的代码:

void inputData() {
    Data temp;
    std::cout << "Inserisci x\n";
    std::cin >> temp.x;
    fout << temp.x << "\n";
}

【问题讨论】:

  • 也许让foutan ofstream 代替 std::ftsream?你检查你对 temp.x 的阅读是否正常?
  • 文件打开成功了吗?
  • 是的,我检查过了,它打开了
  • @PaulT.,std::fstream 析构函数保证调用close()。正如here 解释的那样,自己调用它是毫无意义的
  • fout 对象在 inputData() 函数中;此对象是否声明为 global 对象?

标签: c++ input output fstream


【解决方案1】:

在这部分代码中:

void inputData() {
    Data temp;
    std::cout << "Inserisci x\n";
    std::cin >> temp.x;
    fout << temp.x << "\n";
}

最后一行您有一个名为fout 的变量,该变量具有此函数的本地范围,该函数未在此代码块的任何位置或此范围内声明。您有两个选项来解决此问题,除非您在未指定的主函数之外的全局范围内声明此对象:

  • 您可以在此函数中创建一个std::ofstream 临时对象,但您必须openclose 文件流。
  • 或者您可以通过referenceofstream object 传递给此函数。

我将分别展示一个示例:

void inputData() {
    Data temp;
    std::cout << "Iserisci x\n";
    std::cin >> temp.x;
    std::ofstream fout;
    fout.open( /* filename & path */ );
    fout << temp.x << "\n"; 
}

或者

void inputData( std::ostream& out ) {
    Data temp;
    std::cout << "Iserisci x\n";
    std::cin >> temp.x;
    out << temp.x << "\n";
}

然后在调用这个函数的代码块中你可以做...

{
    //... some other code
    std::ofstream fout;
    fout.open( "path & filename", flags );
    inputData( fout );
    fout.close();

    //... some other code
 }

如果你仔细注意到这个函数,我传递了一个对 std::ostream 对象的引用,而不是 std::ofstream 对象。我为什么选择这样做?这很简单,因为这个函数现在可以接受任何输出流类型的对象,而不仅仅是一个输出文件流对象......

{    
    inputData( std::cout ); // will now print to console out
    std::ostringsream ostr;
    inputData( ostr ); // will now populate the output string stream object

    // etc...
}

基本上把这行代码:fout &lt;&lt; temp.x &lt;&lt; "\n";在你的函数上面fout对象没有声明或定义在这个代码块的范围内,除非foutmain之外的全局命名空间中功能。


编辑 - 可选,但作为这行代码的附注:

fout.open("C:/Users/Shantykoff/Documents/visual studio 2017/Projects/Input_Output_fstream_basis/Input_Output_fstream_basis/Dats.txt",
      std::ios::out | std::ios::app);

由于您使用的是 Visual Studio,我通常会这样做:

在解决方案资源管理器中的当前项目设置下:

  • 在配置属性下 - 用于当前配置和平台设置
    • 一般
      • 输出目录:设置为 - $(SolutionDir)“ProjectName”\_build\
    • 调试
      • 工作目录:设置为 - $(ProjectDir)_build\

注意: "ProjectName" 只是项目实际名称的占位符。

那么这样你就不必从根目录C:\指定整个路径

然后在你的代码中当你有这样的文件时:

sample.txt - 放置在可执行文件现在所在的 _build 文件夹中,而不是“Visual Studio 的”默认位置。

1 2 3 4 5 6 7 8 9

ma​​in.cpp

int main() {
    std::vector<unsigned> values;

    std::ifstream in;
    unsigned val;
    in.open( "sample.txt" );
    while ( in >> val ) {
        values.push_back( val );
    }
    in.close();

    // lets modify some values
    for ( auto v : values ) {
        v *= 10;
    }

    // Let's print new values to same file but lets append it to a new line
    std::ofstream out;
    out.open( "sample.txt", std::ios::app );
    for ( auto v : values ) {
        out << "\n";
        out << v << " ";
    }
    out.close();

    return 0;
}

sample.txt

1 2 3 4 5 6 7 8 9
10 20 30 40 50 60 70 80 90

现在,通过在解决方案资源管理器中创建 _build 文件夹,可以更轻松地读取长路径的代码,因为路径现在与项目目录相关,并且应该指向包含应用程序的同一文件夹可执行文件以及任何第三方依赖项 - 外部 dlls。现在就我自己而言,我选择在 build 文件夹名称的前面放置一个 underscore,只是为了将其保持在其父目录的 top 中。

【讨论】:

  • 这可能是一种糟糕的做法,但没有理由假设他们没有使用在调用函数之前已打开的全局 fout 流。糟糕的做法,但仍然是有效的代码。
  • @AlexanderHuszagh 是的,这就是我在答案中提到它的原因;因为如果不显示,就无法知道他们是否使用了这样的global object
  • 那么这绝对不是真的:The last line you have a variable named fout that has local scope to this function that isn't declared anywhere in this block of code or within this scope. You have two options to resolve this:。他们声明没有编译错误:询问更多信息。
  • @AlexanderHuszagh 是真的;但是从他们提供的东西来看,即使我不应该......假设它没有正确输出。这是我唯一能想到的。他们能够从文件中“读取”,但不能输出到文件,而且我在函数的本地范围内看到了一个未声明的 ofstream 对象。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多