• Announcements

    • khawk

      Download the Game Design and Indie Game Marketing Freebook   07/19/17

      GameDev.net and CRC Press have teamed up to bring a free ebook of content curated from top titles published by CRC Press. The freebook, Practices of Game Design & Indie Game Marketing, includes chapters from The Art of Game Design: A Book of Lenses, A Practical Guide to Indie Game Marketing, and An Architectural Approach to Level Design. The GameDev.net FreeBook is relevant to game designers, developers, and those interested in learning more about the challenges in game development. We know game development can be a tough discipline and business, so we picked several chapters from CRC Press titles that we thought would be of interest to you, the GameDev.net audience, in your journey to design, develop, and market your next game. The free ebook is available through CRC Press by clicking here. The Curated Books The Art of Game Design: A Book of Lenses, Second Edition, by Jesse Schell Presents 100+ sets of questions, or different lenses, for viewing a game’s design, encompassing diverse fields such as psychology, architecture, music, film, software engineering, theme park design, mathematics, anthropology, and more. Written by one of the world's top game designers, this book describes the deepest and most fundamental principles of game design, demonstrating how tactics used in board, card, and athletic games also work in video games. It provides practical instruction on creating world-class games that will be played again and again. View it here. A Practical Guide to Indie Game Marketing, by Joel Dreskin Marketing is an essential but too frequently overlooked or minimized component of the release plan for indie games. A Practical Guide to Indie Game Marketing provides you with the tools needed to build visibility and sell your indie games. With special focus on those developers with small budgets and limited staff and resources, this book is packed with tangible recommendations and techniques that you can put to use immediately. As a seasoned professional of the indie game arena, author Joel Dreskin gives you insight into practical, real-world experiences of marketing numerous successful games and also provides stories of the failures. View it here. An Architectural Approach to Level Design This is one of the first books to integrate architectural and spatial design theory with the field of level design. The book presents architectural techniques and theories for level designers to use in their own work. It connects architecture and level design in different ways that address the practical elements of how designers construct space and the experiential elements of how and why humans interact with this space. Throughout the text, readers learn skills for spatial layout, evoking emotion through gamespaces, and creating better levels through architectural theory. View it here. Learn more and download the ebook by clicking here. Did you know? GameDev.net and CRC Press also recently teamed up to bring GDNet+ Members up to a 20% discount on all CRC Press books. Learn more about this and other benefits here.
Sign in to follow this  
Followers 0
Boooke

Copy .txt data to another .txt file

5 posts in this topic

Hello, I do not really figure how to solve this problem. I am to make a database in a text file, and I would like to delete specific users in the file without affecting the rest of the file. To do so, I read the user list into a copied text file (Which seems to work somewhat fine), until I find the specific "ID" i want to delete. From here I continue to read the input file but avoid copying it over to the other text-file. It should then stop doing this when it finds another ID tag, but this seems to fail, Also, I want to copy the copied text file back to the original file because of the orignal filename is needed. Here it seems to fail, and the only output copied is "0x28fad4".





This is the function
[CODE]
void erase(std::string ID)
{
std::ifstream inFile("userlist.txt");
std::ofstream outCopy("copy.txt");
std::string buffer;
bool copyDone = false;
while (getline(inFile, buffer))
{
if (buffer == ("ID: " + ID))
{
while (getline(inFile, buffer) && buffer != "ID: ");
copyDone = true;
buffer.clear();
std::cout << "ID Found. Deleting user.";
}
outCopy << buffer;
std::cout << buffer << std::endl;
}
if (copyDone == false)
{
std::cout << "ID not present in userlist.";
outCopy.close();
inFile.close();
remove("copy.txt");
return;
}
inFile.close();
outCopy.close();
inFile.open("copy.txt");
outCopy.open("userlist.txt", std::ios::trunc);
if (outCopy.good())
std::cout << "Hej.";
outCopy << inFile;
inFile.close();
outCopy.close();
//remove("copy.txt");
}
[/CODE]

here is userlist.txt, where ID: 111d should be deleted
[CODE]
Hello.
ID: 111d
Test.
ID: 202d
Should be kept safe from harm.
[/CODE]

The copy.txt where everything concerning ID: 111d should have been removed ,but not IDs after,
[CODE]
Hello.
[/CODE]
The userlist.txt after erase(string) now only contain,
[CODE]
0x28fad4
[/CODE]


I guess the read loop inside the first while loop needs another condition, and the way I try to copy input from inFile to inCopy do not work, but I thought it could have been interesting to know, if it was possible to copy from the copied text back again without getline().

Regards,
Boooke
0

Share this post


Link to post
Share on other sites
Im not sure if this is the issue but it appears that you are clearing the buffer then latter attempting to write the empty buffer when you find the ID you are looking for. [quote name='Boooke' timestamp='1332754643' post='4925296'][code]
if (buffer == ("ID: " + ID))
{
while (getline(inFile, buffer) && buffer != "ID: ");
copyDone = true;
buffer.clear();
std::cout << "ID Found. Deleting user.";
}
outCopy << buffer;
std::cout << buffer << std::endl;[/code]
[/quote]

Did you mean to put the second part inside an else block?
[code] outCopy << buffer;
std::cout << buffer << std::endl;[/code]
0

Share this post


Link to post
Share on other sites
Yeah, I actually looked at that and it seemed at bit wrong, but I wasn't sure. It would be a good idea to put it into an else-statement. Thank you for the tip! I completely forgot about that one. But I still do not figure how I faulted the copy-section.
0

Share this post


Link to post
Share on other sites
[quote name='Boooke' timestamp='1332754643' post='4925296']
[code]
if (buffer == ("ID: " + ID))
{
[/code]
[/quote]
C++ doesn't do native string concatenation like one would expect:
[code]
int main() {
const char* str = "Test: " + 3; // Pointer arithmetic, not concatenation
cout << '"' << str << '"' << endl;
}
[/code]
Output:
[tt]"t: "[/tt]

The C++ way would probably look something like this:
[code]
istringstream ss( buffer );
string prefix, extra;
int value;
ss >> prefix >> value;
getline( ss, extra );
if ( ss && prefix == "ID:" && extra.empty() ) {
// Do something with value
} else {
// Error
}
[/code]
0

Share this post


Link to post
Share on other sites
Given that you appear to require the database to fit in memory, I would recommend reading the database just once at startup. Read it into a record type. When changes are made to the database, add or remove these records from the collection in memory, and then write the data from memory to the file*.
This will be easier than writing multiple routines that trying to add or remove records while streaming the text from the file. It also separates the structure of the file from the logic - you can change the loader / saver without having to modify the way adding, removing, searching or sorting is done internally.


* How and when to write the data depends on how much you care about the data:
[list]
[*] If you don't care (e.g. test program), you can just write the data when the user quits the program.
[*] If you care a little bit about data, write changes immediately after any non-read operation.
[*] If you moderately care about data, it is better to write the data to a temporary file first, and use an atomic rename to "replace" the file once you are sure it has been written correctly to disk.
[*] If you really care about data loss, you'll use an ACID database to store it.
[/list]

You don't need to explicitly close std::fstreams. You shouldn't re-use them, as you would need to account for the various error reporting flags. For example, if your streams become invalid (e.g. the filesystem becomes full or some other program has obtained a lock on the file), then you will lose all data in the file. You need much more careful error handling to avoid data loss and corruption.

[edit: I misread your code. You don't appear to require the data to fit into memory. Still, consider the above points]
0

Share this post


Link to post
Share on other sites
The plan is to read everything into a dynamic struct at some point. In the beginning would be a good idea. Maybe it would be much quicker to just edit the struct element that needs to be editted and then rewrite the whole "database", instead of having to edit the .txt and then read to the struct? Gonna try that, at least.

I know little of database-structuring. However, I will write the data to a copy.txt every time I change it in the struct and then I will read the copy to the now erased userlist.txt.. I am not sure if that is what you meant. But thank you for the ACID-model idea. If I have time, it would be a great idea to implement, also for exercising use in real projects.

I guess a lot of the erase() function i made is now inefficient, but the parts I need are actually still defunct, since I copying from text to text seems to give me some problems with the input.
0

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0