我正在编写一个程序,需要将当前日期和时间写入日志文件,虽然代码正常,但有很多重复代码。代码是
#include<iostream>
#include<fstream>
#include<unistd.h>
using namespace std;
string logFile="/home/shared/c++/time.log";
char timeBuffer[80];
int main()
{
struct tm * timeInfo;
time_t rawtime;
ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out);
{
{
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo);
string timeNow(timeBuffer);
cout << timeNow << " - Start of log." << endl;
vLog << timeNow << " - Start of log." << endl;
}
// Do a part of the code
{
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo);
string timeNow(timeBuffer);
cout << " " << timeNow << " - 1st Line of log." << endl;
vLog << " " << timeNow << " - 1st Line of log." << endl;
}
// Do more code
{
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo);
string timeNow(timeBuffer);
cout << " " << timeNow << " - 2nd Line of log." << endl;
vLog << " " << timeNow << " - 2nd Line of log." << endl;
}
// Do the last part of the code
{
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo);
string timeNow(timeBuffer);
cout << timeNow << " - End of log." << endl;
vLog << timeNow << " - End of log." << endl;
}
}
}
我必须在每个部分包含{},以便变量仅用于一个特定的代码块。如果我不使用它们,那么我在编译时会遇到错误。
time.cpp: In function "int main()":
time.cpp:54:29: error: redeclaration of "std::string timeNow"
string timeNow(timeBuffer);
^
time.cpp:45:11: error: "std::string timeNow" previously declared here
string timeNow(timeBuffer);
^
包含括号,然后编译并运行没有问题。
将写入日志文件的信息会有所不同,因此需要与时间分开。
由于我是C ++的新手,我觉得我过度使问题复杂化,所以任何指导都会受到赞赏。 我正在运行CentOS 7和g ++(GCC)4.8.5 20150623(Red Hat 4.8.5-11)
此致 琥珀色 - 马里
感谢您的帮助。完整的代码现在是:
#include<iostream>
#include<fstream>
#include<unistd.h>
std::string logFile="/home/shared/c++/time.log";
char timeBuffer[80];
void getTime(std::ofstream &vLog, const std::string &format_args, const std::string &message)
{
struct tm * timeInfo;
time_t rawtime;
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),format_args.c_str(),timeInfo);
std::string timeNow(timeBuffer);
std::cout << timeNow << message << std::endl;
vLog<< timeNow << message << std::endl;
}
int main()
{
std::ofstream vLog(logFile.c_str(), std::ios_base::app | std::ios_base::out);
getTime(vLog, "%A %d %b %Y %r %Z", " - Start of logging");
// Do part of the code
getTime(vLog, " %r", " - 1st line of log");
// Do more code
getTime(vLog, " %r", " - 2nd line of log");
// Do the last part of the code
getTime(vLog, "%A %d %b %Y %r %Z", " - End of logging");
vLog << std::endl;
return (0);
}
希望其他人会觉得这很有帮助。
琥珀 - 马里
答案 0 :(得分:1)
编写一个函数来包装你的代码。参数应该是ofstream,strftime格式参数和日志消息(“ - 第一行代码”,..)
void foo(ofstream &vLog, const string &format_args, const string &message)
{
struct tm * timeInfo;
time_t rawtime;
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),format_args.c_str(),timeInfo);
string timeNow(timeBuffer);
cout << timeNow << message << endl;
vLog<< timeNow << message << endl;
}
int main()
{
ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out);
foo(vLog, "%A %d %b %Y %r %Z", " - 1st Line of log.");
// Do a part of the code
foo(/* second call */);
// Other stuff
foo(/* 3rd call */);
// ...
return 0;
}
答案 1 :(得分:0)
问题是你要重新声明变量&#34; timeNow&#34;并调用其构造函数为其赋予&#34; timeBuffer&#34;的值。这与括号一起使用,因为每个括号都是新范围。每次重新声明&#34; timeNow&#34;对于它的所有其他声明是不可见的,因此编译器的部分没有混淆。要摆脱这种情况,请使用赋值而不是尝试重新声明变量。使用timeNow = timeBuffer
而不是
string timeNow(timeBuffer);
我尝试了这段代码,它在我的结尾使用g ++:
int main()
{
struct tm * timeInfo;
time_t rawtime;
ofstream vLog(logFile.c_str(), ios_base::app | ios_base::out);
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo);
string timeNow(timeBuffer);
cout << timeNow << " - Start of log." << endl;
vLog << timeNow << " - Start of log." << endl;
// Do a part of the code
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo);
timeNow = timeBuffer;
cout << " " << timeNow << " - 1st Line of log." << endl;
vLog << " " << timeNow << " - 1st Line of log." << endl;
// Do more code
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%r",timeInfo);
timeNow = timeBuffer;
cout << " " << timeNow << " - 2nd Line of log." << endl;
vLog << " " << timeNow << " - 2nd Line of log." << endl;
// Do the last part of the code
time (&rawtime);
timeInfo = localtime(&rawtime);
strftime(timeBuffer,sizeof(timeBuffer),"%A %d %b %Y %r %Z",timeInfo);
timeNow = timeBuffer;
cout << timeNow << " - End of log." << endl;
vLog << timeNow << " - End of log." << endl;
}
答案 2 :(得分:0)
是的,这是可能的:)
让我们首先考虑整个获取和格式化时间的业务。重复代码中唯一可变的东西是格式字符串,所以让它成为一个参数:
std::string formattedCurrentTime(char const *const format) {
std::time_t const rawTime = std::time(nullptr);
std::tm const *const timeInfo = std::localtime(&rawTime);
char buffer[80];
std::size_t const length = std::strftime(buffer, sizeof buffer, format, timeInfo);
return {buffer, buffer + length};
}
然后我们可以看一下日志行的重复。由于整个operator <<
重载和多态性业务,一般解决方案实现起来有点棘手,但您的案例看起来足够一致,可以从定制解决方案中受益:
auto const logBookend = [&](std::string const &message) {
auto const timeNow = formattedCurrentTime("%A %d %b %Y %r %Z");
std::cout << timeNow << " - " << message << std::endl;
vLog << timeNow << " - " << message << std::endl;
};
auto const logLine = [&](std::string const &message) {
auto const timeNow = formattedCurrentTime("%r");
std::cout << timeNow << " - " << message << std::endl;
vLog << timeNow << " - " << message << std::endl;
};
注意:请参阅this question了解不为何使用using namespace std;
。