简体   繁体   English

C++ 中的格式化输入。 像这样---> x: y: z

[英]Formatted input in C++ . like this ---> x : y : z

I want to take inputs in this format (x: y: z) in C++ language.我想在 C++ 语言中以这种格式(x:y:z)输入。 in the input section the input formation will be like this:在输入部分,输入格式将是这样的:

x: y: z x: y: z

where, x,y and z are three separate integer type inputs.其中,x,y 和 z 是三个独立的 integer 类型输入。

You can simply read it from any stream like this您可以像这样简单地从任何 stream 读取它

#include <iostream>

int main() {

    int x, y, z;
    char colon;

    if (std::cin >> x >> colon >> y >> colon >> z) {

        std::cout << "\nYou entered:\t" << x << "\t" << y << "\t" << z;
    }
    else {
        std::cerr << "\nError: Wrong input format\n";
    }
    return 0;
}

EDIT: Based on the comment of Alan Birtles I will add input validation.编辑:根据 Alan Birtles 的评论,我将添加输入验证。 Although, I could not read that in the question.虽然,我无法在问题中阅读。

And before people want to generalize the question, I will also answer that.在人们想要概括这个问题之前,我也会回答这个问题。

But first.但首先。 You can also use:您还可以使用:

 if ((std::cin >> x >> colon) && (colon ==':') && (std::cin >> y >> colon) && (colon == ':') && (std::cin >> z)) {

I do not think that anybody cares about that, but, just to be complete.我认为没有人关心这一点,但是,只是为了完整。 . . . .


For the general case.对于一般情况。 You should maybe better use std::getline to read a complete line of input and then split it.您最好使用std::getline来读取完整的输入行,然后将其拆分。

You never need boost for such a task.你永远不需要提升这样的任务。

See some common patterns for splitting a string:查看拆分字符串的一些常见模式:

Splitting a string into tokens is a very old task.将字符串拆分为标记是一项非常古老的任务。 There are many many solutions available.有许多可用的解决方案。 All have different properties.都有不同的属性。 Some are difficult to understand, some are hard to develop, some are more complex, slower or faster or more flexible or not.有些难以理解,有些难以开发,有些更复杂,更慢或更快或更灵活或不灵活。

Alternatives备择方案

  1. Handcrafted, many variants, using pointers or iterators, maybe hard to develop and error prone.手工制作,许多变体,使用指针或迭代器,可能难以开发且容易出错。
  2. Using old style std::strtok function.使用旧式std::strtok function。 Maybe unsafe.也许不安全。 Maybe should not be used any longer也许不应该再使用了
  3. std::getline . std::getline Most used implementation.最常用的实现。 But actually a "misuse" and not so flexible但实际上是一种“误用”,并没有那么灵活
  4. Using dedicated modern function, specifically developed for this purpose, most flexible and good fitting into the STL environment and algortithm landscape.使用专门为此目的开发的专用现代 function,最灵活且最适合 STL 环境和算法环境。 But slower.但是比较慢。

Please see 4 examples in one piece of code.请在一段代码中查看 4 个示例。

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <regex>
#include <algorithm>
#include <iterator>
#include <cstring>
#include <forward_list>
#include <deque>

using Container = std::vector<std::string>;
std::regex delimiter{ "," };


int main() {

    // Some function to print the contents of an STL container
    auto print = [](const auto& container) -> void { std::copy(container.begin(), container.end(),
        std::ostream_iterator<std::decay<decltype(*container.begin())>::type>(std::cout, " ")); std::cout << '\n'; };

    // Example 1:   Handcrafted -------------------------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Search for comma, then take the part and add to the result
        for (size_t i{ 0U }, startpos{ 0U }; i <= stringToSplit.size(); ++i) {

            // So, if there is a comma or the end of the string
            if ((stringToSplit[i] == ',') || (i == (stringToSplit.size()))) {

                // Copy substring
                c.push_back(stringToSplit.substr(startpos, i - startpos));
                startpos = i + 1;
            }
        }
        print(c);
    }

    // Example 2:   Using very old strtok function ----------------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Split string into parts in a simple for loop
#pragma warning(suppress : 4996)
        for (char* token = std::strtok(const_cast<char*>(stringToSplit.data()), ","); token != nullptr; token = std::strtok(nullptr, ",")) {
            c.push_back(token);
        }

        print(c);
    }

    // Example 3:   Very often used std::getline with additional istringstream ------------------------------------------------
    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };
        Container c{};

        // Put string in an std::istringstream
        std::istringstream iss{ stringToSplit };

        // Extract string parts in simple for loop
        for (std::string part{}; std::getline(iss, part, ','); c.push_back(part))
            ;

        print(c);
    }

    // Example 4:   Most flexible iterator solution  ------------------------------------------------

    {
        // Our string that we want to split
        std::string stringToSplit{ "aaa,bbb,ccc,ddd" };


        Container c(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});
        //
        // Everything done already with range constructor. No additional code needed.
        //

        print(c);


        // Works also with other containers in the same way
        std::forward_list<std::string> c2(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {});

        print(c2);

        // And works with algorithms
        std::deque<std::string> c3{};
        std::copy(std::sregex_token_iterator(stringToSplit.begin(), stringToSplit.end(), delimiter, -1), {}, std::back_inserter(c3));

        print(c3);
    }
    return 0;
}

A possibility is boost::split() , which allows the specification of multiple delimiters and does not require prior knowledge of the size of the input:一种可能性是boost::split() ,它允许指定多个分隔符,并且不需要事先了解输入的大小:

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

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/split.hpp>

int main()
{
    std::vector<std::string> tokens;
    std::string s("x:y:z");
    boost::split(tokens, s, boost::is_any_of(":"));

    // "x"  == tokens[0]
    // "y"  == tokens[1]
    // "z"  == tokens[2]

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 运算符重载C ++(x == y == z) - operator overloading c++ (x==y==z) myClass(x,y,z)=值的C ++运算符重载 - C++ operator overloading for myClass(x,y,z) = value 在C ++中,“ x(y)= z(w)”是什么意思? - What does “x(y) = z(w)” mean in C++? C ++中的格式化输入 - Formatted input in c++ 有没有办法像 python:np.concatenate([x,y,z],axis=1) 中的方式一样在 C++ 中沿着列连接三个二维向量? - Is there a way to concatenate three two-dimensional vectors along the Column in C++ like the way in python:np.concatenate([x,y,z], axis=1)? 在3D中查找X,Y和Z轴的角度 - OpenGL / C ++ - Finding the angles for the X, Y and Z axis in 3D - OpenGL/C++ 在DirectX 11.2 C ++中围绕所有3个(X,Y,Z)轴旋转模型 - Rotating a model around all 3 (X, Y, Z) axis in DirectX 11.2 C++ C ++二叉树错误:请求(Y)中非类类型(Z)的成员(X) - C++ Binary Tree error: request for member (X) in (Y) which is of non-class type (Z) C ++:奇怪的出现“请求Y成员X的非类型Z” - C++: bizarre occurrence of “Request for member X of Y which is of non-class type Z” 使用OpenGL在C ++中同时围绕(x,y&z)轴旋转对象 - Roatating an Object around its (x,y&z) axis contemporaneously in C++ using OpenGL
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM