【问题标题】:modify number of variables in istringstream修改 istringstream 中的变量数
【发布时间】:2017-04-03 12:03:17
【问题描述】:

我需要根据先前输入确定的可修改数量的变量在一行中获取输入。

如果你在前面的函数中得到的输入是 1,那么代码会是这样的

std::string istring;
std::getline(std::cin, istring);
std::istringstream stream(istring);
while (stream >> a)
{
   statement;
}

是否可以根据您的输入为 while 循环创建一个条件?所以如果输入是例如 5,它的行为就像

while (stream >> a >> a >> a >> a >> a)
{
   statement;
}

我尝试过 while ((stream>>a)*number) 但这不起作用

【问题讨论】:

  • 一定要使用istringstream吗?因为您也可以只创建一个字符串数组,例如:std::vector<std::string> istring 并在 for 循环中使用 std::getline
  • 每一行应该有多个输入变量。早些时候,程序会询问它将获取信息的人数,因此如果该数字是例如 3,那么每一行应该看起来像“1 2 3”或“3 4 5”等等。行数是任意的,但每行中的变量数取决于从先前输入确定的人数
  • 我希望你在那个语句中实际上没有a 5 次,而是你有不同的变量?
  • 实际上,据我所知,无论是 (stream>>a>>a>>a) 还是 (stream>>a>>b>>c),程序的行为都没有区别...但这不是让我感到困扰的事情
  • @SanderDeDycker 序列点参数不适用于此处。只要a 只是一个变量,操作的顺序是明确定义的。请记住,<< 扩展为下面的嵌套函数调用,必须以固定顺序执行。唯一未定义的是这些调用的参数评估顺序,但由于您直接传递变量a,因此不需要评估参数。您在此处为多个函数调用重用同一个变量这一事实并没有改变这一点。

标签: c++ istringstream sstream


【解决方案1】:

具体解决方案

首先回答您的具体问题:

我需要根据先前输入确定的可修改数量的变量在一行中获取输入。

C++ 中的解决方案是 istringstreamwhile 循环和 vector 的组合:

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

int main() {

    unsigned int earlierInput = 5;  // this is the earlier input
    std::vector<int> numbers;  // The type of vector also controls what
                               // data type you want the user to give
                               // you. Because the stream will try to
                               // the user input into that type.

    while (numbers.size() != earlierInput) {

        // Here we ask the user for input and convert the input
        // to a stream, like that we can try to convert the user
        // input into the data type we want.
        std::string istring;
        std::cout << "Please type in " << earlierInput << " numbers: ";
        std::getline(std::cin, istring);
        std::istringstream reader(istring);

        // read as many numbers as possible.
        for (int number; reader >> number;) {
            numbers.push_back(number);
        }

        if (numbers.size() != earlierInput) {
            // if not enough numbers empty vector and print
            // error message
            std::cout << "Not the right amount of numbers!";
            std::cout << "Try again!" << std::endl;
            numbers.clear();
        }
    }

    // If we get here the user typed in the right amount of numbers
    std::cout << "You typed the following numbers:" << std::endl;
    for (const int& i : numbers) {
        std::cout << i << std::endl;
    }
}

这仅用于一个用户输入。如果您想询问用户任意次数来执行此操作(例如,您想询问用户 10 次以获得 5 个数字),那么您需要再次应用上述规则并因此叠加:

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

int main() {

    unsigned int amountOfInputs = 2;  // this is the amount of times
                                      // you want the user to type
                                      // something in
    unsigned int earlierInput = 5;  // this is the earlier input


    std::vector<std::vector<int>> allNumbers; // Now we need a vector in
                                // a vector to store the results.
                                // The type of the inner vector also
                                // controls what data type you want the
                                // user to give you.

    while (allNumbers.size() != amountOfInputs) {
        std::vector<int> numbers; // This is the vector as in the example
                                  // above.

        while (numbers.size() != earlierInput) {
            // Here we ask the user for input and convert the input
            // to a stream, like that we can try to convert the user
            // input into the data type we want.
            std::string istring;
            std::cout << "Please type in " << earlierInput << " numbers: ";
            std::getline(std::cin, istring);
            std::istringstream reader(istring);

            // read as many numbers as possible.
            for (int number; reader >> number;) {
                numbers.push_back(number);
            }

            if (numbers.size() != earlierInput) {
                // if not enough numbers empty vector and print
                // error message
                std::cout << "Not the right amount of numbers!";
                std::cout << "Try again!" << std::endl;
                numbers.clear();
            }
        }

        // If we get here the user typed in the right amount of numbers
        // and we can save them and clear the array for using it again.
        allNumbers.push_back(numbers);
        numbers.clear();
    }

    std::cout << "You typed the following numbers:" << std::endl;
    unsigned int round = 1;
    for (auto numbersOfRound : allNumbers) {
        std::cout << "For round " << round++ << ": ";
        for (auto i: numbersOfRound) {
            std::cout << i;
        }
        std::cout << std::endl;
    }
}

理论

为什么选择向量

要保存任意数量的数据并能够访问它,您必须使用动态分配的数组或类似的东西。这是因为在编译时您不知道在运行时需要多少变量,因此您无法为所有变量命名。

为什么是流

理论上,流可能是无限长的字符串或数据(另请参阅here)。因此,用户输入是stream,因为理论上它可能是无限长的。虽然这在实践中并不适用。

要从流中提取信息,必须使用&gt;&gt; 运算符,也称为提取运算符。如文档here 中所述,此运算符不支持将vectors 作为(rhs)操作数。它只支持基本数据类型(这就是为什么我们在上面的例子中需要一个临时变量int number)。

【讨论】:

  • 我认为您误解了问题。您编写的代码需要一个数字,然后检查数组大小是否等于该数字,但它不必相等。唯一的条件是您每次输入 5 个变量。输入一行输入多少次是任意的。因此,如果有 5 个人,在绝大多数情况下,数组最终不会有 5 个变量,而是 5xN。
  • 编辑:我写了“唯一的条件是你每次都输入 N 个变量的输入”。 N 应该是 5 以避免与我后来写的内容混淆。我编辑了它
  • 我认为更简单的解决方案是,如果代码与您之前发布的代码一样,但在 while 循环中添加了一个 for 循环,该循环将输入添加到属于 vector[i] 点,即用于将特定人的所有输入相加。我想我知道我现在可以做些什么来让它运行,但是这两种解决方案都是 hacky - 仍然不知道如何使用输入流来做到这一点。但是感谢您的努力
  • 输入流只能在空格处划分输入。所以实际上你可以做点什么。看上面while循环的条件。它实际上正在做你想要的。
  • 你还是没抓住重点。行数不应等于输入的人数。人数是用来确定在每一行中输入了多少变量——每人一个。我尝试运行代码,它的作用是输入 5 行输入,其中每行可以包含任意数量的变量,而它应该采用任意数量的输入行,其中每行应包含 5 个变量。
猜你喜欢
  • 1970-01-01
  • 2012-01-15
  • 2015-11-11
  • 1970-01-01
  • 2017-11-03
  • 1970-01-01
  • 2017-06-26
  • 2012-11-28
相关资源
最近更新 更多