Results 1 to 10 of 10

Thread: Reverse Edit File

  1. #1

    Thread Starter
    Addicted Member
    Join Date
    Jan 2017
    Posts
    199

    Reverse Edit File

    Hello,
    can someone help me , how to make reverse option from this code.
    With this code i make edit the file .txt to insert the name of the account in the file.

    Now i need an reverse code to remove the name account from the file.

    Example:
    In the file has this information:

    [File]
    Test1
    Test3
    Test5
    [/EndFile]

    so if i use the reverse code , for example to find the user account if exists inside to remove it from the file .
    Example my account name is "Test3" and when code checks that i use the name Test3 will make the file like this:

    [File]
    Test1
    Test5
    [/EndFile]

    Important is to not have blank spaces after it removes the Account name from the file.

    The code that i use for add the account name in the file is this:
    Code:
    std::vector<std::string> example;
    example.push_back(lpUser->AccountID);
    
    std::fstream of("..\\Data\\Custom\\VipUsers.txt");
    
    if (!of.is_open()) 
    {
    	of.open("..\\Data\\Custom\\VipUsers.txt", std::ios_base::out);
    }
    
    of.seekp(0, std::ios::end);
    std::ostream_iterator<std::string> oi(of, "\n");
    copy(example.begin(), example.end(), oi);
    //End Push it

  2. #2
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    Assuming that the lines in the file don't contain white-space chars, then one way you do this is:

    Code:
    #include <vector>
    #include <string>
    #include <fstream>
    #include <algorithm>
    #include <iterator>
    #include <iostream>
    using namespace std;
    
    const string tfilnam = "names.txt";  // "..\\Data\\Custom\\VipUsers.txt"
    const string remnam = "Test3";  // lpUser->AccountID
    
    int main()
    {
    	ifstream ifs(tfilnam);
    
    	if (!ifs.is_open())
    		return cout << "Cannot open input file " << tfilnam << endl, 1;
    
    	vector<string> data((istream_iterator<string>(ifs)), istream_iterator<string>());
    
    	ifs.close();
    
    	ofstream ofs(tfilnam);
    
    	if (!ofs.is_open())
    		return cout << "Cannot open output file " << tfilnam << endl, 1;
    
    	data.erase(remove_if(data.begin(), data.end(), [&](const string& st) {return st == remnam;}), data.end());
    	copy(data.begin(), data.end(), ostream_iterator<string>(ofs, "\n"));
    	ofs.close();
    }
    If the lines in the file do contain white space chars, then you'll need to have separate code to read the file into the vector instead of doing it as part of the vector constructor.

    It reads the whole file into a vector, finds and removes the required line from this vector, closes and re-opens the file for output and then write the changed vector back to the file.

    There are ways of doing this without reading the whole file into memory but assuming that the file will fit into memory this is probably the easiest. Note that this method is not the fastest but for small files performance probably doesn't matter. If performance is an issue, I can let you have more complicated but faster code.
    Last edited by 2kaud; Jun 25th, 2018 at 01:28 PM.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3

    Thread Starter
    Addicted Member
    Join Date
    Jan 2017
    Posts
    199

    Re: Reverse Edit File

    yes it would be nice to make it easier and more advanced code in C++ without using ofstream, because its not much good to use the memory it will make the application run slow, because it calls tons of calls in seconds.
    If there is other method to do this , i would be glad if you could help me out. Thank you for your time , advices and help man.

  4. #4
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    Deleting in the middle of a file is non-trivial. There are basically three ways:

    1) Read the file into memory, make the changes() and write the file back out overwriting the existing file. This is as per the code in post #2 - although depending upon how large this file is, this method can be speeded up somewhat.

    2) Read the file into a temporary file upto the line to be removed, read that line and discard, copy the rest of the file to the temp. Then delete the original and rename the temp as the original.

    3) Read the file upto the line to be removed (need to keep position of beginning of line read), find the position of the start of the line following the one to be removed and copy the rest of the file from the position of the following line to the position of the removed line. Effectively shuffling the file down.

    Really, I suggest that the speeded up method of 1) would probably be your best case. How large is this file? 2) and 3) would probably be slower. I'll put together the speeded up version of 1) and post.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    Try this. The speed should be OK for what you want. Note that it's c++17 code.

    Code:
    #include <string>
    #include <fstream>
    #include <iostream>
    #include <memory>
    #include <cstring>
    #include <string_view>
    using namespace std;
    
    const string tfilnam = "names.txt";
    const string remnam = "Test3";
    
    struct FileData {
    	string_view fdata {};
    	unique_ptr<char> buffer = nullptr;
    };
    
    [[nodiscard]]
    FileData readFile(std::ifstream& fs, char term = '\n')
    {
    	if (!fs.is_open())
    		return FileData {};
    
    	fs.clear();
    	fs.seekg(0, fs.end);
    
    	const auto fsz = static_cast<size_t>(fs.tellg()) + 1;
    	FileData fd;
    
    	fd.buffer.reset(new char[fsz]);
    	fs.seekg(0);
    	fs.read(fd.buffer.get(), fsz - 1);
    
    	const auto bufflen = static_cast<size_t>(fs.gcount());
    
    	fd.buffer.get()[bufflen] = term;
    	fd.fdata = string_view(fd.buffer.get(), bufflen);
    
    	return fd;
    }
    
    int main()
    {
    	ifstream ifs(tfilnam);
    
    	if (!ifs.is_open())
    		return cout << "Cannot open file " << tfilnam << endl, 1;
    
    	auto[fdata, buff] = readFile(ifs);
    
    	size_t spos = 0;
    	size_t res = 0;
    
    	do {
    		res = fdata.find(remnam, spos);
    
    		if ((res != string_view::npos) && (fdata[res + remnam.size()] != '\n'))
    			spos += remnam.size();
    
    	} while ((res != string_view::npos) && (fdata[res + remnam.size()] != '\n'));
    
    	if (res == string_view::npos)
    		return cout << "Cannot find data " << remnam << endl, 2;
    
    	const auto datastart = fdata.data() + res;
    
    	memcpy(const_cast<char*>(datastart), datastart + remnam.size() + 1, fdata.size() - res);
    	fdata.remove_suffix(remnam.size() + 1);
    	ifs.close();
    
    	ofstream ofs(tfilnam);
    
    	if (!ofs.is_open())
    		return cout << "Cannot open file " << tfilnam << endl, 3;
    
    	ofs.write(fdata.data(), fdata.size());
    	ofs.close();
    }
    Last edited by 2kaud; Jun 26th, 2018 at 03:05 PM. Reason: Distinguish Test33 from Test3
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  6. #6

    Thread Starter
    Addicted Member
    Join Date
    Jan 2017
    Posts
    199

    Re: Reverse Edit File

    hi thanks for information, but i use visual studio 2010 to build c++ and i do not understand this code
    for example for how to get the accountid and remove it the calls of this

  7. #7
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    I suggest you update to the latest visual studio VS2017 which supports c++17. VS2010 is now 18 years old and doesn't even support the c++11 standard - never mind the current c++17 standard. You are effectively constrained to the c++98 standard which is now massively outdated. Coming from effectively c++98 (there was a c++03 that was mainly a tidying up of the words in the standard) to c++17 is going to be something of a shock - as you haven't got to grips with the intervening c++ standards. Following c++98 (apart from c++03) there was c++11 which brought huge changes to the language, then c++14 which was really only a minor upgrade - and then c++17 which again brought big changes to the c++ standard. I suggest that you get a good c++ book that covers c++17 so that you can learn it.

    PS As this is test sample code, you'll need to modify this for your own usage. The variable remnam is the text of the line to be removed. Here it is just set to the constant Test3 (as per your usage from post #1) - but in your actual program you'll probably want to set it to lpUser->AccountID (possibly as a reference variable). Same with the variable tfilnam. For the purposes of this test, it is set to names.txt, but you'll want to set it to "..\\Data\\Custom\\VipUsers.txt".
    Last edited by 2kaud; Jun 26th, 2018 at 06:08 AM. Reason: PS
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  8. #8
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    I think this is the c++98 version of the revised code in post #5 - so it should compile with VS2010.

    Code:
    #include <string>
    #include <fstream>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const string tfilnam = "names.txt";
    const string remnam = "Test3";
    
    int main()
    {
    	ifstream ifs(tfilnam);
    
    	if (!ifs.is_open())
    		return cout << "Cannot open file " << tfilnam << endl, 1;
    
    	ifs.seekg(0, ifs.end);
    
    	const size_t fsz = static_cast<size_t>(ifs.tellg()) + 2;
    	char *const buffer = new char[fsz];
    
    	ifs.seekg(0);
    	ifs.read(buffer, fsz - 1);
    
    	size_t bufflen = static_cast<size_t>(ifs.gcount());
    
    	buffer[bufflen] = '\n';
    	buffer[bufflen + 1] = 0;
    
    	const char* datastart = NULL;
    	const char* strt = buffer;
    
    	do {
    		datastart = strstr(strt, remnam.c_str());
    
    		if ((datastart != NULL) && (*(datastart + remnam.size()) != '\n'))
    			strt += remnam.size();
    
    	} while (datastart != NULL && (*(datastart + remnam.size()) != '\n'));
    
    	if (datastart == NULL)
    		return cout << "Cannot find data " << remnam << endl, 2;
    
    	memcpy(const_cast<char*>(datastart), datastart + remnam.size() + 1, bufflen - (datastart - buffer));
    	bufflen -= remnam.size() + 1;
    	ifs.close();
    
    	ofstream ofs(tfilnam);
    
    	if (!ofs.is_open())
    		return cout << "Cannot open file " << tfilnam << endl, 3;
    
    	ofs.write(buffer, bufflen);
    	ofs.close();
    
    	delete[] buffer;
    }
    Last edited by 2kaud; Jun 26th, 2018 at 02:55 PM.
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  9. #9
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: Reverse Edit File

    they really jumped the shark with the comma operator...

  10. #10
    Fanatic Member 2kaud's Avatar
    Join Date
    May 2014
    Location
    England
    Posts
    996

    Re: Reverse Edit File

    Quote Originally Posted by DEXWERX View Post
    they really jumped the shark with the comma operator...
    All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width