I have a large file (50x11k) of a grid of numbers. All i am trying to do is place the values into a vector so that i can access the values of different lines at the same time. I get a seg fault everytime (i cannot even do a cout before a the while loop). Anyone see the issue?
If there is an easier way to do this then please let me know. Its a large file and I need to be able to compare the values of one row with another so a simple getline does not work, Is there a way to jump around a file and not "grab" the lines, but just "examine" the lines so that I can later go back an examine that same line by putting in that number? Like looking at the file like a big array? I wanna look at the third line and 5 character in that line at the same time i look at the 56th line and 9th character, something like that.
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
using namespace std;
//int g_Max = 0;
int main() {
vector<vector<string> > grid;
ifstream in("grid.txt");
int row = 0;
int column = 0;
string c;
if (!in) {
cout << "NO!";
}
while (!in.eof()) {
c = in.get();
if ( c.compare("\n") == 0) {
row++;
column = 0;
}
else {
c = grid[column][row];
cout << grid[column][row];
column++;
}
}
return 0;
}
vector<vector<string> > grid;
This declares an empty vector, with no elements.
c = grid[column][row];
This accesses elements of the vector, but there are no elements.
If you change it to use vector::at() instead of vector::operator[] like so:
c = grid.at(column).at(row);
then you'll get exceptions telling you you're accessing out of range.
You need to populate the vector with elements before you can access them. One way is to declare it with the right number of elements up front:
vector<vector<string> > grid(11000, std::vector<string>(50));
You probably also want to fix your IO loop, testing !in.eof() is usually wrong. Why not read a line at a time and split the line up, instead of reading single characters?
while (getline(in, c))
If all you need is to access all lines at once why you don't declare it as std::vector<std::string> and each line is an string??
std::string s;
std::vector<std::string> lines;
while( std::getline(in, s) ) lines.push_back( s );
std::cout << "File contain " << lines.size() << " line" << std::endl;
std::cout << "Char at [1][2] is " << lines[1][2] << std::endl; // assume [1][2] is valid!
Related
I am currently working in c++. My goal is to be able to implement the A* algorithm, through a series of steps I plan to be able to store, and list the shortest path from Point A to Point B.
My program will take in a command-line argument which will be a file to read in. The purpose of giving the program a file t read in is that each file is its own "grid" for A* to process. The format for the grid file is as follows:
Num 1 = WIDTH and then Num 2 = HEIGHT
o = start
* = finish
. = passable node
# = impassable wall
So an example grid, let's call it "Grid1", would be:
8 5
o......#
......##
.....###
....####
.......*
So to process this, when you run the program you would pass in "Grid1".
From here, I plan to create a filestream and read in each character into a 2D Array/Vector to attempt to recreate the grid so I can have positions. For example, in "Grid1" the character "o" would be at position [0][0] in a Array/Vector. My attempted implementation is as follows:
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>
using namespace std;
int main(int argc, char *argv[])
{
//Checking for CLA
if( argc < 1 )
{
cout << "Program must take atleast <1> arguments!" << endl << "1) File to read 2) OPTIONAL: Type of search" << endl;
}
//CLA #1 is the file containing GRID to be read in
string gridTBO = argv[1];
//Start new filestream and open grid file for reading
ofstream gridFile;
gridFile.open( gridTBO );
//Check to make sure we can even open the file before proceeding
if( gridFile.is_open() )
{
//To store grid data
vector<string> grid;
grid[0][0].push_back("Hello");
cout << grid[0][0];
}
However, in regards to my "push_back", it seems that I am not able to print out or throw the data into the vector. I would primarily want each index such as [0][0] [0][1] [0][2] to hold each individual character in order to recreate a grid like the one I pass in.
I am not quite sure what I am doing incorrectly as I am fairly inexperienced using vectors, however, the code for pushing data into the grid is purely for testing purposes. Once I am able to parse some data into the vector, I would then like to automate it with a loop and have "getline" or a similar function grab the data for me.
So my main questions are:
1) Why is my push_back and print out failing?
2) How would I read in char by char with a loop to prevent me from manually putting data in?
The error I receive on run-time is:
Segmentation Fault(core dump)
Thank you everyone in advance for your assistance and knowledge!
ofstream is for output file. Use ifstream for reading the file.
vector<string> grid;
vector<string> will work in your case. But it's easier to create a 2-D array of vector with vector<vector<char>>, then you access grid[x][y]
Unlike arrays, vectors don't have any elements when they are created, so there is no valid grid[x][y] or grid[x] until you add something to it.
Try this code instead:
int main()
{
ifstream fin("test.txt");
vector<vector<char>> grid;
int row = 0;
string line;
while(fin >> line)
{
grid.resize(row + 1);
for(auto c : line)
grid[row].push_back(c);
row++;
}
for(auto row_vector : grid)
{
for(auto e : row_vector)
cout << e;
cout << "\n";
}
return 0;
}
I believe my error is within my writeline function, when I attempt to write the contents of the vector to the new file using a while loop.
//Read from txt file, write to new text file
#include<iostream>
#include<fstream>
#include<vector>
#include<string>
#include<algorithm>
using namespace std;
void readline();
void sortline(vector<string>& sortthis);
void writeline(vector<string>& list);
int main()
{
readline();
system("pause");
return 0;
};
void readline()
{
string line;
vector<string> lines;
ifstream myfile("classes.txt");
if (myfile.is_open())
{
while (myfile.good())
{
getline(myfile, line);
lines.push_back(line);
};
myfile.close();
}
cout << "readline() has run" << endl;
sortline(lines);
writeline(lines);
};
void sortline(vector<string>& sortthis)
{
sort(sortthis.begin(), sortthis.end());
};
void writeline(vector<string>& list)
{
ofstream myfile2("new.txt");
if (myfile2.is_open())
{
int i = 0;
while(i !=list.size()-1)
{
myfile2 << list[i] << endl;
i++;
};
myfile2.close();
};
cout << "writeline() has run" << endl;
};
this is a project from a semester ago that i'm revisiting. I wrote the program on my mac, now i'm trying to run it on my windows comp with visual studio. I'll describe what I'm attempting to do, I apologize if my choice of words is terrible in advance. anywhere I put a * is where I'm not sure what is happening, but I'll take a stab at it.. any explanations of my code is very appreciated!!
my readline() function does the following: creates a string called line, creates a vector of string type called lines, **input the file classes.txt and establish myfile as it's object, then open myfile for writing, **use the while loop to write the lines from the txt into the myfile object, then close myfile, print out a statement to let the user know readline() has run, then **pass the vector called lines into the sortline function, and then pass lines into the writeline function.
** sortline takes in a vector of strings as its arg, and assigns it the object sortthis?? then I'm not sure what happens, but it looks like i applied a sorting algorithm, anybody have any thoughts?
and finally we get to my writeline function which takes in a vector of strings as its arg and assigns them the name lines (is that correct?) i then want to establish a new out file stream to a new textfile called "new.txt" with an object name myfile2, if myfile2 is open, then i want to write all the lines from the vector of strings(which contain the contents of the original text file) into myfile2, which will write them to the new.txt file, then close myfile2, print a message stating the function has run, and that is all.
The way you loop through list in writeline is not safe. You should use a for loop or a while loop with iterator. As it is, your code probably doesn't do what you intend it to do even if there are several elements in list. Consider the following:
std::vector<std::string> vLines;
vLines.push_back("Hello");
vLines.push_back("File");
vLines.push_back("World");
std::ofstream of("file.txt");
int i = 0;
while (i != vLines.size() - 1)
{
of << vLines[i] << std::endl;
++i;
}
Even with several elements in vLines, this will only actually print output 2 elements into of.
i will be 0 which is not 2, so "Hello" will be output to of.
i will be 1 which is not 2, so "File" will be output to of.
i is now 2, which is equal to 2, so "World" will not be output to of.
That's with elements. If there are 0 elements in vLines, you will be indexing out of bounds (which I suspect is what you are doing, hence your error):
std::vector<std::string> vLines;
std::ofstream of("file.txt");
int i = 0;
while (i != vLines.size() - 1)
{
of << vLines[i] << std::endl;
++i;
}
i will be 0, which is not equal to -1, so the code will run and try to output vLines[0] to of, but there is no vLines[0]! I suspect this is what you are experiencing.
This will go away if you use a proper range-based loop instead (credit to #WhozCraig for C++11 solution):
for (auto const& s : vLines)
of << s;
Or if you don't have C++11 you can still mimic a proper range-based loop with the following:
for (int i = 0; i < vLines.size(); ++i)
of << vLines[i] << std::endl;
Or an iterator:
for (auto it = vLines.begin(); it != vLines.end(); ++it)
of << *it << std::endl;
You will now output all elements in your std::vector to your std::ofstream as well as properly handle situations where there are no elements.
I would like to be able to read the data that I have into C++ and then start to do things to manipulate it. I am quite new but have a tiny bit of basic knowledge. The most obvious way of doing this that strikes me (and maybe this comes from using excel previously) would be to read the data into a 2d array. This is the code that I have so far.
#include <iostream>
#include <fstream>
#include <algorithm>
#include <string>
#include <sstream>
using namespace std;
string C_J;
int main()
{
float data[1000000][10];
ifstream C_J_input;
C_J_input.open("/Users/RT/B/CJ.csv");
if (!C_J_input) return -1;
for(int row = 0; row <1000000; row++)
{
string line;
getline(C_J_input, C_J, '?');
if ( !C_J_input.good() )
break;
stringstream iss(line);
for(int col = 0; col < 10; col++)
{
string val;
getline(iss, val, ',');
if (!iss.good() )
break;
stringstream converter(val);
converter >> data[row][col];
}
}
cout << data;
return 0;
}
Once I have the data read in I would like to be able to read through it line by line and then pull analyse it, looking for certain things however I think that could probably be the topic of another thread, once I have the data read in.
Just let me know if this is a bad question in any way and I will try to add anything more that might make it better.
Thanks!
as request of the asker, this is how you would load it into a string, then split into lines, and then further split into elements:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <sstream>
//This takes a string and splits it with a delimiter and returns a vector of strings
std::vector<std::string> &SplitString(const std::string &s, char delim, std::vector<std::string> &elems)
{
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim))
{
elems.push_back(item);
}
return elems;
}
int main(int argc, char* argv[])
{
//load the file with ifstream
std::ifstream t("test.csv");
if (!t)
{
std::cout << "Unknown File" << std::endl;
return 1;
}
//this is just a block of code designed to load the whole file into one string
std::string str;
//this sets the read position to the end
t.seekg(0, std::ios::end);
str.reserve(t.tellg());//this gives the string enough memory to allocate up the the read position of the file (which is the end)
t.seekg(0, std::ios::beg);//this sets the read position back to the beginning to start reading it
//this takes the everything in the stream (the file data) and loads it into the string.
//istreambuf_iterator is used to loop through the contents of the stream (t), and in this case go up to the end.
str.assign((std::istreambuf_iterator<char>(t)),
std::istreambuf_iterator<char>());
//if (sizeof(rawData) != *rawSize)
// return false;
//if the file has size (is not empty) then analyze
if (str.length() > 0)
{
//the file is loaded
//split by delimeter(which is the newline character)
std::vector<std::string> lines;//this holds a string for each line in the file
SplitString(str, '\n', lines);
//each element in the vector holds a vector of of elements(strings between commas)
std::vector<std::vector<std::string> > LineElements;
//for each line
for (auto it : lines)
{
//this is a vector of elements in this line
std::vector<std::string> elementsInLine;
//split with the comma, this would seperate "one,two,three" into {"one","two","three"}
SplitString(it, ',', elementsInLine);
//take the elements in this line, and add it to the line-element vector
LineElements.push_back(elementsInLine);
}
//this displays each element in an organized fashion
//for each line
for (auto it : LineElements)
{
//for each element IN that line
for (auto i : it)
{
//if it is not the last element in the line, then insert comma
if (i != it.back())
std::cout << i << ',';
else
std::cout << i;//last element does not get a trailing comma
}
//the end of the line
std::cout << '\n';
}
}
else
{
std::cout << "File Is empty" << std::endl;
return 1;
}
system("PAUSE");
return 0;
}
On second glance, I've noticed few obvious issues which will slow your progress greatly, so I'll drop them here:
1) you are using two disconnected variables for reading the lines:
C_J - which receives data from getline function
line - which is used as the source of stringstream
I'm pretty sure that the C_J is completely unnecessary. I think you wanted to simply do
getline(C_J_input, line, ...) // so that the textline read will fly to the LINE var
// ...and later
stringstream iss(line); // no change
or, alternatively:
getline(C_J_input, C_J, ...) // no change
// ...and later
stringstream iss(C_J); // so that ISS will read the textline we've just read
elsewise, the stringstream will never see what getline has read form the file - getline writes the data to different place (C_J) than the stringstream looks at (line).
2) another tiny bit is that you are feeding a '?' into getline() as the line separator. CSVs usually use a 'newline' character to separate the data lines. Of course, your input file may use '?' - I dont know. But if you wanted to use a newline instead then omit the parameter at all, getline will use default newline character matching your OS, and this will probably be just OK.
3) your array of float is, um huge. Consider using list instead. It will nicely grow as you read rows. You can even nest them, so list<list<float>> is also very usable. I'd actually probably use list<vector<float>> as the number of columns is constant though. Using a preallocated huge array is not a good idea, as there always be a file with one-line-too-much you know and ka-boom.
4) your code contains a just-as-huge loop that iterates a constant number of times. A loop itself is ok, but the linecount will vary. You actually don't need to count the lines. Especially if you use list<> to store the values. Just like you;ve checked if the file is properly open if(!C_J_input), you may also check if you have reached End-Of-File:
if(C_J_input.eof())
; // will fire ONLY if you are at the end of the file.
see here for an example
uh.. well, that's for start. Goodluck!
I am trying to write a C++ program, but I am not familiar with C++. I have a .txt file, which contains values as follows:
0
0.0146484
0.0292969
0.0439453
0.0585938
0.0732422
0.0878906
What I have done in my C++ code is as follows:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myReadFile;
myReadFile.open("Qi.txt");
if(myReadFile.is_open())
{
while(myReadFile.good())
{
getline(myReadFile,line);
cout << line << endl;
}
myReadFile.close();
}
return 0;
}
I would like to make the output of the program an array, i.e.
line[0] = 0
line[1] = 0.0146484
line[2] = 0.0292969
line[3] = 0.0439453
line[4] = 0.0585938
line[5] = 0.0732422
line[6] = 0.0878906
Assuming you want your data stored as floating point numbers (not strings) you probably want to do something like this:
#include <iostream>
#include <vector>
#include <iterator>
#include <fstream>
int main() {
std::ifstream in("Qi.txt");
// initialize the vector from the values in the file:
std::vector<double> lines{ std::istream_iterator<double>(in),
std::istream_iterator<double>() };
// Display the values:
for (int i=0; i<lines.size(); i++)
std::cout << "lines[" << i << "] = " << lines[i] << '\n';
}
Just a quick note on style: I prefer to see variables fully initialized right when you create them, so std::ifstream in("Qi.txt"); is preferable to std::ifstream in; in.open("Qi.txt");. Likewise, it's preferable to initialize the vector of lines directly from istream iterators rather than create an empty vector, then fill it in an explicit loop.
Finally, note that if you insist on writing an explicit loop anyway, you never want to use something like while (somestream.good()) or while (!somestream.eof()) to control your loop -- these are mostly broken, so they don't (dependably) read a file correctly. Depending on the type of data involved, they'll frequently appear to read the last item from the file twice. Usually, you want something like while (file >> value) or while (std::getline(file, somestring)). These check the state of the file immediately after reading, so as soon as reading fails they fall out of the loop, avoiding the problems of the while (good()) style.
Oh, as a side note: this is written expecting a compiler that (at lest sort of) conforms with C++11. For an older compiler you'd want to change this:
// initialize the vector from the values in the file:
std::vector<double> lines{ std::istream_iterator<double>(in),
std::istream_iterator<double>() };
...to something like this:
// initialize the vector from the values in the file:
std::vector<double> lines(( std::istream_iterator<double>(in)),
std::istream_iterator<double>() );
First you'll need a vector:
std::vector<std::string> lines; // requires #include <vector>
Then you'll need to take a string taken from the getline operation, and push it back into the vector. It's very simple:
for (std::string line; std::getline(myReadFile, line);)
{
lines.push_back(line);
}
For an output operation, all you need is:
{
int i = 0;
for (auto a : lines)
{
std::cout << "lines[" << i++ << "] = " << a << std::endl;
}
}
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
string line;
ifstream myReadFile;
myReadFile.open("Qi.txt");
if(myReadFile.is_open())
{
for(int i=0;i<7;++i)
if(myReadFile.good())
{
getline(myReadFile,line);
cout<<"line["<<i<<"] = " << line << endl;
}
myReadFile.close();
}
return 0;
}
I need to read a .dat file which looks like this:
Atask1 Atask2 Atask3 Atask4 Atask5
Btask1 Btask2 Btask3 Btask4 Btask5
Ctask1 Ctask2 Ctask3 Ctask4 Ctask5
Dtask1 Dtask2 Dtask3 Dtask4 Dtask5
and i need to be able to output information like this:
cout << line(3) << endl; // required output shown below
>>Ctask1 Ctask2 Ctask3 Ctask4 Ctask5
cout << line(2)(4) << endl; // required output shown below
>>Btask4
I don't know how to read 1 line and split it into an array of 5 different strings.
I'd ideally like to have the whole .dat file converted into a vector or a list or some kind of matrix/array structure for easy reference
any simple code or solutions for this??
PLEASE HELP?!?!?!? :-)
EDIT:
vector<string> dutyVec[5];
dut1.open(dutyFILE);
if( !dut1.is_open() ){
cout << "Can't open file " << dutyFILE << endl;
exit(1);
}
if(dut1.eof()){
cout << "Empty file - no duties" << endl;
exit(1);
}
while ( !dut1.eof()){
int count = 0;
getline(dut1, dutyVec[count]);
count++;
}
Your problem addresses a number of issues, all of which I will attempt to answer in one go. So, forgive the length of this post.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <fstream>
int main(int argc, char argv[]){
std::vector <std::string> v;//just a temporary string vector to store each line
std::ifstream ifile;
ifile.open("C://sample.txt");//this is the location of your text file (windows)
//check to see that the file was opened correctly
if(ifile.is_open()) {
//while the end of file character has not been read, do the following:
while(!ifile.eof()) {
std::string temp;//just a temporary string
getline(ifile, temp);//this gets all the text up to the newline character
v.push_back(temp);//add the line to the temporary string vector
}
ifile.close();//close the file
}
//this is the vector that will contain all the tokens that
//can be accessed via tokens[line-number][[position-number]
std::vector < std::vector<std::string> > tokens(v.size());//initialize it to be the size of the temporary string vector
//iterate over the tokens vector and fill it with data
for (int i=0; i<v.size(); i++) {
//tokenize the string here:
//by using an input stringstream
//see here: http://stackoverflow.com/questions/5167625/splitting-a-c-stdstring-using-tokens-e-g
std::istringstream f(v[i].c_str());
std::string temp;
while(std::getline(f, temp, ' ')) {
tokens[i].push_back(temp);//now tokens is completely filled with all the information from the file
}
}
//at this point, the tokens vector has been filled with the information
//now you can actually use it like you wanted:
//tokens[line-number][[position-number]
//let's test it below:
//let's see that the information is correct
for (int i=0; i<tokens.size(); i++) {
for(int j=0; j<tokens[i].size(); j++) {
std::cout << tokens[i][j] << ' ';
}
std::cout << std::endl;
}
system("pause");//only true if you use windows. (shudder)
return 0;
}
Note, I did not use iterators, which would have been beneficial here. But, that's something I think you can attempt for yourself.