C ++:从cin中读取整数行

时间:2016-04-01 20:20:36

标签: c++

当我熟悉C ++的I / O方面时,我试图编写一个程序来读取std :: cin中的一些整数行。说输入如下:

1 2 3
4 5 6
7 8 9
10 11 12

如何将上述行读入2D矢量?

vector<vector<int>> nums;
/* 
 ... some code here and nums will look like the following:
 nums = {
    {1,2,3},
    {4,5,6},
    {7,8,9},
    {10,11,12}
  }
*/

我也尝试将上面的整数行读到1D向量,但我在处理&#39; \ n&#39;字符。我的代码是:

string rawInput;
vector<int> temp;
while(getline(cin, rawInput, ' ') ){
  int num = atoi( rawInput.c_str() );
  temp.push_back(num);
 }

我通过打印出&#34; temp&#34;中的所有元素得到的最终结果。矢量是:

1 2 3 5 6 8 9 11 12   // 4, 7, 10 went missing

感谢任何帮助。谢谢。

5 个答案:

答案 0 :(得分:1)

发生的事情是因为你只使用''(空格)作为分隔符,输入恰好是

1
2
3\n4 //<------ Newline also comes with the input

...

所以,你将3\n46\n7等传递给atoi它返回3,6等(atoi解析输入直到第一个非数字输入)和{{1}失去了。

为了实现你想要的你可以使用带有istringstream的getline(将默认的分隔符保持为换行符)

4,7

答案 1 :(得分:0)

你可以使用stringstream

&#13;
&#13;
string rawInput;
vector<int> temp;
stringstream ss;

while(getline(cin,rawInput)){
  ss<<rawInput;
  vector<int> temp;
  int x;
  
  while(ss>>x){
    temp.push_back(x);
  }
  
  num.push_back(temp)
}
&#13;
&#13;
&#13;

答案 2 :(得分:0)

首先使用getline抓取整行,然后您可以使用istringstream为该行创建int的流。

此时,只需使用带有两个迭代器的向量构造函数创建int的每个子向量。 istringstream上的istream_iterator<int>可以完成此操作:

std::vector<std::vector<int>> nums;
std::string line;
while (std::getline(std::cin, line)) {
    std::istringstream ss(line);
    nums.emplace_back(std::istream_iterator<int>{ss}, std::istream_iterator<int>{});
}

答案 3 :(得分:0)

我最近写了另一个问题的答案,但经过一些调整后,它完全符合您的要求(我希望):

#ifndef _IOSTREAM_H
#include <iostream>
#endif
#ifndef _STRING_H
#include <string>
#endif
#ifndef _VECTOR_H
#include <vector>
#endif

using namespace std;

enum XYZ { X = 0, Y = 1, Z = 2 };

struct Vector {
    float x, y, z;
    Vector(float _x=0, float _y=0, float _z=0) {
        x = _x;
        y = _y;
        z = _z;
    }
    float& operator[](size_t index) {
        if (index == XYZ::X) return x;
        if (index == XYZ::Y) return y;
        if (index == XYZ::Z) return z;
        throw new exception;
    }
};



#define min(a, b) (((a) < (b)) ? (a) : (b))

bool isCharNumeric(char c) {
    const char* numbers = "0123456789";
    for (size_t index = 0; index < strlen(numbers); index++)
        if (c == numbers[index]) return true; return false;
}

vector<Vector> parseNumbers(string str_in) {
    str_in += "  "; //safe, no out of bounds
    vector<Vector> results = {};
    char currentChar;
    char skipChar = ' ';
    bool found_period = false;
    size_t count_len = 0;
    Vector vector_buffer(0,0,0);
    XYZ current_axis = (XYZ)0;
    for (size_t index = 0; index < str_in.length(); index++) {
        currentChar = str_in[index];
        if (currentChar == skipChar || currentChar == '\n' || currentChar == '\t')
            continue;

        else if (isCharNumeric(currentChar)) {
            string word = ""; //word buffer
            size_t word_len = min(min(str_in.find_first_of(' ', index + 1) - (index), str_in.find_first_of('\n', index + 1) - (index)), str_in.find_first_of('\t', index + 1) - (index)); //whatever char comes first; newline, tab or space
                                                                                                                                                              //append chars of following word checking if it is still valid number char
            if (word_len > 0) {
                size_t count_word_len = 0;
                for (count_word_len = 0; count_word_len < word_len; count_word_len++)
                    if (isCharNumeric(str_in[index + count_word_len])) {
                        word += str_in[index + count_word_len];
                    }
                    else if (str_in[index + count_word_len] == '.' && isCharNumeric(str_in[index + count_word_len + 1])) {
                        //Floating-point numbers
                        word += '.';
                        found_period = true;
                        continue;
                    }
                    else {
                        word = "";
                        continue;
                    }

                    vector_buffer[current_axis] = stof(word);


                    if (current_axis == XYZ::Z) {
                        current_axis = XYZ::X;
                        results.push_back(vector_buffer);
                    }
                    else {
                        current_axis = (XYZ)(current_axis + 1);
                    }


                    index += count_word_len;
                    word = "";
                    continue;
            }

        }
    }
    return results;
}

示例实施:

int main(int argc, char** argv) {
    string user_input;
    cin >> user_input;
    vector<Vector> numbers = parseNumbers(user_input);
    for each (Vector v in numbers) {
        cout << "X=" << v.X << "\n";
        cout << "Y=" << v.Y << "\n";
        cout << "Z=" << v.Z << "\n\n";
    }
}

答案 4 :(得分:0)

令人惊讶的是,没有一个答案使用istream流运算符: http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/

当stream为空时,设置了eofbit,因此在其上运行while循环。

适用于所有类型,并且可以为自定义类型(例如2D纹理)重载。