偶然发现getline、fstream、范围不一致

Posted

技术标签:

【中文标题】偶然发现getline、fstream、范围不一致【英文标题】:Stumbling across getline, fstream, scope inconsistency 【发布时间】:2014-08-04 16:48:13 【问题描述】:

我正在阅读 std::getline(),但我没有弄清楚我做错了什么。在这种情况下,我不确定为什么在主功能块中声明并定义为“0”的 user_input 变量将在修改它的内部块中正确修改为“2”,然后设置为“ NULL”之后在主功能块中。

我的理解是,当在嵌套块中修改内容时,外部块无法识别更改——它们永远不会离开内部块的范围。

我最好的猜测是它一定与我的文件打开和文件关闭有关,或者我不知道 getline 如何与它们交互。在过去的一年里,我做了很多 cin 和 cout,但没有接触过 getline,也没有接触过文件交互。

//fake_main.cpp

#include <fstream>
#include <iostream>
#include <string>

int main()

    //---|Initializations|---
    std::string user_input = "0";
    //user_input is 0 in this block

    std::ofstream outbound_filestream;
    outbound_filestream.open ("a.txt");
    outbound_filestream << "2" << std::endl;
    outbound_filestream.close();

    std::ifstream inbound_filestream;

    //verifying that there is a "2" in my otherwise empty file
    inbound_filestream.open ("a.txt");
    if (inbound_filestream.is_open())
    
        while (std::getline(inbound_filestream, user_input))
        
            std::cout << user_input << '\n';
            //user_input is 2
        
        inbound_filestream.close();
    //right here, after losing scope, user_input is NULL, not 0.
    
    //and then, following suit, user_input is NULL here, not 0 or 2.

    //---|Main Program|---

    intro(user_input);

    //snip

    return 0;

【问题讨论】:

想想std::getline()的最后一次调用读取了什么,为什么它返回false,因此循环结束。 天哪。哦,天哪,哦,天哪。您是在告诉我它放入一个空行是因为它被调用了两次,而不是一次?我觉得好傻。在将其标记为已解决之前,我会确认我可以让它工作。 我不认为你真的是指NULL,是吗? “我的理解是,当在嵌套块中修改内容时,外部块无法识别更改——它们永远不会离开内部块的范围。”不,这不太对。对象的生命周期遵循此规则,但您在作用域内对现存对象所做的任何修改在退出作用域后都将持续存在;它不会全部“回滚”或任何东西。 我曾认为它是 NULL,因为它只是一个空格,并且因为我之前观察到与我的程序错误类似的行为是由意外设置为 NULL 的变量引起的。这是一个错误的假设。 【参考方案1】:

线条

    while (std::getline(inbound_filestream, user_input)) 
    

会将输入读入user_input 变量,直到没有更多输入可用。因此,您想要的内容仅在循环体内可用。

退出循环的最后一个循环,将设置user_input为空。

如果您想逐行收集流中的所有输入,您可能需要一个额外的变量来读取该行:

    std::string line;
    while (std::getline(inbound_filestream,line)) 
        user_input += line;
    

【讨论】:

事实证明,虽然您认为这是一个问题是对的,但我认为我发现这是问题的根源是完全错误的。我以为我已经隔离了导致更大问题的原因,即现在,我的程序正在运行所有内容,而不会停止从用户那里获取输入,即使我到处都有 std::getline(std::cin, variable_name) .所以感谢您的帮助,我会将其标记为正确,但我想我应该在进行更多筛选后提出一个新问题。 我终于解决了这个问题,如果您有兴趣了解或向我解释这个切线差异。我有一个字符串类型的输入解析函数。在其中,我使用“getline(cin, input)”,但在此之前,我(在手动调试期间)放置了“cin >> input”,并且输入是字符串类型。因为我试图 cin 到一个字符串,它“锁定”了我的输入流,我无法输入任何其他内容。您或其他任何人阅读的内容是否可以告诉我有关此行为的信息,以便我了解幕后发生的事情?

以上是关于偶然发现getline、fstream、范围不一致的主要内容,如果未能解决你的问题,请参考以下文章

c++ fstream 的问题

iostream fstream istringstream

fstream类怎么创建和删除文件?

C++ Getline 并不总是在 Linux 中的多个分叉进程中获得一致

c++程序中,iostream可以被fstream代替吗

在方法getline c ++之后切换语句反应错误