std::ofstream错误覆盖文件行:文本输出函数问题排查
Hey there, let's break down why your File_IO::save function is having trouble with unexpected line overwrites, and walk through solutions to fix it.
First, let's recap the key parts of your code that might be contributing to the problem:
void File_IO::save( const std::string& path_ ) const { const std::string file_name = path_ + this->local_time() + ".txt"; std::ofstream outfile( file_name ); std::vector<std::string> vec = { "One", "Two", "Three", "Four" }; outfile << '\n' << '\n' << "//--------------------------------- DATA:" << '\n' << '\n'; long pos_beg = outfile.tellp(); for( auto& i : vec ) { outfile << i << '\n'; // ... your omitted code here } }
Common Causes & Fixes
1. Duplicate File Names Triggering File Truncation
Your filename uses local_time() to make it unique, but if the time precision is too low (e.g., only to the second), calling save() multiple times in the same second will generate the exact same filename. By default, std::ofstream opens files with std::ios::out | std::ios::trunc mode—this clears the entire file before writing, which looks like your lines are being overwritten.
How to fix it:
- Boost the precision of your timestamp to ensure unique filenames every time. For example, add milliseconds:
#include <chrono> std::string precise_local_time() { auto now = std::chrono::system_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()) % 1000; std::time_t curr_time = std::chrono::system_clock::to_time_t(now); std::tm local_tm = *std::localtime(&curr_time); char time_buf[25]; std::strftime(time_buf, sizeof(time_buf), "%Y%m%d_%H%M%S", &local_tm); return std::string(time_buf) + "_" + std::to_string(ms.count()); } - Alternatively, check if the file exists before opening it, and handle duplicates (like appending a counter or switching to append mode):
std::ifstream file_check(file_name); if (file_check.good()) { // File exists—either warn the user or switch to append mode std::cerr << "Warning: " << file_name << " already exists. Appending instead.\n"; outfile.open(file_name, std::ios::out | std::ios::app); } else { outfile.open(file_name); }
2. Accidental File Pointer Movement
You’re using outfile.tellp() to record the starting position after your header. If the omitted code (...) uses outfile.seekp() to jump back to an earlier position in the file, you’ll overwrite lines you already wrote.
How to fix it:
- Audit the omitted code to remove any unintended
seekp()calls. If you do need to move the pointer temporarily, make sure to reset it to the end of the file before continuing your loop:long pos_beg = outfile.tellp(); // Temporary pointer movement for some operation outfile.seekp(some_old_position); // ... do your work ... // Reset to the end of the file to resume appending outfile.seekp(0, std::ios::end);
3. Wrong File Opening Mode
If your goal is to add content to an existing file (instead of creating a new one every time), using the default mode will overwrite the entire file.
How to fix it:
- Use
std::ios::app(append) mode to force all writes to go to the end of the file:std::ofstream outfile(file_name, std::ios::out | std::ios::app); - If you need to both read and write to the file, use
std::ios::in | std::ios::out—just note this will fail if the file doesn’t already exist.
Quick Verification Steps
- Print the
file_namevariable before opening the file to confirm it’s unique each time you callsave(). - Double-check the omitted code for any
seekp()operations that might be rewinding the write pointer. - Confirm the file opening mode matches your intended behavior (create new file vs. append to existing).
内容的提问来源于stack exchange,提问作者LearnMore

