getline() function in visual studio 2012 working differently, directly skipping to the last line - c++

this is the first time i am using getline() and i think there is something wrong with it!
Here is my code:
ifstream file ("new2.csv");
string val;
while (file.good())
{
getline (file,val);
}
cout<<val;
and the output is always the last line of the csv file, no matter how many lines i have in the csv file.
my csv file is a simple Delimited file. like:
cat,dog,a,b,c,hello,world
monkey,flower,text,word
i think getline is supposed to read the first line of the csv file, but in this case, my output will be : monkey,flower,text,word
and this happens with any number of lines in the csv file.
i am unable to find out what may be doing this. please help me.
thanks.

Ofcourse it will only print the last line read from the file, because cout prints outside the loop and it prints the last line, after reading ALL lines finished.
You should write this instead:
ifstream file ("new2.csv");
string val;
while (file.good())
{
getline (file,val);
cout<< val << endl;
}

while (file.good())
{
getline (file,val);
}
cout<<val;
Your cout is outside the loop, so you'll only print the last line.

Related

How to extract specific substring from getline function in C++?

I'm fairly new to C++ so please forgive me if my terminology or methodology isn't correct.
I'm trying to write a simple program that:
Opens two input files ("infileicd" and "infilesel").
Opens a single output file "list.txt".
Compares "infilesel" to "infileicd" line by line.
If a line from "infilesel" is found in "infileicd", it writes that line from "infileicd" to "list.txt", effectively making a separate log file.
I am using the getline() function to do this but have run into trouble when trying to compare each file line. I think it might be easier if I could use only the substring of interest to use as a comparison.
The problem is that there are multiple words within the entire getline string and I am only really interested in the second one. Here are two examples:
"1529 nic1_mau_op_mode_3 "8664afm007-01" "1" OUTPUT 1 0 LOGICAL 4 4136"
"1523 pilot_mfd_only_sel "8664afm003-02" "1" OUTPUT 1 0 LOGICAL 4 4112"
"nic1_mau_op_mode_3" and "pilot_mfd_only_sel" are the only substrings of interest.
It would make it a lot easier if I could only use that second substring to compare but I don't know how to extract it specifically from the getline() function. I haven't found anything suggesting it is impossible to do this, but if it is impossible, what would be an alternative method for extracting that substring?
This is a personal project so I'm under no time contstraints.
Any assistance is greatly apprecated in advance. Here is my code (so far):
int main()
{
//Open the file to write the selected variables to.
ofstream writer("list.txt");
//Open the selected variabels file to be read.
ifstream infilesel;
infilesel.open("varsel.txt");
//Open the icd file to be read.
ifstream infileicd;
infileicd.open("aic_fdk_host.txt");
//Check icd file for errors.
if (infileicd.fail()){
cerr << "Error opening icd.\n" << endl;
return 1;
}
else {
cout << "The icd file has been opened.\n";
}
//Check selected variables file for errors.
if (infilesel.fail()){
cerr << "Error opening selection file.\n" << endl;
return 1;
}
else {
cout << "The selection file has been opened.\n";
}
//Read each infile and copy contents of icd file to the list file.
string namesel;
string nameicd;
while(!infileicd.eof()){
getline(infileicd, nameicd);
getline(infilesel, namesel);
if (nameicd != namesel){ //This is where I would like to extract and compare the two specific strings
infileicd; //Skip to next line if not the same
} else {
writer << nameicd << namesel << endl;
}
}
writer.close();
infilesel.close();
infileicd.close();
return 0;
}
So, based on what we discussed in the comments, you just need to toss the stuff you don't want. So try this:
string namesel;
string nameicd;
string junk;
while(!infileicd.eof()){
// Get the first section, which we'll ignore
getline(infileicd, junk, ' ');
getline(infilesel, junk, ' ');
// Get the real data
getline(infileicd, nameicd, ' ');
getline(infilesel, namesel, ' ');
// Get the rest of the line, which we'll ignore
getline(infileicd, junk);
getline(infilesel, junk);
Basically, getline takes a delimiter, which by default is a newline. By setting it as a space the first time, you get rid of the first junk section, using the same method, you get the part you want, and then the final portion goes to the end of the line, also ignoring it.

reading a line from a file and put it in a string (with fstream)

i want to read a file and put each line in a string (each line contains a single word)
i've used getline but it doesn't work neither does the >> command.
here's my code:
(i'm using visual studio)
string device_kind;
ifstream bank_info;
bank_info.open ("acquirer.info");
bank_info >> device_kind; //fails to compile
getline (bank_info, device_kind); //also fails
bank_info.close();
use bank_info.geline(device_kind,size)
getline is member function of ifstream so use it with . operator.
Look at my code on IDEONE
string device_kind;
ifstream bank_info("acquirer.info");
if(!bank_info.bad())
{
getline(bank_info, device_kind);
cout << device_kind;
}
bank_info.close();
It outputs the first line of the file for me, so it should also work for you!
If you want to read your file in a vector<string> of lines, you can do it, like I do here: http://ideone.com/qNW5N9

Problems using getline()

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>());

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>()
);

getline() reads an extra line

ifstream file("file.txt");
if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
cout<<line[l++]<<"\n";
}
}
I am using a two dimensional character array to keep the text (more than one line) read from a file to count the number of lines and words in the file but the problem is that getline always reads an extra line.
Your code as I'm writing this:
ifstream file("file.txt");
if(file.fail())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
cout<<line[l++]<<"\n";
}
}
The first time getline fails, you still increment the line counter and output the (non-existing) line.
Always check for an error.
extra advice: use std::string from the <string> header, and use its getline function.
cheers & hth.
The problem is when you're at the end of the file the test on file will still succeed because you have not yet read past the end of file. So you need to test the return from getline() as well.
Since you need to test the return from getline() to see if it succeeded, you may as well put it right in the while loop:
while (file.getline(line[l], 80))
cout << line[l++] << "\n";
This way you don't need a separate test on file and getline().
This will solve your problem:
ifstream file("file.txt");
if(!file.good())
{
cout<<"Could not open the file";
exit(1);
}
else
{
while(file)
{
file.getline(line[l],80);
if(!file.eof())
cout<<line[l++]<<"\n";
}
}
Its more robust
Does the file end with a newline? If it does, the EOF flag will not be triggered until one extra loop passes. For example, if the file is
abc\n
def\n
Then the loop will be run 3 times, the first time it will get abc, the second time it will get def and the third time it will get nothing. That's probably why you see an additional line.
Try checking the failbit on the stream AFTER the getline.
Only do the cout if file.good() is true. The extra line you're seeing comes from the last call to file.getline() which reads past the end of the file.