Its probably an easy answer and i hope its easy to understand my question.
I have a text document that has a lot of lines and several paragraphs
Is there a way to merge all lines into one single line without doing it manually?
The reason i am asking this its because lets say I am searching for a specific word in a document that only has one paragraph.(let say the paragraph has 10 lines) If that word its in that one paragraph its suppose to return paragraph1 accepted. But what my program its doing something weird instead its giving me an output like this:
paragraph1:accepted
paragraph2:accepted
paragraph3:accepted
paragraph4:accepted
paragraph5:accepted
paragraph6:accepted
paragraph7:accepted
paragraph8:accepted
paragraph9:accepted
paragraph10:accepted
This is the code that reads my document
void processParagraph(std::string ¶graph, size_t paragraphNumber)
{
ifstream input;
input.open("data.txt"); //opens the text file with the documents
if (input.fail()) //if the file doesn't open
{
cout << "file not found" << endl;
return;
}
if (isMyWordThere(paragraph)) //if the word im looking its there
cout << "paragraph " << paragraphNumber << ": accepted" << endl;
else // if the word its not there
cout << "paragraph " << paragraphNumber << ": not accepted" << endl;
paragraph.clear(); // reset the paragraph to handle the next one.
std::string line;
std::string paragraph;
size_t paragraphNumber = 0;
while ( getline(input, line) ) // read a LINE
{
if ( !line.empty() ) // paragraph not finished
{
paragraph.append("\n").append(line);
}
else // paragraph finished, because we found an empty line
{
++paragraphNumber;
processParagraph(paragraph, paragraphNumber);
}
}
if ( !paragraph.empty() )
{
processParagraph(paragraph, paragraphNumber);
}
}
Its there a way to merge all lines into one, or a way that i can change my code so it doesnt count lines?
The input file looks like this:(im looking for the word "hello")
hello world
hello everyone
hello All
The output should look like this
paragraph 1: accepted
but what im getting is
paragraph 1: accepted
paragraph 2: accepted
paragraph 3: accepted
You're processing lines not paragraphs.
This will do it:
void processParagraph(std::string ¶graph, size_t paragraphNumber)
{
if (isMyWordThere(paragraph)) //if the word im looking its there
std::cout << "paragraph " << paragraphNumber << ": accepted" << std::endl;
else // if the word its not there
std::cout << "paragraph " << paragraphNumber << ": not accepted" << std::endl;
paragraph.clear(); // reset the paragraph to handle the next one.
}
void processFile(std::string filename)
{
std::ifstream input;
input.open(filename.c_str()); // open file
std::string line;
std::string paragraph;
size_t paragraphNumber = 0;
while ( getline(input, line) ) // read a LINE
{
if ( !line.empty() ) // paragraph not finished
{
paragraph.append("\n").append(line);
}
else // paragraph finished, because we found an empty line
{
++paragraphNumber;
processParagraph(paragraph, paragraphNumber);
}
}
if ( !paragraph.empty() )
{
processParagraph(paragraph, paragraphNumber);
}
}
It seems that you want to split this functionality out into a separate function, that can either take a filename or an open file stream. Then call this function once for each file.
Related
I want to read recent added lines in a file.txt with c++ . Everytime I add some new lines in the file I want to read just those recent lines.
This code below just read all the lines of the file
void Reading::read(const char* path)
{
string str_path = string(path);
string str;
ifstream file1(path);
if(str_path.substr(str_path.find_last_of(".")+ 1)== "jrn")
{
if(file1.is_open())
{
while (getline(file1, str))
{
cout << str << "\n";
}
file1.close();
}
else
cout <<"File not found " << endl;
file1.close();
}
else
{
cout << "Can't read this type of file" << endl;
}
}
Please can you help me to solve the problem . Thank you .
Have your Reading class cache the return value from file1.tellg(), call file1.seekg() to go to the last read location before reading the lines.
https://www.cplusplus.com/reference/istream/istream/tellg/
https://www.cplusplus.com/reference/istream/istream/seekg/
**Edit: As it turns out, it was a simple typo under the if(i==0) statement. I missed putting {} to enclose both first_nonterminal statements.
I'm creating a CFG for an assignment, but I've gotten stuck. My program is supposed to read a file (of strings) by getting the file name from the command line, and then do certain things with the contents of the file.
using namespace std;
string current, first_nonterminal;
int main(int argc, char *argv[])
{
if(argc != 2)
{
std::cout << "No file name given" << std::endl; // if there is no file name in command line
exit(1);
}
ifstream infile(argv[1]);
if(!infile)
{
std::cout << "Given file " << argv[1] << " will not open."; // if file refuses to open
exit(2);
}
string word;
for(int i = 0; infile >> word; ++i)
{
cout << word << endl; // (debug) print input word
try // check if first word is in correct format
{
if (i == 0 && word.find(':') == string::npos) // check only first word,
{
throw runtime_error("File does not have correct format.");
}
}
catch(runtime_error &e)
{
cout << "Error:" << e.what();
exit(3);
}
if (i==0)
first_nonterminal = word;
first_nonterminal.pop_back(); // remove colon
insert(word); //put string through insert() method
}
randomize(); // randomize and replace
print(); // print end result
infile.close();
}
The above code intakes a file which is formatted like so:
STMT: THIS THAT OTHER
THIS: That carpet
THIS: Atlanta
THAT: is wild
OTHER: .
OTHER: , oooh OTHER2
OTHER2: oooh OTHER2
OTHER2: !
Any word that has a colon following it is considered a nonterminal, with the words following it considered terminals. Regardless, I've figured out the issue isn't my randomize() or insert() functions, as they work perfectly if I hard-code the file into the program. My issue is the file stops being read after a certain number of strings, and I'm not sure why. For example, when I put the above's file name into the command line, it runs through, but then after it puts "That" into the insert() function, it prints "carpet" via the debug cout, and then stops.
I have a problem with the following section.
This particular part should do the following:
List all modules taught by selected lecturer
I'm struggling with part of match the input from the user with data in the text file, and only display that list of module taught by the selected lecturer.
I have text file called: Taught.txt and the content of the text file is of the following:
IS1S01 AW
IS1S02 MG
SE2S552 BM
CS2S504 BM
CS3S08 SL
MS3S28 DJ
CS1S03 EM
BE1S01 SJ
BE2S01 SH
SS1S02 AB
SE1S02 AW
The below section is code I have done so far.
void listofmodulebylecturer()
{
std::string Lecturer;
std::string Module;
// Display message asking for the user input
std::cout << "\nList all modules taught by selected lecturers." << std::endl;
std::cout << "Enter your preferred lecturers." << std::endl;
// Read in from the user input
std::cin >> Lecturer;
// Read from text file and Display list of modules taught by the selected lecturer
std::ifstream infile;
// infile.open("Lecturer");
infile.open("Taught.txt");
if (!infile)
{
std::cout << "List is empty" << std::endl;
}
else
{
std::cout << "\nList of Modules:" << std::endl;
while(!infile.eof())
{
getline(infile,Module);
std::cout << Module << std::endl;
}
std::cout << "End of list\n" << std::endl;
}
infile.close(); // close the text file
system ("PAUSE");
}
I was thinking of using
if (........)
{
}
else
I wondering if that can work?
Using infile.eof() cannot work reliable for the purpose you want to use it for. You should read two words and print the first word if the second word matches the expected. Reading the words would look something like this:
for (std::string module, teacher; infile >> module >> teacher; ) {
// check if the teacher is the correct one and, if so, print the module
}
... and, yes, an if statement works for this.
Since each line contains only two strings, I wouldn't use getline() but this:
std::string course, teacher;
while (infile) {
infile >> course >> teacher;
if (infile) { // strings read correctly
if (teacher == Lecturere) {
...
}
}
}
when running the following code, the amount of lines will read on less then there actually is (if the input file is main itself, or otherwise)
why is this and how can i change that fact (besides for just adding 1)?
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
// open text file for input
string file_name;
cout << "please enter file name: ";
cin >> file_name;
// associate the input file stream with a text file
ifstream infile(file_name.c_str());
// error checking for a valid filename
if ( !infile ) {
cerr << "Unable to open file "
<< file_name << " -- quitting!\n";
return( -1 );
}
else cout << "\n";
// some data structures to perform the function
vector<string> lines_of_text;
string textline;
// read in text file, line by line
while (getline( infile, textline, '\n' )) {
// add the new element to the vector
lines_of_text.push_back( textline );
// print the 'back' vector element - see the STL documentation
cout << "line read: " << lines_of_text.back() << "\n";
}
cout<<lines_of_text.size();
return 0;
}
The code you have is sound. Here's a small test case that might help:
void read_lines(std::istream& input) {
using namespace std;
vector<string> lines;
for (string line; getline(input, line);) {
lines.push_back(line);
cout << "read: " << lines.back() << '\n';
}
cout << "size: " << lines.size() << '\n';
}
int main() {
{
std::istringstream ss ("abc\n\n");
read_lines(ss);
}
std::cout << "---\n";
{
std::istringstream ss ("abc\n123\n");
read_lines(ss);
}
std::cout << "---\n";
{
std::istringstream ss ("abc\n123"); // last line missing newline
read_lines(ss);
}
return 0;
}
Output:
read: abc
read:
size: 2
---
read: abc
read: 123
size: 2
---
read: abc
read: 123
size: 2
I think I have tracked down the source of your problem. In Code::Blocks, a completely empty file will report that there is 1 line in it (the current one) in the gizmo on the status bar at the bottom of the IDE. This means that were you actually to enter a line of text, it would be line 1. In other words, Code::Blocks will normally over-report the number of actual lines in a file. You should never depend on CB, or any other IDE, to find out info on files - that's not what they are for.
Well, if the last line of your file is just '\n', you don't push it into the vector. If you want it to be there, change the loop to:
while (getline( infile, textline, '\n' ).gcount() > 0)
{
if (infile.fail()) break; //An error occurred, break or do something else
// add the new element to the vector
lines_of_text.push_back( textline );
// print the 'back' vector element - see the STL documentation
cout << "line read: " << lines_of_text.back() << "\n";
}
Use the gcount() member to check how many characters were read in the last read - this will return 1 if it only read a delimiter character.
Ok so here is an explanation that you will hopefully understand. Your code should work fine if the file we're talking about doesn't end with newline. But what if it does? Let's say it looks like this:
"line 1"
"line 2"
""
Or as a sequence of characters:
line 1\nline 2\n
This file has THREE lines -- the last one being empty but it's there. After calling getline twice, you've read all the characters from the file. The third call to getline will say oops, end of file, sorry no more characters so you'll see only two lines of text.
I am trying to read from file:
The file is multiline and basically i need to go over each "word". Word being anything non space.
Sample input file would be:
Sample file:
test 2d
word 3.5
input
{
test 13.5 12.3
another {
testing 145.4
}
}
So I tried something like this:
ifstream inFile(fajl.c_str(), ifstream::in);
if(!inFile)
{
cout << "Cannot open " << fajl << endl;
exit(0);
}
string curr_str;
char curr_ch;
int curr_int;
float curr_float;
cout << "HERE\n";
inFile >> curr_str;
cout << "Read " << curr_str << endl;
The problem is when it reads new line it just hangs. I read everything before test 13.5
but once it reaches that line it doesnt do anything.
Anyone can tell me what I am doing wrong?
Any better suggestion on how to do this???
I essentially need to go through file and go one "word" (non white char) at the time.
I
Thanks
You open a file 'inFile' but are reading from the 'std::cin' any particular reason?
/*
* Open the file.
*/
std::ifstream inFile(fajl.c_str()); // use input file stream don't.
// Then you don't need explicitly specify
// that input flag in second parameter
if (!inFile) // Test for error.
{
std::cerr << "Error opening file:\n";
exit(1);
}
std::string word;
while(inFile >> word) // while reading a word succeeds. Note >> operator with string
{ // Will read 1 space separated word.
std::cout << "Word(" << word << ")\n";
}
Not sure how "in the spirit" of the iostream library this is, but you could do it with unformatted input. Something like:
char tempCharacter;
std::string currentWord;
while (file.get(tempCharacter))
{
if (tempCharacter == '\t' || tempCharacter == '\n' || tempCharacter == '\r' || tempCharacter == ' ')
{
std::cout << "Current Word: " << currentWord << std::endl;
currentWord.clear();
continue;
}
currentWord.push_back(tempCharacter);
}
Does that work?