c++ text file redirection getline infinite loop - c++

So I'm having an issue where I am reading in a text file using cin. Here is a basic idea of my code:
while(getline(cin,line) {
cout << line << endl;
}
//Do some task
return 0;
The problem I'm running into is that the loop will not terminate and //Do some task will never run. The only solution that I've found is to look directly at the text file, see how many lines of text there are, and hard code a conditional to break out of it. So say I have a text file with 5 lines and an variable int row. Then I would do something like this:
while(getline(cin,line) {
cout << line << endl;
if(row == 5) {
break;
}
//Do some task
return 0;
I tried googling but I can't seem to find an answer anywhere. Any ideas? And also only libraries I'm allowed to use is iostream.

You can use rdbuf to redirect your cin output
Following Link will help you.
http://www.cplusplus.com/reference/ios/ios/rdbuf/

The following code block should solve your issue:
Credit goes to the author: kevinchkin
http://www.cplusplus.com/forum/beginner/8388/
#include<iostream>
#include<fstream>
using namespace std;
int main() {
ifstream myReadFile;
myReadFile.open("text.txt");
char output[100];
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
myReadFile >> output;
cout<<output;
}
}
myReadFile.close();
return 0;
}
This is a basic template for reading from a .txt file. I also can not think of any reason why you should not be able to use more than just iostream. They make the other libraries because iostream isn't the best way to go about it.
Most(if not all) Teachers/Professors I have had like it when students go above and beyond what the class is studying, and try to learn more.
If you need additional help, take a look at: http://www.cplusplus.com/doc/tutorial/files/

Related

I/O redirection in C++

I wrote a program that takes its input from a file (using ifstream), uses a bunch of std::getline to extract the data and manipulate it.
I want to use I/O redirection so that these lines can be used using std::cin (As if someone is typing this info). I looked it up but I didn't quite understand how I would implement it using the Visual Studio Community program. Any help is greatly appreciated.
I would suggest you to use a stringstream for that:
#include <iostream>
#include <sstream>
int main() {
string z = "100";
stringstream a("");
a << z;
int x;
a >> z; // Extracts data; a works like cin would have if it were used to input data
cout << z;
return 0;
}
I found the solution to my question!
I simply changed the following line of code from:
std::ifstream datastream(text file location);
while (std::getline(datastream, output_str)) {
.
stuff...
.
}
To:
while (std::cin(datastream, output_str));
Once I compiled my code with no errors and got my ./a.out, I typed in my compiler:
./a.out < text file
And that pretty much started inputting the file content into std::cin as if someone was typing it.

Recursive Descent Parser Help (Not reading a text file string)

char input[100]; //Used to check grammar
char *s;
int main(int argc, char *argv[]) {
ifstream fin("input.txt"); //Open input file
while (fin>>input) { //Store text in input[]
s = input; //Point c at the input text
cout<<"String read from file: "<<input<<endl; //Show input text
if (A() && *s == '\0') { //Testing the grammar
cout<<"The string \""<<input<<"\" is in the language."<<endl;
}
else cout<<"The string \""<<input<<"\" is not in the language."<<endl;
cout<<endl; //Formatting for output in console
}
fin.close(); //Close input file
return 0;
}
Can someone tell me what i am doing wrong here. The parser is not reading string from the text file.
Let's treat this like two problems.
Problem 1: Reading in the file.
I've stripped out everything that isn't absolutely essential to reading the data in.
char input[100]; //Used to check grammar
int main(int argc, char *argv[]) {
ifstream fin("input.txt"); //Open input file
while (fin>>input) { //Store text in input[]
cout<<"String read from file: "<<input<<endl; //Show input text
}
return 0;
}
Nothing really wrong here, but you should seriously consider replacing char input[100]; with std::string input; to save you headaches with large tokens. For example, watch what happens here:
int main()
{
stringstream stream("1234567890"); // pack ten characters into stream
// note: no whitespace.
char snookums[] = "snookums";
char array[5];
cout << snookums << endl; // prove contents of snookums
stream >> array; // read up to first whitespace from stream into array
cout << array << endl; // display what we read.
cout << snookums << endl; // oh dear. Now look at poor snookums!
return 0;
}
output:
snookums
1234567890
67890
Despite array being size 5, it contains all 10. Or does it? Nope. Sadly poor snookums got run over. This won't happen with strings.
For all we know fin>>inputjust read 30000 characters from a whitespace-free file, annihilated the rest of your program's memory, and the program died before printing out anything.
Anyway, your code leaves a few questions:
Are you actually able to open the file? You don't know, really. You never checked.
Was the file empty? Also don't know. You didn't tell us. This is one of the things folks are getting on about in the comments.
None of this fixes anything, but hopefully gives you a better idea what's going wrong.
string input; // using string in case the data you're reading is incompatible
//with a 100 character char array.
int main(int argc, char *argv[]) {
ifstream fin("input.txt"); //Open input file
if (fin.is_open()
{
while (fin>>input)
{ //Store text in input
cout<<"String read from file: "<<input<<endl; //Show input text
}
}
else
{
cout << "Failed to open file." << endl;
}
return 0;
}
Once you know if you are actually reading in data, and if not, why not.
Problem 2: language parsing.
We can't help you here. No information was provided, but a few notes on coding style because they will help you ask future questions:
A() is meaningless to everyone but you. Give it a descriptive name so that someone other than you has some hints about what it does. A() takes no parameters. I assume that's because it is operating on input. OK, but why not pass input in? The cost is minimal and it provides more information to readers. Note how commenters zeroed in on A() right away? That's fear. The good kind of fear. We have no [insert expletive here] clue what it is or what it does, so it is instantly scrutinized.
A(input) reads to me as "A does something to input." I don't know what it does, but it does it to input. Unless the writer of the program has a history of doing silly stuff, it probably only does stuff to input and I don't have to fear this function nearly as much.
LanguageInterpreter() tells me that a language interpreter was run. Not much, but if I'm looking tor a bug in the file reading code, I'm not likely to find it in there. Unfortunately it also tells me that LanguageInterpreter is feasting on global data and Crom only knows what sort of side effects it could have on the rest of the program.
LanguageInterpretter(input) tells me a lot. For one thing it tells me that I can get on with my day because it has nothing to do with, or better have nothing to do with, the reading in of the data file. I'll check other places for bugs first.
string *s;
int main()
{
string input;
ifstream fin("input.txt");
if(fin.is_open())
{
while(getline(fin,input))
{
s=&input;
if (A() && *s == '\0') /* error: no match for 'operator==' in '* s == '\000''*/
{ //Testing the grammar
cout<<"The string \""<<*s<<"\" is in the language."<<endl;
}
else cout<<"The string \""<<*s<<"\" is not in the language."<<endl;
cout<<endl;
}
}
fin.close();
return 0;
}

Checking if one document has the contents of the other c++

I am writing a code to check to see if one document (text1.txt) contains a list of banned words (bannedwords.txt) in it.
For example, the text1 document contains lyrics to a song and i want to check whether the word pig from the banned document is included in it. I then want the out put to be similar to:
"pig" found 0 times
"ant" found 3 times
This is what I have come up with so far but cannot seem to put the array of banned words into the search. Any help would be amazing :D
Thanks Fitz
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
bool CheckWord(char* filename, char* search)
{
int offset;
string line;
ifstream Myfile;
Myfile.open(filename);
if (Myfile.is_open())
{
while (!Myfile.eof())
{
getline(Myfile, line);
if ((offset = line.find(search, 0)) != string::npos)
{
cout << "The Word " << search<< " was found" << endl;
return true;
}
else
{
cout << "Not found";
}
}
Myfile.close();
}
else
cout << "Unable to open this file." << endl;
return false;
}
int main()
{
ifstream file("banned.txt");
if (file.is_open())//file is opened
{
string bannedWords[8];//array is created
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
}
else //file could not be opened
{
cout << "File could not be opened." << endl;
}
ifstream text1;//file is opened
text1.open("text1.txt");
if (!text1)//if file could not be opened
{
cout << "Unable to open file" << endl;
}
CheckWord("text1.txt", "cat");
system("pause");
}
Your main() function is reading the contents of banned.txt into an array of 8 std::string named bannedWords.
The array bannedWords is not being used anywhere after that. C++ doesn't work by magic, and compilers are not psychic so cannot read your mind in order to understand what you want your code to do. If an array (or its elements) are not accessed anywhere, they will not be used to do what you want with them.
You need to pass strings from the bannedWords array to CheckWord(). For example;
CheckWord("text1.txt", bannedWords[0].c_str());
will attempt to pass the contents of the first string in bannedWords to CheckWord().
However, that will not compile either unless you make the second parameter of CheckWord() (named search) be const qualified.
Or, better yet, change the type of the second argument to be of type std::string. If you do that, you can eliminate the usage of c_str() in the above.
I don't claim that is a complete solution to your problem - because there are numerous problems in your code, some related to what you've asked about, and some not. However, my advice here will get you started.
Your question is really vague; it looks like you need to spend some time to pin down your program structure before you could ask for help here.
However, since we were all new once, here's a suggestion for a suitable structure:
(I'm leaving out the file handling bits because they're irrelevant to the essential structure)
//Populate your array of banned words
std::string bannedWords[8];
int i;
for (int i = 0; i < 8; ++i)
{
file >> bannedWords[i];
}
//Load the entire file content into memory
std::ifstream in("text1.txt");
std::string fileContents((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
So now the entire file content is in the string "fileContents", and the 8 banned words are in "bannedWords". I suggest this approach because otherwise you're opening, reading, and closing the file for every word. Hardly a good design.
Now you've got to check each word against the file content. There's some more sophisticated ways to do this, but your simplest option is a loop.
//Loop through each banned word, and check if it's in the file
for (int i = 0; i < 8; i++)
{
if (fileContents.find(bannedwords[i]) != std::string::npos)
{
//Do whatever
}
}
Obviously you'll need to do the find a little differently if you want to count the number of occurrences, but that's another question.

Reading input from a text file and outputting the text to the screen in c++

I'm a new student of the c++ language and I'm having trouble understanding...well, frankly, a whole lot of things. I've been given this assignment to read text from a text file and output it to the screen, and I'm having quite a bit of trouble. I've spent several hours on this now already researching and testing, and this is the code that I've got so far, and it's not working, and I'm not really sure why. Any and all help or insights anyone would be willing to share with me would be very much appreciated. I'm sorry I don't recall all the errors I've encountered as I worked on this by name...but I assure you there were plenty of them. Like trying to use "fopen" in my compiler...it didn't like that, so I tried "fopen_s" like it suggested, but then it said that it wouldn't accept any arguments anymore...then I found that I needed to add "#define _CRT_SECURE_NO_DEPRECATE" as a header(?) file at the top of the program, and that problem did get solved and the program actually compiled...but then it gave me a fatal error, not sure what I did that was so fatal, but there you are. Please help.
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *pf;
char ch;
pf = fopen("C:\\lowerCase\anyOldTextFile.txt", "r");
feof(pf);
if (pf == NULL)
{
printf("Unable to open the file.\n");
}
else
{
while (!feof(pf))
{
ch = fgetc(pf);
printf("%c", ch);
}
fclose(pf);
}
system("pause");
}
Try this, which I pasted from this site:
// reading a text file
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("example.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
}
myfile.close();
}
else cout << "Unable to open file";
return 0;
}
I didn't test this code, but it looks fine. They also explain the code on the website. I suggest visiting that page and reading all of it. Then you should be able to understand how this is working.

ifstream is failing to open file

Here is my code:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void getHighScores(int scores[], string names[]);
int main()
{
ifstream stream;
stream.open("scores.txt");
int scores[32];
string names[32];
stream>>scores[0];
stream>>names[0];
if(stream.fail())
cout<<"It failed\n"<<strerror(errno)<<endl;
for(int i=1;i<5;i++)
{
stream>>scores[i];
stream>>names[i];
cout<<i<<endl;
}
cout<<scores[2]<<endl;
stream.close();
return 0;
}
void getHighScores(int scores[], string names[])
{
}
It get garbage output for scores[2] because stream.open("scores.txt") fails to open a file.
strerror(errno) gives me "No error".
I've checked to see if my file is really called "scores.txt.txt". It is not. I've also tried moving my file to "C:\scores.txt". I've tried using the full address. I've tried deleting it and re-creating it. I've tried other things too that I cannot remember. ![enter image description here][1]I've been trying for hours to fix this and I'm desperate. I'd be grateful if anyone could help me fix this.
void gethighscores is a function that I plan to use later.
The input file looks like this:
Ronaldo
10400
Didier
9800
Pele
12300
Kaka
8400
Cristiano
8000
The output of the program looks like this
It failed
No error
1
2
3
4
-858993460
Press any key to continue . . .
I'm running this in Microsoft Visual Studio Express 2012 for Windows Desktop
My operating system is Windows 7 ultimate 64 bit.
when using the "\" to define a path use two instead of one
C:\ \scores.txt
try this:
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
void getHighScores(int scores[], string names[]);
int main()
{
string filename = "scores.txt"; // could come from command line.
ifstream fin(filename.c_str());
if (!fin.is_open())
{
cout << "Could not open file: " << filename << endl;
return 1;
}
int scores[32];
string names[32];
int iter = 0;
while (fin >> names[iter] >> scores[iter])
{
if (++iter >= 32 )
{
break;
}
cout << iter << endl;
}
if (iter >= 2)
{
cout << scores[2] << endl;
}
fin.close();
return 0;
}
void getHighScores(int scores[], string names[])
{
}
Had me stumped for a bit. Your C++ code is reading scores and names in the opposite order from your input text. The first line of text in the input file is Ronaldo, but your first operator>> is to score[0] (an int). This causes the failbit to be set, and so fail() returns true. It also explains why you end up getting garbage for the destination array elements.
Reverse the order of the scores/names in either the scores.txt file or your C++ parsing code (but not both!) and you should be good to go.
The reason it fails is this:
int scores[32];
string names[32];
stream>>scores[0];
stream>>names[0];
if(stream.fail())
cout<<"It failed\n"<<strerror(errno)<<endl;
By default, scores[0] and names[0] don't have any set value and it tries to assign them to the file, which causes it to fail. If you try commenting those two lines:
stream>>scores[0];
stream>>names[0];
You'll see that it no longer fails and works fine.