C++ localtime函数异常求助:时间值异常且localtime_s无法使用
Let's break down what's going wrong with your time code and fix it step by step:
The Root Problems
You're not capturing the result of
localtime
When you calllocaltime(¤t), it returns a pointer to a populatedtmstruct—but you never assign that pointer to yournowvariable. That meansnow.tm_hour,now.tm_min, andnow.tm_secare uninitialized garbage values, which explains those huge, nonsensical numbers.localtime_susage was incorrect
VS Code (with MSVC compiler) flagslocaltimeas unsafe because it uses a shared global buffer (risky in multi-threaded code) and recommendslocaltime_sinstead. If it wasn't working for you, it's likely because you didn't follow its correct parameter format.
Fixed Code
Here's the corrected version of your function, with proper time handling, safety, and clean formatting:
#include <iostream> #include <string> #include <sstream> #include <fstream> #include <ctime> #include <iomanip> // Needed for setw/setfill to pad numbers with zeros // Assume these functions are defined elsewhere std::string show() { return "Sample content for the file"; } void print_time() { // Your print_time implementation here } void write(std::string team_name) { // Get current time time_t current_time = time(0); struct tm local_time{}; // Initialize struct to avoid garbage values // Use localtime_s (safe, MSVC-recommended version) errno_t time_err = localtime_s(&local_time, ¤t_time); if (time_err != 0) { std::cerr << "Error getting local time!" << std::endl; return; } // Format time as HH:MM:SS (with leading zeros for single-digit values) std::stringstream time_stream; time_stream << std::setw(2) << std::setfill('0') << local_time.tm_hour << ":" << std::setw(2) << std::setfill('0') << local_time.tm_min << ":" << std::setw(2) << std::setfill('0') << local_time.tm_sec; // Create a clean filename (added underscores for readability) std::stringstream filename_stream; filename_stream << "Filename_" << team_name << "_" << time_stream.str() << ".txt"; // Open and write to the file std::ofstream output_file(filename_stream.str()); if (output_file.is_open()) { output_file << show(); print_time(); // Removed the unnecessary declaration here output_file.close(); } else { std::cerr << "Failed to open output file!" << std::endl; } }
Key Improvements Explained
- Proper
localtime_susage: This function takes two pointers (yourtmstruct and thetime_tvalue) and returns an error code to check if it succeeded—no more shared global buffers. - Struct initialization:
struct tm local_time{};zero-initializes the struct, so even if something goes wrong, you won't get random garbage values. - Leading zeros for time:
std::setw(2)andstd::setfill('0')ensure single-digit hours/minutes/seconds are padded with a zero (e.g., 9:5:3 becomes09:05:03), matching your desiredHH:MM:SSformat. - Cleaner filenames: Added underscores between filename parts so
TeamA+163030becomesTeamA_163030instead ofTeamA163030. - Error checking: Added checks for time retrieval and file opening to catch issues early.
If You Must Use localtime (Not Recommended)
If you need to use the older localtime function (not safe for multi-threaded code), you have to capture its returned pointer and copy the data into your struct:
struct tm* time_ptr = localtime(¤t_time); if (time_ptr != nullptr) { local_time = *time_ptr; } else { std::cerr << "Error getting local time!" << std::endl; return; }
But stick with localtime_s—it's the safer, standard-compliant choice for modern Windows/C++ development.
内容的提问来源于stack exchange,提问作者frushan

