在 C++ 中读取引用的字符串

问题描述 投票:0回答:2

我正在尝试从文件中读取带引号的字符串并将其存储在字符串中。我正在从文件中读取字符串,输入文件是这样的:

"Rigatoni" starch 2.99
"Mac & Cheese" starch 0.50
"Potato Salad" starch 3.59
"Fudge Brownie" sweet 4.99
"Sugar Cookie" sweet 1.50

我尝试做几件事:

1.

input.open(filename);
    if (input.fail())
    {
        std::cout << "File is not found!";
        exit(1);
    }   
    else
    {    
        std::string foodName = ""; std::string foodType = "";
        double cost;
        input >> foodName >> foodType >> cost;
        foodName = foodName.substr(1, foodName.size()-2);    
        std::cout << foodName << " " << foodType << " " << cost << std::endl;
    }


    input.close();

此版本仅适用于第一行。在第一行之后我没有得到完整的引用词。另一个版本读取整个引用的单词,但是,后面的单词和数字是分开的。

input.open(filename);
        if (input.fail())
        {
            std::cout << "File is not found!";
            exit(1);
        }   
        else
        {


            std::string line = "";
            while (std::getline(input, line, '\n')) //delimeter is new line
            {
                if (line != "")
                {
                    std::stringstream stream(line);
                    std::string foodName = "";
                    while (std::getline(stream, foodName, '"') ) //delimeter is double quotes
                    {                   
                        std::cout << "current word " << foodName << std::endl;
                    }
                }
            }
        }   input.close();

我的目标是阅读 3 个单独的单词。我查看了 stackoverflow 中的其他类似主题,但找不到适合我问题的正确解决方案

c++ ifstream
2个回答
16
投票

这对于 C++14 来说变得微不足道

std::quoted

#include <iomanip>
std::string foodName, foodType;
double cost;
while (fs >> std::quoted(foodName) >> foodType >> cost)
{
}

是的,这会将

"some word"
正确解析为
some word
。没有支持 C++14 的编译器? (你应该,例如 Fedora 22 附带 GCC 5.1.0)然后使用 Boost。标准库在这个 Boost 组件之后建模
std::quoted
,所以它应该可以正常工作。

你的代码还有一些问题:

  1. Streams 有一个到 bool 的转换运算符。这意味着您可以:

    if (!input.open(filename)) { ... }

  2. input.close()
    是多余的。析构函数将自动关闭流。

  3. 您不检查输入是否有效,即

    if (!(input >> a >> b >> c)) { // error }


6
投票

我经常用这个来阅读引号之间的内容:

std::string skip; // throw this away
std::string foodName;
std::getline(std::getline(input, skip, '"'), foodName, '"');

第一个 std::getline 读取(并删除)第一个引号。它返回输入流,因此您可以将其包装在另一个 std::getline 中,该变量读取您的变量直到结束引号。

例如这样的:

#include <string>
#include <sstream>
#include <iostream>

std::istringstream input(R"~(
"Rigatoni" starch 2.99
"Mac & Cheese" starch 0.50
"Potato Salad" starch 3.59
"Fudge Brownie" sweet 4.99
"Sugar Cookie" sweet 1.50
)~");

int main()
{
    std::string skip; // dummy
    std::string foodName;
    std::string foodType;
    float foodValue;

    while(std::getline(std::getline(input, skip, '"'), foodName, '"') >> foodType >> foodValue)
    {
        std::cout << "food : " << foodName << '\n';
        std::cout << "type : " << foodType << '\n';
        std::cout << "value: " << foodValue << '\n';
        std::cout << '\n';
    }
}

输出:

food : Rigatoni
type : starch
value: 2.99

food : Mac & Cheese
type : starch
value: 0.5

food : Potato Salad
type : starch
value: 3.59

food : Fudge Brownie
type : sweet
value: 4.99

food : Sugar Cookie
type : sweet
value: 1.5
© www.soinside.com 2019 - 2024. All rights reserved.