I have double numbers in a file (one on each line) that I am trying to read into a c++ array. I am using the below code, but get the below error while running:
segmentation fault: 11
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main () {
string line;
ifstream myfile ("temp2.csv");
std::vector<double> myArray;
int index = 0;
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
// myArray[index++] << line;
myArray[index++] = atoi( line.c_str() );
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
You can't do
myArray[index++] = atoi( line.c_str() );
It is an empty vector. You either need to push_back elements into it. Or initialize it with sufficient memory.
This should work:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <stdlib.h>
using namespace std;
int main () {
string line;
ifstream myfile ("temp2.csv");
std::vector<double> myArray;
int index = 0;
if (myfile.is_open())
{
while (! myfile.eof() )
{
getline (myfile,line);
cout << line << endl;
// myArray[index++] << line;
myArray.push_back(atoi( line.c_str() ));
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
On this line:
std::vector<double> myArray;
You create a vector using the default constructor. As you can see from the documentation, the default constructor creates an empty vector.
On this line:
myArray[index++] = atoi( line.c_str() );
You access elements from the vector with successively increasing indices. But those elements do not exist and the indices are out of bounds because the vector is empty. Accessing outside the bounds of the vector has undefined behaviour.
TL;DR you forgot to add any elements into the vector.
The code is far more complex than it needs to be. It's much simpler to just read one value at a time:
std::vector<double> myArray;
double value;
std::ifstream myfile(temp2.csv);
if (!myfile) {
std::cout << "Unable to open file\n");
return EXIT_FAILURE;
}
while (myfile >> value)
myArray.push_back(value);
Related
I must say I'm completely new to C++. I got the following problem.
I've got a text file which only has one 8 digits number
Text-File: "01485052"
I want to read the file and put all numbers into a vector, e.g. Vector v = ( 0, 1, 4, 8, 5, 0, 5, 2 ). Then write it into another text file.
How do I implement it the best way? That's what I made possible so far:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main()
{
char matrikelnummer[100];
cout << "Enter file name: ";
cin >> matrikelnummer;
// Declare input file stream variable
ifstream inputFile(matrikelnummer);
string numbers;
//Check if exists and then open the file
if (inputFile.good()) {
//
while (getline(inputFile, numbers))
{
cout << numbers;
}
// Close the file
inputFile.close();
}
else // In case TXT file does not exist
{
cout << "Error! This file does not exist.";
exit(0);
return 0;
}
// Writing solutions into TXT file called Matrikelnummer_solution.txt
ofstream myFile;
myFile.open("Matrikelnummer_solution.txt");
myFile << "Matrikelnummer: " << numbers << '\n';
myFile.close();
return 0;
}
You can use the following program for writing the number into another file and also into a vector:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main()
{
ifstream inputFile("input.txt");
std::string numberString;
int individualNumber;
std::vector<int> vec;
if(inputFile)
{
std::ofstream outputFile("outputFile.txt");
while(std::getline(inputFile, numberString,'\n'))//go line by line
{
for(int i = 0; i < numberString.size(); ++i)//go character by character
{
individualNumber = numberString.at(i) - '0';
outputFile << individualNumber;//write individualNumber into the output file
vec.push_back(individualNumber);//add individualNumber into the vector
}
}
outputFile.close();
}
else
{
std::cout<<"input file cannot be openede"<<std::endl;
}
inputFile.close();
//print out the vector
for(int elem: vec)
{
std::cout<<elem<<std::endl;
}
return 0;
}
The output of the above program can be seen here.
Read from file to numbers using inputFile >> numbers. Then, add each digit character of the string to a std::vector.
Also, to write to the file, write each element of vector in a for loop.
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <sstream>
using namespace std;
int main()
{
char matrikelnummer[100];
cout << "Enter file name: \n";
cin >> matrikelnummer;
// Declare input file stream variable
ifstream inputFile(matrikelnummer);
string numbers;
vector<int> individualNumbers;
//Check if exists and then open the file
if (inputFile.good()) {
inputFile >> numbers;
for (int i = 0; i < numbers.length(); i++) {
if (numbers[i] >= '0' && numbers[i] <= '9')
individualNumbers.push_back(numbers[i] - '0');
}
// Close the file
inputFile.close();
}
else // In case TXT file does not exist
{
cout << "Error! This file does not exist.";
exit(0);
return 0;
}
// Writing solutions into TXT file called Matrikelnummer_solution.txt
ofstream myFile;
myFile.open("Matrikelnummer_solution.txt");
myFile << "Matrikelnummer: ";
for (int number : individualNumbers) {
myFile << number << " ";
}
myFile << endl;
myFile.close();
return 0;
}
I'm trying to read in a file into an array so that I could process the array into selection sort. But when I try to read in the file, I get a segmentation fault(core dumped) error. Here is my code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string array[40707];
int loop = 0;
int loop2;
string line;
ifstream inFile("beowulf.txt");
if (inFile.is_open())
{
while(!inFile.eof())
{
getline(inFile, line);
array[loop] = line;
loop++;
}
inFile.close();
}
else cout << "Unable to open file" << endl;
for (loop2 =0; loop2 <= loop; loop2++)
cout << array[loop2] << endl;
return 0;
}
Change your string array to:
std::vector<std::string> array;
Then you can read the file and copy into the vector simply as:
std::copy(std::istream_iterator<std::string>(inFile),
std::istream_iterator<std::string>(),
std::back_inserter(array));
EDIT: To read the file line-by-line, either define your own insert_iterator or do it like this:
std::string line;
while (getline(inFile, line))
array.push_back(line);
Your code will then change to something like this
#include <bits/stdc++.h>
using namespace std;
int main() {
vector<string> array;
string line;
ifstream inFile("beowulf.txt");
if (!inFile.is_open()) {
cerr << "Unable to open file" << endl;
return 1;
}
while (getline(inFile, line))
array.push_back(line);
inFile.close();
for (int i = 0; i < array.size(); ++i)
cout << array[i] << endl;
return 0;
}
Two potential error cases I can see right away.
Overrunning the end of the end of array. It can happen while reading because there is no guard on loop. If the array read was exactly 40707 lines it will happen while printing out when loop2 == loop. Either of these is probably the cause of the segfault. The recommended solution is to use C++'s std::vector because it will dynamically size itself to the input and automate iterating through the items stored.
The second error is less severe, but allows an infinite loop on an IO error. The end of file may never be reached if an error prevents reading a line and places the stream in an error condition. Unlikely to happen with getline, but a common occurrence with formatted reads.
Using most of the OP's solution:
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> array; // vector eliminates buffer overflow problem of string array.
//int loop = 0; vector also eliminates the need for this counter
//int loop2; and this one
string line;
ifstream inFile("beowulf.txt");
if (inFile.is_open())
{
while(getline(inFile, line)) //exits if anything goes wrong with the file IO
{
array.push_back(line); // stores line in vector
}
inFile.close();
}
else cout << "Unable to open file" << endl;
// C++11 way
for (string const & str: array)
{ // iterates through the string automatically
cout << str << endl;
}
/* Old C++ way
for (vector<string>::iterator str = array.begin();
token != array.end();
++token)
{ // iterates through the string manually
cout << *str << endl;
}
*/
return 0;
}
I need to parse a table of numbers formatted as ascii text. There are 36 space delimited signed integers per line of text and about 3000 lines in the file. The input file is generated by me in Matlab so I could modify the format. On the other hand, I also want to be able to parse the same file in VHDL and so ascii text is about the only format possible.
So far, I have a little program like this that can loop through all the lines of the input file. I just haven't found a way to get individual numbers out of the line. I am not a C++ purest. I would consider fscanf() but 36 numbers is a bit much for that. Please suggest practical ways to get numbers out of a text file.
int main()
{
string line;
ifstream myfile("CorrOut.dat");
if (!myfile.is_open())
cout << "Unable to open file";
else{
while (getline(myfile, line))
{
cout << line << '\n';
}
myfile.close();
}
return 0;
}
Use std::istringstream. Here is an example:
#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
using namespace std;
int main()
{
string line;
istringstream strm;
int num;
ifstream ifs("YourData");
while (getline(ifs, line))
{
istringstream strm(line);
while ( strm >> num )
cout << num << " ";
cout << "\n";
}
}
Live Example
If you want to create a table, use a std::vector or other suitable container:
#include <sstream>
#include <string>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string line;
// our 2 dimensional table
vector<vector<int>> table;
istringstream strm;
int num;
ifstream ifs("YourData");
while (getline(ifs, line))
{
vector<int> vInt;
istringstream strm(line);
while ( strm >> num )
vInt.push_back(num);
table.push_back(vInt);
}
}
The table vector gets populated, row by row. Note we created an intermediate vector to store each row, and then that row gets added to the table.
Live Example
You can use a few different approaches, the one offered above is probable the quickest of them, however in case you have different delimitation characters you may consider one of the following solutions:
The first solution, read strings line by line. After that it use the find function in order to find the first position o the specific delimiter. It then removes the number read and continues till the delimiter is not found anymore.
You can customize the delimiter by modifying the delimiter variable value.
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myfile("CorrOut.dat");
string delimiter = " ";
size_t pos = 0;
string token;
vector<vector<int>> data;
if (!myfile.is_open())
cout << "Unable to open file";
else {
while (getline(myfile, line))
{
vector<int> temp;
pos = 0;
while ((pos = line.find(delimiter)) != std::string::npos) {
token = line.substr(0, pos);
std::cout << token << std::endl;
line.erase(0, pos + delimiter.length());
temp.push_back(atoi(token.c_str()));
}
data.push_back(temp);
}
myfile.close();
}
return 0;
}
The second solution make use of regex and it doesn't care about the delimiter use, it will search and match any integers found in the string.
#include <iostream>
#include <string>
#include <regex> // The new library introduced in C++ 11
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myfile("CorrOut.dat");
std::smatch m;
std::regex e("[-+]?\\d+");
vector<vector<int>> data;
if (!myfile.is_open())
cout << "Unable to open file";
else {
while (getline(myfile, line))
{
vector<int> temp;
while (regex_search(line, m, e)) {
for (auto x : m) {
std::cout << x.str() << " ";
temp.push_back(atoi(x.str().c_str()));
}
std::cout << std::endl;
line = m.suffix().str();
}
data.push_back(temp);
}
myfile.close();
}
return 0;
}
I have a text file with 2 columns and many rows. each column is separated by spaces. i need to read them to a 2D array for further calculations.
my data file looks like
0.5 0.479425539
1 0.841470985
1.5 0.997494987
2 0.909297427
2.5 0.598472144
3 0.141120008
3.5 -0.350783228
4 -0.756802495
4.5 -0.977530118
5 -0.958924275
And my feeble attempt is
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <ctype.h>
using namespace std;
int main () {
char line,element;
std::ifstream myfile ("C:\\Users\\g\\Desktop\\test.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
getline(myfile,line);
cout << line<<endl;
_getch();
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
The problem is I'm not able to read them correctly.... its either reading the whole line... if I specify the delimiter as 'space' then, its not reading the next row.
Pls point out whats wrong. and what should i do to store the data into 2d array for further calculations.
Thank you
#include <fstream>
#include <string>
#include <sstream>
#include <iostream>
#include <vector>
int main(int argc, char** argv) {
std::ifstream f(argv[1]);
std::string l;
std::vector<std::vector<double> > rows;
while(std::getline(f, l)) {
std::stringstream s(l);
double d1;
double d2;
if(s >> d1 >> d2) {
std::vector<double> row;
row.push_back(d1);
row.push_back(d2);
rows.push_back(row);
}
}
for(int i = 0; i < rows.size(); ++i)
std::cout << rows[i][0] << " " << rows[i][1] << '\n';
}
The last for loop shows how to use the values in the "array". The variable rows is strictly speaking not an array, but a vector of vectors. However, a vector is much safer than c-style arrays, and allows access to its elements using [].
[As I posted this I saw a very similar program posted as a response. I wrote mine independently.]
You can read the whole line into a std::string, then use std::istringstream to extract the values from the line.
A complete working program:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
int main()
{
std::ifstream file("C:\\Users\\g\\Desktop\\test.txt");
std::string line;
// Read a line of input from the file
while (std::getline(file, line))
{
// `istringstream` behaves like a normal input stream
// but can be initialized from a string
std::istringstream iss(line);
float value;
// The input operator `>>` returns the stream
// And streams can be used as a boolean value
// A stream is "true" as long as everything is okay
while (iss >> value)
{
std::cout << "Value = " << value << '\t';
}
// Flush the standard output stream and print a newline
std::cout << std::endl;
}
}
Given the contents in the file being as in the question, the first three lines of output should be:
Value = 0.5 Value = 0.479425539
Value = 1 Value = 0.841470985
Value = 1.5 Value = 0.997494987
For a 2d-array, I would use a std::vector of std::array:
#include <vector>
#include <array>
...
std::vector<std::array<float, 2>> array;
...
float value1, value2;
if (iss >> value1 >> value2)
{
std::cout << "Values = " << value1 << ", " << value2;
array.emplace_back(std::array<int, 2>{{value1, value2}});
}
Now the first line values are array[0][0] and array[0][1], and the last lines values are array[array.size() - 1][0] and array[array.size() - 1][1].
As C++ has evolved over the years, below is a Modern C++ version.
It uses auto where possible
Uses std::pair to hold 2 values (A std::pair is a specific case of a std::tuple with two elements)
Does not close file (destructor does that at end of block)
Does not read line by line, as the stream uses <space> and <enter> as delimiters
The variables have meaningful names, so the program "reads" easily,
Uses a range for loop to output the data.
Doesn't bring the whole std namespace into the code - Why is “using namespace std” considered bad practice?
.
#include <fstream>
#include <iostream>
#include <vector>
#include <utility>
int main( int argc, char** argv )
{
if ( argc < 1 )
return -1;
const auto fileName = argv[ 1 ];
std::ifstream fileToRead( fileName );
typedef std::pair< double, double > DoublesPair;
std::vector< DoublesPair > rowsOfDoublesPair;
DoublesPair doublePairFromFile;
while ( fileToRead >> doublePairFromFile.first >> doublePairFromFile.second )
{
rowsOfDoublesPair.push_back( doublePairFromFile );
}
for ( const auto row : rowsOfDoublesPair )
std::cout << row.first << " " << row.second << '\n';
}
I want to put some text from a text file into an array, but have the text in the array as individual characters.
How would I do that?
Currently I have
#include <iostream>
#include <fstream>
#include <string>
#include <cmath>
#include <vector>
#include <sstream>
using namespace std;
int main()
{
string line;
ifstream myfile ("maze.txt");
if (myfile.is_open())
{
while ( myfile.good() )
{
getline (myfile,line);
// --------------------------------------
string s(line);
istringstream iss(s);
do
{
string sub;
iss >> sub;
cout << "Substring: " << sub << endl;
} while (iss);
// ---------------------------------------------
}
myfile.close();
}
else cout << "Unable to open file";
system ("pause");
return 0;
}
I'm guessing getline gets one line at a time. Now how would I split that line into individual characters, and then put those characters in an array?
I am taking a C++ course for the first time so I'm new, be nice :p
std::ifstream file("hello.txt");
if (file) {
std::vector<char> vec(std::istreambuf_iterator<char>(file),
(std::istreambuf_iterator<char>()));
} else {
// ...
}
Very elegant compared to the manual approach using a loop and push_back.
#include <vector>
#include <fstream>
int main() {
std::vector< char > myvector;
std::ifstream myfile("maze.txt");
char c;
while(myfile.get(c)) {
myvector.push_back(c);
}
}