首页 文章

C:从cin读取整数行

提问于
浏览
0

由于我熟悉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向量,但是我遇到了一些处理'\ n'字符的问题 . 我的代码是:

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

通过打印出“temp”向量中的所有元素得到的最终结果是:

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

任何帮助表示赞赏 . 谢谢 .

5 回答

  • 0

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

    当流为空时,设置eofbit,因此在其上运行while循环 .

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

  • 1

    你可以使用stringstream

    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)
    }
    
  • 0

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

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

    所以,你将 3\n46\n7 等传递给 atoi 它返回3,6等(atoi解析输入直到第一个非数字输入)并且 4,7 丢失 .

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

    string rawInput;
    vector<vector<int>> temp;
    while(getline(cin, rawInput) ){
      istringstream bufferInput(rawInput); 
      temp.push_back(vector<int>{std::istream_iterator<int>{bufferInput}, std::istream_iterator<int>{}});
    }
    
  • 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";
        }
    }
    
  • 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>{});
    }
    

相关问题