getline(stream, string) from example is rejected by editor(VS2019) - c++

The example is taken from:
[http://www-h.eng.cam.ac.uk/help/tpl/languages/C++/1AComputing/Mich/index.php?reply=extraReadingfromfiles#extraReadingfromfilesanchor][1]
I wrote the code without the while loop to read file, the example used getline(stream, strgvar), but this is not admited by the editor
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
string message;
ifstream fin; // variable to store information about a file
fin.open("s.txt"); // trying to open file for reading
// next line would try to check if file has been opened succesfully
if (not fin.good())
{
cout << "\n\t Couldn't open the s file." << endl;
cout << "\n\t It needs to be in the same folder as your program."
<<endl;
return 1; // In the main function this line quits from the
whole program.
}
// we have menaged to open the file. Now we'll read a line from the file into the string
while (message!="works!")
{
fin >> message;
cout << message << " ";
}
//getline(fin,message);
}
My questions is why the line now commented is rejected ?

fin>>message;
The stream extraction operator '>>' is used when you want to read a single word from file.
Find complete explanation at : https://www.google.com/amp/s/www.geeksforgeeks.org/cpp-program-read-file-word-word/amp/
While
getline(fin,message);
In this, a full line from the file will be read in message variable. It will continue reading and assigning file contents till a '\n' (Line Deliminator) character does not appear. And thats why you getline() statement is rejected.
For complete explanation visit : http://www.cplusplus.com/forum/windows/48212/
Your program is expected to read a word at a time. And to accomplish this, fin>>mesage is used. Basically stream extraction operator read the contents till a space appears, and hence it is used to read single word.
And if you still want to use getline (), then add a third parameter to your function call as space character ' '.
Like
getline(fin,message,' '); // and done
Basically the third parameter of getline function is Deliminator, by default it is '\n', but if you want to define your own Deliminator, you can do so by providing third parameter. It will read the contents of file till the Deliminator does not occurs while reading.

To use std::getline() include <string> in the header.
https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-2010/2whx1zkx(v=vs.100)
istream also has a getline. More details here
https://learn.microsoft.com/en-us/previous-versions/visualstudio/visual-studio-6.0/aa277361(v=vs.60)

Related

Program seems to be skipping function call

I can't seem to get the program to call the second function. The program is supposed to open up a joke file, read it and display it for the user. Then close the file, open a second punchline file, seek the last line and read it to the user. I'm getting it to open the first file and display the joke but it doesn't do anything after that. Any idea what I'm doing wrong? Thank you in advance.
#include <iostream>
#include <iomanip>
#include <fstream>
#include <string>
using namespace std;
// Function prototypes
void displayAllLines(ifstream &joke); // Display joke
void displayLastLine(ifstream &punchline); // Display punchline
int main()
{
ifstream jokeFile, punchLineFile;
// Open the joke file
jokeFile.open("joke.txt", ios::in);
// Make sure the file actually opens
if (!jokeFile)
cout << "Error opening file." << endl;
// Call on function to display the joke
displayAllLines(jokeFile);
// Close the joke file
jokeFile.close();
// Open the punchline file
punchLineFile.open("punchline.txt", ios::in);
// Make sure the file actually opens
if (!punchLineFile)
cout << "Error obtaining the punchline, sorry :(." << endl;
// Call on function to display punchline
displayLastLine(punchLineFile);
// Close the punchline file
punchLineFile.close();
system("pause");
return 0;
}
// function to display the joke
void displayAllLines(ifstream &joke)
{
string input;
// Read an item from the file
getline(joke, input);
// Display the joke to the user
while (joke)
{
cout << input << endl;
getline(joke, input);
}
}
// function to display the punchline
void displayLastLine(ifstream &punchline)
{
string input;
punchline.seekg(0L, ios::beg); // Fast forward to the end of the file
punchline.seekg('/n', ios::cur); // rewind the the new line character
getline(punchline, input); // Read the line
cout << input << endl; // display the line
}
seekg takes a offset in the file - you are passing it '/n' which is not an offset.
Because you used a forward slash (/), rather than a backslash (\), the compiler is treating '/n' as a Unicode or multibyte character sequence and moving forward 12142 bytes (at least in VS 2013), which is probably past the end of your file.
Also your comment says "Fast forward to the end of the file", but you are using ios:beg which is the beginning of the file.
punchline.seekg(0L, ios::beg); // Fast forward to the end of the file
No, it doesn't. This fast forwards to the beginning of the file, that's what "ios::beg" means.
punchline.seekg('/n', ios::cur); // rewind the the new line character
This does not rewind to the newline character, the comment notwithstanding. It does not rewind to the first newline character, it doesn't rewind it to the last newline character. seekg() always positions the get pointer at a fixed offset, as indicated. And, here, the fixed offset is utterly meaningless.
Your compiler is likely complaining about this line. Do not ignore your compiler's complaints, even if it still compiles the code despite them.
See this question for one possible algorithm to find the last line in the file.
I faced this problem when i tried to call a particular function i but it everywhere in the program to be called from there but it doesn't until i discovered that there was an error with object code files "don't worry it is a simple problem".
the solution:
is simply just shutdown the environment you work on and open it again or rebuild your entire project. then you call will be executed successfully

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

Reading File in C++

I am unable to figure out why my code is not able to open and read a file. What am i missing?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main (int argc, char * const argv[])
{
string line;
ifstream myfile ("input_file_1.txt");
if (myfile.is_open())
{
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
}
else
{
cout << "Was unable to open the file" << endl;
}
return 0;
}
The file "input_file_1.txt" is int he same directory as my .cpp file and it has read permissions. I even gave gave it 777 permissions and i was unable to read it.
Can anyone tell me what i am doing wrong? I really cannot figure it out....
Try to use full path for the file
The default location to look for the file is where the executable is , not where the source is.
How and where do you execute your program? From a IDE?
Can you run the program from the same directory where you have your text file.
Another possibility is to use an absolute path to the file.
If you don't specify a path, the library will attempt to load the file from the current directory. You need to make sure that this is where the file is.
Also, you might not be able to open the file if it is opened in an exclusive manner by another program. Ensure that it is not still open in another program such as your editor.
Other Problems:
Explicitly testing for EOF is usually wrong.
The last valid read (getline() here) reads up-to but no past the EOF. You then print the line. Then restart the loop. These test for eof() does not fail (as it has not read past the EOF). You then enter the loop body and attempt to read the next line (with getline()) this fails as there are 0 bytes left to read (thus leaving the value of line in an undefined state). You then print out line (undefined value) and a newline character.
while (!myfile.eof())
{
getline (myfile,line);
cout << line << endl;
}
A correct version of a loop reading a file is:
while (getline (myfile,line))
{
cout << line << endl;
}
This works because the getline() returns a reference to a stream. A stream used in a boolean context (like a while condition) tests to see if the stream is in a bad state (ie it test for EOF and other bad situations) and returns an object that can be used correctyl in the context. If the state of the stream is OK then a successful read has happened and the loop is entered (thus allowing you to print the line).
The binary created from your code (including your cpp) is executed somewhere different from your code is, probably a "bin"-folder. You schould put the file into the same folder as your executable.

getline() returns empty line in Eclipse but working properly in Dev C++

Here is my code:
#include <iostream>
#include <stdlib.h>
#include <fstream>
using namespace std;
int main() {
string line;
ifstream inputFile;
inputFile.open("input.txt");
do {
getline(inputFile, line);
cout << line << endl;
} while (line != "0");
return 0;
}
input.txt content:
5 9 2 9 3
8 2 8 2 1
0
In Enclipse, it goes to infinite-loop. I'm using MinGW 5.1.6 + Eclipse CDT.
I tried many things but I couldn't find the problem.
Since you are on windows try:
} while (line != "0\r");
The last line is stored as "0\r\n". The \n is used as the line delimiter by getline so the actual line read will be "0\r"
or
you can convert the dos format file to UNIX format using command
dos2unix input.txt
Now your original program should work. The command will change the \r\n at the end of the line to \n
Also you should always do error checking after you try to open a file, something like:
inputFile.open("input.txt");
if(! inputFile.is_open()) {
cerr<< "Error opening file";
exit(1);
}
It will create an infinite loop if no line contains exactly 0. For example 0\n is not the same thing as 0. My guess is that that is your problem.
EDIT: To elaborate, getline should be discarding the newline. Perhaps the newline encoding of your file wrong (i.e. windows vs. unix).
Your main problem is working directory.
Because you are specifying a file using a relative path it searches for the file from the current working directory. The working directory can be specified by your dev environment. (Note: The working directory is not necessarily the same directory where the executable lives (this is a common assumption among beginners but only holds in very special circumstances)).
Though you have a special end of input marker "0" you should also check that the getline() is not failing (as it could error out for other reasons (including beady formatted input). As such it is usually best to check the condition of the file as you read it.
int main()
{
string line;
ifstream inputFile;
inputFile.open("input.txt");
while((getline(inputfile, line)) && (line != "0"))
{
// loop only entered if getline() worked and line !="0"
// In the original an infinite loop is entered when bad input results in EOF being hit.
cout << line << endl;
}
if (inputfile)
{
cout << line << endl; // If you really really really want to print the "0"
// Personally I think doing anything with the termination
// sequence is a mistake but added here to satisfy comments.
}
return 0;
}