当我熟悉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
感谢任何帮助。谢谢。
答案 0 :(得分:1)
发生的事情是因为你只使用''(空格)作为分隔符,输入恰好是
1
2
3\n4 //<------ Newline also comes with the input
...
所以,你将3\n4
,6\n7
等传递给atoi
它返回3,6等(atoi解析输入直到第一个非数字输入)和{{1}失去了。
为了实现你想要的你可以使用带有istringstream的getline(将默认的分隔符保持为换行符)
4,7
答案 1 :(得分:0)
你可以使用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)
}
&#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纹理)重载。