Get recent added lines from a file.txt c++ - c++

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/

Related

Text can not be appended to the file

I want to append text to the file "filename.txt" but the text won't append. I have even set the attribute ios_base::app but it does not work(I have tried deleting the file and starting the program again so that the part where the attribute is added will be run;
ifstream MyReadFile("filename.txt");
ifstream f("filename.txt");
bool exits_and_can_be_opened = f.good();
if (exits_and_can_be_opened) {
cout << "This file already exists";
}
else {
MyWriteFile.open("filename.txt", ios_base::app);
MyWriteFile << "Files can be tricky, but it is fun enough!";
MyWriteFile.close();
}
while (getline(MyReadFile, myText)) {
// Output the text from the file
cout << myText << "\n";
}
MyWriteFile << "This thing was appended";
cout << "This was the final change";
You could open the file for reading and writing, and then use positioning functions to move around in the file or to switch from reading to writing
fstream MyFile("filename.txt");
while (getline(MyFile, myText)) {
// Output the text from the file
cout << myText << "\n";
}
MyFile.clear(); // clear any error
MyFile.seekg(0, ios_base::end); // move to the end of the file
MyFile << "This thing was appended";
The other (maybe simpler) way is to close and reopen the file every time you want to switch from reading to writing. Don't have the same file opened twice simultaneously.

C++: std::ofstream method open() wipes open ifstream file on second iteration

I am trying to build a "fileUpdater" which will copy an original file into multiple directories, where a file with the same name and extension was previously found.
bool update_files(const string inputPath, const vector<string> outputPaths)
{
ifstream src(inputPath);
if(!src.is_open())
{
cout << "Unable to open input file\n" << inputPath <<endl;
return false;
}
else
{
ofstream dst;
for(unsigned int i=0; i<= outputPaths.size()-1; i++)
{
dst.open(outputPaths[i]);
try
{
dst << src.rdbuf();
dst.close();
}
catch(int e)
{
cout << "Unable to replace file\n" <<endl;
cout << outputPaths[i] <<"\n"<< endl;
cout << "Error code: " <<e<<endl;
}
}
};
src.close();
return true;
}
Exactly after executing
dst.open(outputPaths[i]);
in the second iteration, the original file opened by
ifstream src(inputPath);
gets wiped and only an empty file is copied into the remaining directories.
I also tried
dst.clear();
dst.close();
and
src.clear();
src.seekg(0,ios::beg);
before entering the next iteration, but it made no difference.
UPDATE
After trying different files, I realised the behavior depends on the input file. Above behavior appeared for .m-files (MatLab).
After testing it with .txt files, all files were wiped.
The way you're copying the file, with dst << src.rdbuf();, will leave the current file position at the end of your input file. On the second iteration, that same read won't read anything (leaving an empty copy of the file) because you're already at the end of the input file.
The solution is to seek back to the beginning of the input file before every read, using seekg. You should call tellg before reading anything (right after opening the file), then seek to that position.
auto startpos = src.tellg();
ofstream dst;
// ...
src.seekg(startpos);
dst << src.rdbuf();
None of the proposed methods work.
Neither resetting the pointer, nor pulling ifstream into the loop, which would result in opening the input file (which is not supposed to change) unnecessarily often.
It is still unclear why dst.open(outputPaths[i]); is wiping the input file. Also the exact moment of the wipe depends on used types of files.
I implemented following workaround, effectively reading the input file into a string and closing it beforehand, in order to protect it from further read/write action.
bool update_files( const string inputPath, const vector<string> outputPaths)
{
const char * in = inputPath.c_str();
ifstream src(in);
if(!src.is_open())
{
cout << "Unable to open input file\n" << inputPath <<endl;
return false;
}
else
{
string buffer;
streamsize s=src.gcount();
src.seekg(0,ios::end);
buffer.reserve(src.tellg());
src.seekg(0,ios::beg);
buffer.assign((istreambuf_iterator<char>(src)), istreambuf_iterator<char>());
src.close();
for(unsigned int i=0; i<= outputPaths.size()-1; i++)
{
const char * out = outputPaths[i].c_str();
ofstream dst(out);
try
{
dst << buffer;
dst.close();
}
catch(int e)
{
cout << "Unable to replace file\n" <<endl;
cout << outputPaths[i] <<"\n"<< endl;
cout << "Error code: " <<e<<endl;
}
}
};
src.close();
return true;
}

C++ text document

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 &paragraph, 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 &paragraph, 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.

Am I missing something? I keep outputting "No file found!"

void getBookData(bookType books[], int& noOfBooks)
{
ifstream infile;
string file = "bookData.txt";
infile.open(file.c_str());
if (infile.fail()) {
cout << "No file found!" << endl;
infile.clear();
}
while (true) {
string line;
getline(infile, line, '\r');
if (infile.fail()) {
break;
}
cout << "Line: " << line << endl;
}
infile.close();
}
I've tried putting the file in every location I can think of, but somehow it's not loading in. Or, more likely, I'm doing something else wrong. This isn't anything like what the end result of my code is supposed to be like, right now I'm just trying to read out my file line by line.
I guess you really need help debugging why this is happening to you.
Try adding some more code to your routine to help you determine what is going on. One thing to try is to call getcwd.
#include <unistd.h>
...
char buf[PATH_MAX];
std::cout << "cwd: " << getcwd(buf, sizeof(buf)) << std::endl;
...
This should report to you where your program thinks it is running from.
Start with that first, and I am guessing the next steps will become obvious to you.

Reading through file using ifstream

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?