【问题标题】:How to read multiple data types in a file line c++如何在文件行中读取多种数据类型c ++
【发布时间】:2021-09-20 21:25:10
【问题描述】:

我的代码会将变量写入文件作为备份系统。当用户重新运行代码时,我需要复制文件数据并保存到变量中。

John McClane, 31, 1.76

该文件将始终按此顺序包含一个字符串、一个整数和一个双精度数。 考虑到总是用逗号分隔,是否有一个函数可以轻松读取变量?最好使用txt或csv文件类型?

【问题讨论】:

  • 查看使用std::getline() 从任何std::istream 读取整行以及分隔字符串。从std::ifstream 中读取一行,将字符串放入std::istringstream,使用',' 作为分隔符从中读取子字符串。根据需要使用operator>>std::stoi()/std::stod() 将子字符串转换为整数/浮点数。

标签: c++ file


【解决方案1】:

很好地学习iostream 的问题。

让我们从头开始。你可能见过类似的东西:

std::cout << value1 << ',' << value2 << ',' << value3 << '\n';

秘诀是重载运算符&lt;&lt;,可以实现为:

std::ostream& operator << (std::ostream& os, const SomeType& st)

对于许多标准数据类型,该运算符被重载。可以将其链接起来的秘密之一是它返回对给定流的引用。 (请注意,这个函数也可以显式调用)

所以,如果你写:

std::cout << value;

然后,它将值写入std::cout 并返回对给定流std::cout 的引用。如果我们看一下上面的链式调用,那么在 value1 被写入之后,std::cout 被返回。然后要处理的新的 rest 语句将是

std::cout << ',' << value2 << ',' << value3 << '\n';

然后它将输出命令并再次返回std::cout。结果将是:

std::cout << value2 << ',' << value3 << '\n'; // then next
std::cout << ',' << value3 << '\n'; // then next
std::cout << value3 << '\n'; // then next
std::cout << '\n'; // then next
std::cout  // then next

您现在可能会问,为什么我列出最后一行很重要。也就是说,因为流的bool 运算符和!(非)运算符都被覆盖了。请阅读herehere。因此,如果您在条件上下文中使用流,例如在ifforwhile 中。因此,打开一个流后,你可以简单地写:if (stream),你就知道没有错误。

如果你想循环读取值,那么你可以写

while (filestream >> v1 >> v2 >> v3) {   . . . 

然后它将按照上述方式进行所有提取,其余语句将为while(filestream)。将调用流的 bool 运算符并检查是否一切正常,或者它们是否失败或 eof(文件结束)。

接下来,了解格式化和非格式化操作的机制很重要。以上都是格式化的。提取器运算符会将流数据转换为您的类型的值。它不会读取任何空格,包括换行符'\n'。在读取下一个值之前,它会先跳过所有的空格,然后读取并转换下一个值,而不是读取尾随的空格。

std::getline 这样的非格式化输入函数将读取完整的一行,不进行任何转换并从流中消耗最后一个新行'\n'。

这会导致许多理解问题,并且是许多错误的根源。

R.g.如果您有从格式化输入到非格式化输入的转换,则会发生以下情况。 std::cin &gt;&gt; value 中的最后一个格式化输入将读取该值并进行转换。它不会读取换行符。这仍然在流中。并且,对std::getline 的后续调用将一直读取到换行符,它会立即找到它作为第一个字符,作为先前格式化读取的剩余字符,因此什么也不做。

因此,如果存在从格式化输入到未格式化输入的转换,则需要去掉新行(或其他空格)。为此,我们在库中有一个操纵器。它被称为std::ws,并且完全符合我们的要求。请参阅here。它将丢弃输入流中的前导空格。很好。

那么我们现在来看一些示例代码:

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

const std::string fileName{ "data.txt" };

int main() {

    // Open file and check, if it could be opened
    if (std::ifstream inputFileStream{ fileName }; inputFileStream) {

        // We want toread 3 values
        std::string name{};
        int iValue{};
        double dValue{};
        char comma{};

        // Read data from file, convert them to there data type and read until eof
        while (std::getline(inputFileStream >> std::ws, name, ',') >> iValue >> comma >> dValue) {

            // Show output
            std::cout << name << " --> " << iValue << " --> " << dValue << '\n';
        }
    } // Error message, if file could not be opened
    else std::cerr << "\nError:Could not open file '" << fileName << "'\n\n";
    return 0;
}

请应用上面的诀窍。首先将调用inputFileStream &gt;&gt; std::ws,它将返回inputFileStream。然后将调用std::getline,这将返回inputFileStream。然后会调用inputFileStream &gt;&gt; Name,返回inputFileStream,以此类推。

我希望,我可以把一些事情说得更清楚。

【讨论】:

    猜你喜欢
    • 2020-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多