Problems using getline() - c++

I'm running out of hair to pull out, so I thought maybe someone here could help me with this frustration.
I'm trying to read a file line by line, which seems simple enough, using getline(). Problem is, my code seems to keep ignoring the \n, and putting the entire file into one string, which is problematic to say the least.
void MakeRandomLayout(int rows, int cols)
{
string fiveByFive = "cubes25.txt";
string fourByFour = "cubes16.txt";
ifstream infile;
while (true) {
infile.open(fourByFour.c_str());
if (infile.fail()) {
infile.clear();
cout << "No such file found";
} else {
break;
}
}
Vector<string> cubes;
string cube;
while (std::getline(infile, cube)) {
cubes.add(cube);
}
}
Edits: Running OSX 10.7.
The infinite loop for the file is unfinished, will eventually ask for a file.
No luck with extended getline() version, tried that earlier.
Same system for dev and build/run.
The text file i'm reading in looks as follows:
AAEEGN
ABBJOO
ACHOPS
AFFKPS
AOOTTW
CIMOTU
DEILRX
DELRVY
DISTTY
EEGHNW
EEINSU
EHRTVW
EIOSST
ELRTTY
HIMNQU
HLNNRZ
Each string is on a new line in the file. The second one that I'm not reading in is the same but 25 lines instead of 16

Mac software recognizes either '\r' or '\n' as line-endings, for backward compatibility with Mac OS Classic. Make sure that your text editor hasn't put '\r' line endings in your file when your processing code is expecting '\n' (and verify that the '\n' characters you think are in the middle of the string aren't in fact '\r' instead.

I suspect that you are failing to display the contents of Vector correctly. When you dump the Vector, do you print a \n after each entry? You should, because getline discards the newlines on input.
FYI: the typical pattern for reading line-by-line is this:
Vector<string> cubes;
string cube;
while(std::getline(infile, cube)) {
cubes.add(cube);
}
Note that this will discard the newlines, but will put one line per entry in Vector.
EDIT: For whatever it is worth, if you were using an std::vector, you could slurp the file in thusly:
std::ifstream ifile(av[1]);
std::vector<std::string> v(
(std::istream_iterator<std::string>(ifile)),
std::istream_iterator<std::string>());

Related

C++ reading multiple lines from stdin

There is a part of a code I wrote in C++:
int main(int ac, char **av)
{
std::string line;
while (std::getline(std::cin, line)) {
std::cout << "[" << line << "]\n";
}
return (0);
}
Code works properly when it comes to easy examples; it can read multiple lines (single lines in while loop) one by one and display them in terminal:
The problem appears when I try to copy paste two or more lines and print them on the screen; std::getline() blocks and is stuck, unable to read the input till the end (I can guess it's already been read and it's stored somewhere in buffer maybe?).
However, when I click enter it displays the input left, line by line, which is completely fine and desired since it - as the name points - reads one line at time.
Is it possible to unblock std::getline() somehow so it reads entire block of code?
I hope I explained it well, thanks for helping!

How do I deal with a carriage return line feed when trying to read in file

So I am working on a file that I need to read in which contains both commas separating words and carriage return linefeed at the end of each line and I can't figure out a way to handle it. I am trying to read in each word before the comma and put it into the a vector until it hits the carriage return line feed but I am having problems.
Here is my text file (as seen on notepad++ so you can see the symbols. on the actual text, the things inside [] don't appear)
microwave,lamp,guitar,couch,bed,dog,cat[cr][lf]
P1:microwave,couch,bed,dog,chair,bookcase,fish[cr][lf]
I have tried multiple solutions, but nothing seems to work. Here is what I have tried so far. but it obviously isn't working. I have seen some users suggest using substring to somehow read out the comma, and read in the words but I am not sure how to do that. I couldn't find a good tutorial or example of one. In my head, I have the algorithm(or at least, steps on how to go about it), but i am not sure how to go about implementing it.
Import file (istream)
Read until comma, take string and place it in vector1 (getline, input, ,), vector.push_back(input)
Repeat previous step until you reach \cr\lf stop reading. (getline(input, '/r'))
move on to the next line
Read until comma, take string and place it in vector2
Repeat
Read the line until /cr/lf
Here is the code I put in practice using part of the above steps i made.
string input;
vector<string> v1;
vector<string> v2;
ifstream infile;
infile.open("example.txt");
while(getline(infile, input)) //read until end of line
{
while(getline(infile, input, '\r')) //read until it reaches a carriage return
{
while(getline(infile, input, ',')) // read until it reaches a comma
{
v1.push_back(input); //take the word and put in vector.
}
}
}
infile.close();
Any help would be appreciated.
Edit: I forgot to mention. When I used this code, it seemed to not import anything into the vectors. I am sure all the words got lost somewhere in the getline functions, but I don't know how to just read up to comma and carriage return line feed without using it.
You should use getline() to get a whole line first. It should handle carriage returns for you. Then, put the result into a stringstream and use getline() on it to separate the line at the commas.
My code that reads input into a vector of vectors:
#include <fstream>
#include <iostream>
#include <sstream>
#include <vector>
int main()
{
std::ifstream fin("input.txt");
std::vector<std::vector<std::string>> result;
for(std::string line; std::getline(fin, line);)
{
result.emplace_back();
std::stringstream ss(line);
for(std::string word; std::getline(ss, word, ',');)
{
result.back().push_back(word);
}
}
for(const auto &i : result)
{
for(const auto &j : i)
{
std::cout << j << ' ';
}
std::cout << '\n';
}
}
You can modify it to read into two vectors by just removing the outer loop and use two separate loops for each of the two vectors/lines.
In your code, you first have a loop that reads line by line until the end of the file. After you read a line, you have a loop that reads until a '\r', which as far as I know does not occur in a normal text file. Even if there are '\r's in the file, you would be overwriting what you just read in from the outer loop. Same thing with the loop inside that.
Were you taught that while(getline(fin, str)) reads from a file without knowing how it works?

I filed my vector from a text file and it wont cout as one line. How can I do this?

Long story short I need my vector to cout as a single line without creating its own new lines for my program to work correctly. the text file i read into the vector was
laptop#a small computer that fits on your lap#
helmet#protective gear for your head#
couch#what I am sitting on#
cigarette#smoke these for nicotine#
binary#ones and zeros#
motorcycle#two wheeled motorized bike#
oj#orange juice#
test#this is a test#
filled the vector using the loop:
if(myFile.is_open())
{
while(getline(myFile, line, '#'))
{
wordVec.push_back(line);
}
cout << "words added.\n";
}
and printed it using this:
for(int i = 0; i < wordVec.size(); i++)
{
cout << wordVec[i];
}
and it outputs as such:
laptopa small computer that fits on your lap
helmetprotective gear for your head
couchwhat I am sitting on
cigarettesmoke these for nicotine
binaryones and zeros
motorcycletwo wheeled motorized bike
ojorange juice
testthis is a test
my program works if I manually input the words and add them to my data structure but if added from the vector which is filled via text file, half of the program doesnt work. before anyone says asks for a better description of the problem, all I need to know is how to fill the vector so that it will output as a single line.
You code getline(myFile, line, '#') reads everything up to end-of-file or the next '#' into line - that includes any newlines. So, as you read text file content...
laptop#a small computer that fits on your lap#
helmet#protective gear for your head#
...which you could also think of as...
"laptop#a small computer that fits on your lap#\nhelmet#protective gear for your head#"
...line takes on successive values...
"laptop"
"a small computer that fits on your lap"
"\nhelmet"
...etc....
Note the newline in "\nhelmet".
There are many ways to avoid or correct this, such as...
while ((myFile >> std::skipws) and getline(myFile, line, '#'))
...
...or...
if (not line.empty() and line[0] == '\n')
line.erase(0, 1);
...or (as Barry suggests in comments)...
while (getline(myFile, line))
{
std::istringstream iss(line);
std::string field;
while (getline(iss, field, '#'))
...
}
while(getline(myFile, line, '#'))
Here, you told std::getline to use the '#' character instead of a newline, '\n', as a delimiter.
So, this simply means that std::getline will no longer think there's anything special about '\n'. It's just another character that std::getline() will keep reading, looking for the next #.
So, you end up reading newline characters into your individual strings, and then outputing them to std::cout, as part of the strings you've printed.

How to read content of the file and save it to string type variable? Why there is empty space?

This is how I get the name of the file from the command line and open a file and save the content of the file line by line to a string. All the procedures works fine except three empty spaces at the beginning of the file. Is anyone can say why these empty spaces occurred and how can I ignore them?
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
if(!fin.good()){
cout<<" = File does not exist ->> No File for reading\n";
exit(1);
}
string s;
while(!fin.eof()){
string tmp;
getline(fin,tmp);
s.append(tmp);
if(s[s.size()-1] == '.')
{
//Do nothing
}
else
{
s.append(" ");
}
cout<<s<<endl;
The most probable cause is that your file is encoded in something else than ASCII. It contains a bunch of unprintable bytes and the string you on the screen is the result of your terminal interpreting those bytes. To confirm this, print the size of s after the reading is done. It should be larger than the number of characters you see on the screen.
Other issues:
string filename = "input.txt";
char *a=new char[filename.size()+1];
a[filename.size()]=0;
memcpy(a,filename.c_str(),filename.size());
ifstream fin(a);
is quite an overzealous way to go about it. Just write ifstream fin(a.c_str());, or simply ifstream fin(a); in C++11.
Next,
while(!fin.eof()){
is almost surely a bug. eof() does not tell if you the next read will succeed, only whether the last one reached eof or not. Using it this way will tipically result in last line seemingly being read twice.
Always, always, check for success of a read operation before you use the result. That's idiomatically done by putting getline in the loop condition: while (getline(fin, tmp))

Reading from a file, only reads text untill it gets to empty space

I managed to successfully read the text in a file but it only reads until it hits an empty space, for example the text: "Hi, this is a test", cout's as: "Hi,".
Removing the "," made no difference.
I think I need to add something similar to "inFil.ignore(1000,'\n');" to the following bit of code:
inFil>>text;
inFil.ignore(1000,'\n');
cout<<"The file cointains the following: "<<text<<endl;
I would prefer not to change to getline(inFil, variabel); because that would force me to redo a program that is essentially working.
Thank you for any help, this seems like a very small and easily fixed problem but I cant seem to find a solution.
std::ifstream file("file.txt");
if(!file) throw std::exception("Could not open file.txt for reading!");
std::string line;
//read until the first \n is found, essentially reading line by line unti file ends
while(std::getline(file, line))
{
//do something line by line
std::cout << "Line : " << line << "\n";
}
This will help you read the file. I don't know what you are trying to achieve since your code is not complete but the above code is commonly used to read files in c++.
You've been using formatted extraction to extract a single string, once: this means a single word.
If you want a string containing the entire file contents:
std::fstream fs("/path/to/file");
std::string all_of_the_file(
(std::istreambuf_iterator<char>(filestream)),
std::istreambuf_iterator<char>()
);