Read matrix from text file using vectors in C++ - c++

we have a matrix in text file like this with commas between numbers, but there is no comma at the end of each line.
1,2,3,4
7,8,2,1
3,4,5,6
7,2,1,3
I was trying to do this with a 2D array like this but it wasn't really working out because also size of matrix is unknown.
string array[4][4];
int id;
for (int i = 0; i < 4; i++) { // go through each line
for (int j = 0; j < 4; j++) {
getline(filein, numbers, ',');
array[i][j] = numbers;
cout << array[i][j] << endl;
}
}
I want to do that with using 2D vectors but I have no idea how to do that. Like after creating a vector with
vector<vector<string>> matrix;
Should I create one more vector inside the loops?

Use vector of vectors. Here is the commentary for each line:
std::vector<std::vector<int>> v; // declare vector of vectors
std::ifstream ifs("myfile.txt"); // open the file
std::string tempstr; // declare a temporary string
int tempint; // declare a temporary integer
char delimiter; // declare a temporary delimiter
while (std::getline(ifs, tempstr)) { // read line by line from a file into a string
std::istringstream iss(tempstr); // initialize the stringstream with that string
std::vector<int> tempv; // declare a temporary vector for the row
while (iss >> tempint) { // extract the numbers from a stringstream
tempv.push_back(tempint); // push it onto our temporary vector
iss >> delimiter; // read the , delimiter
}
v.push_back(tempv); // push the vector onto vector of vectors
}
The full source code is:
#include <iostream>
#include <fstream>
#include <vector>
#include <sstream>
#include <string>
int main() {
std::vector<std::vector<int>> v;
std::ifstream ifs("myfile.txt");
std::string tempstr;
int tempint;
char delimiter;
while (std::getline(ifs, tempstr)) {
std::istringstream iss(tempstr);
std::vector<int> tempv;
while (iss >> tempint) {
tempv.push_back(tempint);
iss >> delimiter;
}
v.push_back(tempv);
}
for (auto row : v) {
for (auto el : row) {
std::cout << el << ' ';
}
std::cout << "\n";
}
}

Use a double std::vector, read the file line by line, and parse the commas as well, and you are done. Every time you read a line, increase the vector's size by 1. You can do that with std::vector::resize().
Example, using your file as "matrix.txt":
#include <iostream>
#include <sstream>
#include <string>
#include <fstream>
#include <vector>
int main(void) {
std::vector<std::vector<int>> matrix;
std::ifstream infile("matrix.txt");
int a, b, c, d;
char comma;
while (infile >> a >> comma >> b >> comma >> c >> comma >> d)
{
//std::cout << a << " " << b << " " << c << " " << d << std::endl;
matrix.resize(matrix.size() + 1);
matrix[matrix.size() - 1].push_back(a);
matrix[matrix.size() - 1].push_back(b);
matrix[matrix.size() - 1].push_back(c);
matrix[matrix.size() - 1].push_back(d);
}
for(auto row: matrix) {
for(auto v: row) {
std::cout << v << " ";
}
std::cout << "\n";
}
return 0;
}
Output:
Georgioss-MacBook-Pro:~ gsamaras$ g++ -std=c++0x main.cpp
Georgioss-MacBook-Pro:~ gsamaras$ ./a.out
1 2 3 4
7 8 2 1
3 4 5 6
7 2 1 3

Related

How to read a CSV dataset in which each row has a distinct length. C++

I'm just new to C++ and am studying how to read data from csv file.
I want to read the following csv data into vector. Each row is a vector. The file name is path.csv:
0
0 1
0 2 4
0 3 6 7
I use the following function:
vector<vector<int>> read_multi_int(string path) {
vector<vector<int>> user_vec;
ifstream fp(path);
string line;
getline(fp, line);
while (getline(fp, line)) {
vector<int> data_line;
string number;
istringstream readstr(line);
while (getline(readstr, number, ',')) {
//getline(readstr, number, ',');
data_line.push_back(atoi(number.c_str()));
}
user_vec.push_back(data_line);
}
return user_vec;
}
vector<vector<int>> path = read_multi_int("C:/Users/data/paths.csv");
Print funtion:
template <typename T>
void print_multi(T u)
{
for (int i = 0; i < u.size(); ++i) {
if (u[i].size() > 1) {
for (int j = 0; j < u[i].size(); ++j) {
//printf("%d ", u[i][j]);
cout << u[i][j] << " ";
}
printf("\n");
}
}
printf("\n");
}
Then I get
0 0 0
0 1 0
0 2 4
0 3 6 7
Zeros are added at the end of the rows. Is possible to just read the data from the csv file without adding those extra zeros? Thanks!
Based on the output you are seeing and the code with ',' commas, I beleive that your actual input data really looks like this:
A,B,C,D
0,,,
0,1,,
0,2,4,
0,3,6,7
So the main change is to replace atoi with strtol, as atoi will always return 0 on a failure to parse a number, but with strtol we can check if the parse succeeded.
That means that the solution is as follows:
vector<vector<int>> read_multi_int(string path) {
vector<vector<int>> user_vec;
ifstream fp(path);
string line;
getline(fp, line);
while (getline(fp, line)) {
vector<int> data_line;
string number;
istringstream readstr(line);
while (getline(readstr, number, ',')) {
char* temp;
char numberA[30];
int numberI = strtol(number.c_str(), &temp, 10);
if (temp == number || *temp != '\0' ||
((numberI == LONG_MIN || numberI == LONG_MAX) && errno == ERANGE))
{
// Could not convert
}else{
data_line.emplace_back(numberI);
}
}
user_vec.emplace_back(data_line);
}
return user_vec;
}
Then to display your results:
vector<vector<int>> path = read_multi_int("C:/Users/data/paths.csv");
for (const auto& row : path)
{
for (const auto& s : row) std::cout << s << ' ';
std::cout << std::endl;
}
Give the expected output:
0
0 1
0 2 4
0 3 6 7
Already very good, but there is one obvious error and another error in your print function. Please see, how I output the values, with simple range based for loops.
If your source file does not contain a comma (','), but a different delimiter, then you need to call std::getline with this different delimiter, in your case a blank (' '). Please read here about std::getline.
If we then use the following input
Header
0
0 1
0 2 4
0 3 6 7
with the corrected program.
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
vector<vector<int>> read_multi_int(string path) {
vector<vector<int>> user_vec;
ifstream fp(path);
string line;
getline(fp, line);
while (getline(fp, line)) {
vector<int> data_line;
string number;
istringstream readstr(line);
while (getline(readstr, number, ' ')) {
//getline(readstr, number, ',');
data_line.push_back(atoi(number.c_str()));
}
user_vec.push_back(data_line);
}
return user_vec;
}
int main() {
vector<vector<int>> path = read_multi_int("C:/Users/data/paths.csv");
for (vector<int>& v : path) {
for (int i : v) std::cout << i << ' ';
std::cout << '\n';
}
}
then we receive this as output:
0
0 1
0 2 4
0 3 6 7
Which is correct, but unfortunately different from your shown output.
So, your output routine, or some other code, may also have some problem.
Besides. If there is no comma, then you can take advantage of formatted input functions using the extraction operator >>. This will read your input until the next space and convert it automatically to a number.
Additionally, it is strongly recommended, to initialize all variables during definition. You should do this always.
Modifying your code to use formatted input, initialization, and, maybe, better variable names, then it could look like the below.
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
vector<vector<int>> multipleLinesWithIntegers(const string& path) {
// Here we will store the resulting 2d vector
vector<vector<int>> result{};
// Open the file
ifstream fp{ path };
// Read header line
string line{};
getline(fp, line);
// Now read all lines with numbers in the file
while (getline(fp, line)) {
// Here we will store all numbers of one line
vector<int> numbers{};
// Put the line into an istringstream for easier extraction
istringstream sline{ line };
int number{};
while (sline >> number) {
numbers.push_back(number);
}
result.push_back(numbers);
}
return result;
}
int main() {
vector<vector<int>> values = multipleLinesWithIntegers("C:/Users/data/paths.csv");
for (const vector<int>& v : values) {
for (const int i : v) std::cout << i << ' ';
std::cout << '\n';
}
}
And, the next step would be to use a some more advanced style:
#include <vector>
#include <fstream>
#include <iostream>
#include <string>
#include <sstream>
#include <iterator>
auto multipleLinesWithIntegers(const std::string& path) {
// Here we will store the resulting 2d vector
std::vector<std::vector<int>> result{};
// Open the file and check, if it could be opened
if (std::ifstream fp{ path }; fp) {
// Read header line
if (std::string line{}; getline(fp, line)) {
// Now read all lines with numbers in the file
while (getline(fp, line)) {
// Put the line into an istringstream for easier extraction
std::istringstream sline{ line };
// Get the numbers and add them to the result
result.emplace_back(std::vector(std::istream_iterator<int>(sline), {}));
}
}
else std::cerr << "\n\nError: Could not read header line '" << line << "'\n\n";
}
else std::cerr << "\n\nError: Could not open file '" << path << "'\n\n'";
return result;
}
int main() {
const std::vector<std::vector<int>> values{ multipleLinesWithIntegers("C:/Users/data/paths.csv") };
for (const std::vector<int>& v : values) {
for (const int i : v) std::cout << i << ' ';
std::cout << '\n';
}
}
Edit
You have shown your output routine. That should be changed to:
void printMulti(const std::vector<std::vector<int>>& u)
{
for (int i = 0; i < u.size(); ++i) {
if (u[i].size() > 0) {
for (int j = 0; j < u[i].size(); ++j) {
std::cout << u[i][j] << ' ';
}
std::cout << '\n';
}
}
std::cout << '\n';
}

C++, reading doubles from txt into vector, problems with reading the whole file

I have a text file with 2 columns of doubles with a tab in between, and try to read them into 2 vectors. My first problem is that it does not go through the whole file but starts in the last third. My second problem is that while it does push_back it converts the numbers in some other numbers.. I just can't get my head around it..
If I try to just put them all into one string vector it works without problems, but I need them as doubles or int for further processing
ifstream myfile("TextFile",ios::in);
if (!myfile)
{
cout << "Can't open" << endl;
system("pause");
return -1;
}
vector<long double> Datenx;
vector<long double> Dateny;
vector<string>lel;
string line;
while (getline(myfile, line)) {
// lel.push_back(line);
string numberx = line.substr(0, 12);
int pos = line.find(" ");
string numbery = line.substr(pos + 1, 12);
stringstream iss(numberx);
long double x = 0.0;
iss>> setprecision(10)>>fixed >>showpoint >> x;
//cout <<fixed<< numberx << endl;
//cout<<setprecision(10)<<fixed<< x << endl;
Datenx.push_back(x);
stringstream is(numbery);
long double y = 0.0;
is >> y;
Dateny.push_back(y);
}
for (int n = 0; n < 100; n++) {
cout << Datenx[n] << ' ' << endl;
}
// cout << fixed << Datenx[2] << ' ' << endl;
cin.get();
return 0;
Part of input file:
0.0000000000 0.0006536954
0.0000000100 0.0005515555
0.0000000200 0.0005004856
0.0000000300 0.0001327819
0.0000000400 0.0006945514
0.0000000500 0.0007864773
0.0000000600 0.0001327819
0.0000000700 0.0007354074
Output: Datenx vector:
0
1e-08
2e-08
3e-08
...
Output: Dateny vector:
0.000653695
0.000551555
0.000500486
0.000132782
so the Dateny is kinda right.. it cuts the last digit
and the Datenx vector is total wrong..
Try to keep it simple first. If it works, you can add functionality.
#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
int main()
{
std::vector<double> v1, v2;
std::string line;
std::ifstream myFile("input.txt");
while(getline(myFile, line))
{
std::istringstream lineStream(line);
double first, second;
lineStream >> first >> second;
v1.push_back(first);
v2.push_back(second);
}
}
I tried this, with the following "input.txt"
1.1 1.2
2.1 2.2
3.1 3.2
4.1 4.2
5.1 5.2

Parsing through text file with C++

I am trying to figure out the best way to read in numbers from a text file and set these numbers to variables. I am having trouble because there will be multiple text files that will be testing my code and they are all of different lengths and sizes. A sample test one looks like this:
0 (1,3) (3,5)
1 (2,6)
2 (4,2)
3 (1,1) (2,4) (4,6)
4 (0,3) (2,7)
Where the first number represents a vertex on a graph, the first number in a coordinate is the vertex it is going towards in a directed graph, and the second number is the weight of the edge. I tried doing getline and putting it into arrays but in certain test cases there could be 100 coordinates and I am not sure how to specify array size. I am also having trouble parsing through the parenthesis and comma and am not sure how to initialize the variables with the correct number from the text file.
Parsing shouldn't be that difficult, espacially when you can use std::stringstream to separate all the elements from input. Indeed, you want to remove all the paranthesis first then emplace the elements into the container.
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <cctype>
int main()
{
std::ifstream read("file.txt");
std::vector<std::vector<std::pair<int, int>>> graph;
// read until you reach the end of the file
for (std::string line; std::getline(read, line); ) {
// removing punctuation like paranthesis, commas, etc.
std::replace_if(std::begin(line), std::end(line), [] (char x) { return std::ispunct(x); }, ' ');
// inserting the line into a stream that helps us parse the content
std::stringstream ss(line);
// read the node number
int source, destination, weight;
ss >> source;
// create a new vector for the new node, so you can place all it's destinations / weights in it
graph.insert(std::next(std::begin(graph), source), {{}});
// read the dests / weights until you reach the end of the current line
while (ss >> destination >> weight)
graph[source].emplace_back(destination, weight);
}
read.close();
std::ofstream write("output.txt");
for (const auto node : graph) {
for (const auto [dest, weight] : node)
write << "(" << dest << ", " << weight << ") ";
write << '\n';
}
}
Note that you need C++17 to compile the code. You have to use basic loops instead of ranged-for loops and omit auto if you use an older C++ standard. Also I used a vector of pairs, but it's better if you use a struct / class for nodes, to make the code more maintanable.
This works too.
#include<iostream>
#include<sstream>
#include<string>
using namespace std;
int main() {
int vertices[1000][3], qv = 0; //use number more than 1000 if it is required
while (cin) {
int n;
char c;
string s;
getline(cin, s);
istringstream is(s);
is >> n;
is >> c;
while (c == '(') {
vertices[qv][0] = n;
is >> vertices[qv][1];
is >> c; //,
is >> vertices[qv++][2];
is >> c; //)
is >> c; //(
}
}
for (int i = 0; i < qv; i++) //unified view
cout << vertices[i][0] << ' ' << vertices[i][1] << ' ' << vertices[i][2] << endl;
for (int i = 0; i < qv; i++) { //initial view
cout << vertices[i][0];
cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
while (i + 1 < qv && vertices[i][0] == vertices[i + 1][0]) {
i++;
cout << " (" << vertices[i][1] << "," << vertices[i][2] << ")";
}
cout << endl;
}
}
I would use something like this:
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <algorithm>
struct coordinate
{
int vertex;
int weight;
};
struct vertex_set
{
int vertex;
std::vector<coordinate> coordinates;
};
std::istream& operator>>(std::istream &in, coordinate &out)
{
char ch1, ch2, ch3;
if (in >> ch1 >> out.to_vertex >> ch2 >> out.weight >> ch3)
{
if ((ch1 != '(') || (ch2 != ',') || (ch3 != ')'))
in.setstate(std::ios_base::failbit);
}
return in;
}
std::istream& operator>>(std::istream &in, std::vector<coordinate> &out)
{
out.clear();
coordinate coord;
while (in >> coord)
out.push_back(coord);
return in;
}
std::istream& operator>>(std::istream &in, vertex_set &out)
{
return in >> out.vertex >> out.coordinates;
}
std::ifstream f("file.txt");
std::string line;
while (std::getline(f, line))
{
vertex_set vs;
if (std::istringstream(line) >> vs)
{
// use vs.vertex and vs.coordinates as needed...
}
}

How to user input the array elements in c++ in one line

I am new to c++ , Basically I belong to PHP . So I am trying to write a program just for practice, to sort an array . I have successfully created the program with static array value that is
// sort algorithm example
#include <iostream> // std::cout
#include <algorithm> // std::sort
#include <vector> // std::vector
bool myfunction (int i,int j) { return (i<j); }
struct myclass { bool operator() (int i,int j) { return (i<j);} } myobject;
int main () {
int myints[] = {55,82,12,450,69,80,93,33};
std::vector<int> myvector (myints, myints+8);
// using default comparison (operator <):
std::sort (myvector.begin(), myvector.begin()+4);
// using function as comp
std::sort (myvector.begin()+4, myvector.end(), myfunction);
// using object as comp
std::sort (myvector.begin(), myvector.end(), myobject);
// print out content:
std::cout << "myvector contains:";
for (std::vector<int>::iterator it=myvector.begin(); it!=myvector.end(); ++it)
std::cout << ' ' << *it;
std::cout << '\n';
return 0;
}
its output is ok . But I want that the elements should input from user with space separated or , separated . So i have tried this
int main () {
char values;
std::cout << "Enter , seperated values :";
std::cin >> values;
int myints[] = {values};
/* other function same */
}
it is not throwing an error while compiling. But op is not as required . It is
Enter , seperated values :20,56,67,45
myvector contains: 0 0 0 0 50
3276800 4196784 4196784
------------------ (program exited with code: 0) Press return to continue
You can use this simple example:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
using namespace std;
int main()
{
stringstream ss;
string str;
getline(cin, str);
replace( str.begin(), str.end(), ',', ' ');
ss << str;
int x = 0;
while (ss >> x)
{
cout << x << endl;
}
}
Live demo
or, if you want to have it more generic and nicely enclosed within a function returning std::vector:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <vector>
using namespace std;
template <typename T>
vector<T> getSeparatedValuesFromUser(char separator = ',')
{
stringstream ss;
string str;
getline(cin, str);
replace(str.begin(), str.end(), separator, ' ');
ss << str;
T value{0};
vector<T> values;
while (ss >> value)
{
values.push_back(value);
}
return values;
}
int main()
{
cout << "Enter , seperated values: ";
auto values = getSeparatedValuesFromUser<int>();
//display values
cout << "Read values: " << endl;
for (auto v : values)
{
cout << v << endl;
}
}
Live demo
Read in all the values into one string, then use a tokenizer to separate out the individual values.
How do I tokenize a string in C++?
The above answers are very good for an arbitrary number of inputs, but if you allready know how many numbers will be put, you could do it like:
int[5] intList;
std::cin >> intList[0] >> intList[1] >> intList[2] >> intList[3] >> intList[4]
But please note that this method does not do any check if the numbers are put properly, so if there are for example letters or special characters in the input, you might get unexpected behavior.
Let's see what you wrote:
int main () {
char values;
std::cout << "Enter , seperated values :";
std::cin >> values; // read a single character
int myints[] = {values}; // create a static array of size 1 containing the single character converted to an int
/* other function same */
}
what you need is:
#include <sstream>
#include <string>
...
int main () {
std::cout << "Enter space seperated values :";
std::vector<int> myvector;
std::string line;
std::getline(std::cin, line); // read characters until end of line into the string
std::istringstream iss(line); // creates an input string stream to parse the line
while(iss >> value) // so long as values can be parsed
myvector.push_back(value); // append the parsed value to the vector
/* other function same */
}
If you want comma separated input you'll need to parse the comma as a single character in addition to the integer values.
What you are doing
int main () {
char values; //Declare space for one character
std::cout << "Enter , seperated values :"; //Ask user to enter a value
std::cin >> values; //Read into values (one value only)
int myints[] = {values}; // assign the first element to the ASCII code of whatever user typed.
/* other function same */
}
In the language char works as an 8-bit integer. Through function overloading, different behavior can be implemented. Read about static polymorphism for more details how it works.
What you need to do
std::vector<int> values;
char ch_in;
std::string temp;
while(cin.get(ch_in)) {
switch(ch_in) {
case ',':
case ' ': //Fall through
values.push_back(atoi(temp.c_str()); //include cstdlib for atoi
temp.clear();
break;
default:
temp+=ch_in;
}
}
You should put this in a separate function. With this skeleton, you can implement a more fancy syntax by adding more cases, but then you need something else than a std::vector<int> to put things into. You can (should?) also add error checking in the default case:
default:
if( (ch_in>='0' && ch_in<='9')
|| (temp.size()==0 && ch_in=='-') ) {
temp+=ch_in;
}
else {
cerr<<ch_in<<" is an illegal character here."
temp.clear();
}
#include <iostream>
#include <string>
#include <sstream>
#include <string.h>
using namespace std;
// THIS CODE IS TO GIVE ARRAY IN ONE LINE AND OF DESIRED LENGHT ALSO WITH NEGATIVE NUMBERS
// You can also do it by using ASCII but we Are using library name
// <sstream> to convert string charters to numbers
//O(n) time complexity
int main()
{
/*
// INPUT
// 7 array length
// 34-56-789 // without space b/w them */
int N;
cout << "Enter the size of the array " << endl;
cin >> N;
cout << "INPUT Without giving space b/w " << endl;
string strx;
cin >> strx;
int X[N]; // array to store num
int p = 0;
// NOTE USE HERE STRX.LENGHT() becouse we have to go through the whole string
for (int i = 0; i < strx.length(); i++)
{ // we have declare tempx to store a particular character
// one time
string tempx;
tempx = strx[i];
stringstream strtointx(tempx);
// this is the syntax to convert char to int using <sstream>
if (strx[i] == '-')
{
/*
The tricky point is when you give string as 1-23
here - and 2 are the separte characters so we are not
getting -2 as number but - and 2 so what we do is
we chek for '-' sign as the character next to it
will be treated as negative number
*/
tempx = strx[i + 1];
// by assigning strx[i+1] to tempx so that we can getting the which should be treated as negative number
stringstream strtointx(tempx);
// still it is a charter type now again using library
// convert it to int type
strtointx >> X[p];
X[p] = -X[p];
// now make that number to negative ones as we want it to be negative
i++;
// inside this if i++ will help you to skip the next charcter of string
// so you can get desired output
}
// now for all the positive ones to int type
else{ strtointx >> X[p]; }
p++; // finally increment p by 1 outside if and else block
}
// loop ends now get your desired output
cout<<"OUTPUT "<<endl;
for (int i = 0; i < N; i++)
{
cout << X[i] << " ";
}
cout<<endl;
cout<<"CODE BY MUKUL RANA NIT SGR Bch(2020)";
return 0;
}
// OUTPUT
/*
Enter the size of the array
7
INPUT Without giving space b/w
34-56-789
OUTPUT
3 4 -5 6 -7 8 9
CODE BY MUKUL RANA NIT SGR Bch(2020)
PS C:\Users\user\Desktop\study c++>
*/
// CAUTION :
/*
1) do not give input with spaces
**** if you do then first you have to change /chek the code for spaces indexes also ***
2)do not give charates as 56-89##13 as you want here only numbers
3) this only for integer if you want to float or double you have to do some changes here
because charters index and length would be difeerent in string.
*/

How to group values from the same line into a pair?

I am trying to write a program that reads a text file which has a data set in the form below and puts every 2 integers per line into a pair:
1 2
3 4
5 6
... and so on
Currently, this part of my main code reads the file line by line and converts the imported strings to integers one number at a time, but I am not sure how I would group 2 integers at a time in each line and put them in a pair. Ultimately, I want to add all the pairs to a single set.
while (getline(fs, line)) {
istringstream is(line);
while(is >> line) {
int j = atoi(line.c_str());
cout << "j = " << j << endl;}}
You could simply use std::pair, like this:
istringstream is(line);
pair<int, int> p;
is >> p.first;
is >> p.second;
cout << p.first << " " << p.second;
In next step you could use std::set<std::pair<int, int> > to acheive your goal of putting the pairs into single set.
Try this:
std::ifstream ifs{ "yourfile.txt" };
// read line by line
std::string line;
while(std::getline(ifs, line)) {
std::istringstream iss{ line }; // make a stream on the line
auto values = std::make_pair<int, int>(0, 0);
if(iss >> values.first >> values.second) { // check stream state
// after reading two ints
// (this skips spaces)
std::cout << "a=" << values.first << ", b=" << values.second << "\n";
} else {
throw std::runtime_error{ "bad data" };
}
// at this point, you have read a valid pair of ints into "values"
}
See the code comments for explanations.
Use pair available in 'utility' header, following is the sample code for the same.
while (getline(fs, line))
{
stringstream is;
is<<test;
int i, j;
is>>i;
is>>j;
pair<int, int> pr(i,j);
}
Following may help:
std::string line;
std::set<std::pair<int, int>> myset;
while (std::getline(fs, line)) {
std::istringstream is(line);
int a, b;
if (is >> a >> b) {
myset.insert({a, b});
} else {
throw std::runtime_error("invalid data");
}
}
Live example
To consider 1, 5 as identical as 5, 1, you may use:
struct unordered_pair_comp
{
bool operator () (const std::pair<int, int>& lhs, const std::pair<int, int>& rhs) const
{
return std::minmax(lhs.first, lhs.second) < std::minmax(rhs.first, rhs.second);
}
};
and so your myset becomes std::set<std::pair<int, int>, unordered_pair_comp> myset;
Live example
Something like this should work for your purposes.
while (getline(fs, line))
{
istringstream is(line);
int i, j;
is >> i >> j;
std::pair<int,int> my_pair = std::make_pair (i, j);
}
Dont make the imported strings into integers. Read the two strings from one line and concatenate them. Then make them integers. Like this:
#include <sstream>
#include <fstream>
#include <string>
#include <iostream>
using namespace std;
int main()
{
string line;
ifstream fs("input.txt");
while (getline(fs, line))
{
istringstream is(line);
string num1, num2;
while (is >> num1 >> num2)
{
num1 += num2;
int j = stoi(num1);
cout << "j = " << j << endl;
}
cin.get();
}
}