使用ofstream出错,谁能帮帮我~
时间:2010-08-31
来源:互联网
本帖最后由 smallest10 于 2010-08-31 19:37 编辑
很简单的一段代码
复制代码
情况是这样的,我们之前做了一个软件,用VC 6 开发的,现在要加一个日志模块,我打算借用std标准库中的ofstream来实现软件中的日志模块。但是上边一段代码始终不能成功。
是个MFC 程序,我把这段代码放在 MFCTestApp::InitInstance()中。新建一个空的MFC程序,加上这段代码,一点问题没有。可是在我们目前已经开发好的代码中加上上边那段代码就出问题了,文件能正常创建,但是写入失败!程序执行完关闭后,omg.txt中内容为空(0字节)。在代码中间加了 outp.tellp(),返回值为-1。 outp.is_open() 返回为true. outp.good()为true,
这个该怎么整啊?
哪位大侠知道怎么查outp.tellp()返回-1是什么问题吗? 试过 outp.seekp(0) , outp.seekp(10) ,再调用 outp.tellp() ,返回值仍是 -1 ,谁能指点一二?
谢啦~~
++++++++++++++++++++++++++++++++++++++
另外,我脸皮厚,不怕丢人,无敌了~~~~~顺便贴上我自己赶时间速写的一个日志类,抄的 log4cplus,log4cplus里边那个Appender和Logger分开我很喜欢,很灵活,所以抄它的。抄的不好,见笑,大家指点一下。是时间该转向linux了,希望这个项目尽快完结。
很简单的一段代码
- std::ofstream outp;
- outp.open("omg.txt");
- outp<<"oh my god,what's the hell";
- outp.flush();
- outp.close();
是个MFC 程序,我把这段代码放在 MFCTestApp::InitInstance()中。新建一个空的MFC程序,加上这段代码,一点问题没有。可是在我们目前已经开发好的代码中加上上边那段代码就出问题了,文件能正常创建,但是写入失败!程序执行完关闭后,omg.txt中内容为空(0字节)。在代码中间加了 outp.tellp(),返回值为-1。 outp.is_open() 返回为true. outp.good()为true,
这个该怎么整啊?
哪位大侠知道怎么查outp.tellp()返回-1是什么问题吗? 试过 outp.seekp(0) , outp.seekp(10) ,再调用 outp.tellp() ,返回值仍是 -1 ,谁能指点一二?
谢啦~~
++++++++++++++++++++++++++++++++++++++
另外,我脸皮厚,不怕丢人,无敌了~~~~~顺便贴上我自己赶时间速写的一个日志类,抄的 log4cplus,log4cplus里边那个Appender和Logger分开我很喜欢,很灵活,所以抄它的。抄的不好,见笑,大家指点一下。是时间该转向linux了,希望这个项目尽快完结。
作者: smallest10 发布时间: 2010-08-31
本帖最后由 smallest10 于 2010-08-31 19:37 编辑
复制代码
- // Logger.h: interface for the Logger class.
- //
- //////////////////////////////////////////////////////////////////////
-
- #if !defined(AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_)
- #define AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_
-
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
-
- #include <string>
- #include <fstream>
- #include <vector>
- #include <sstream>
- using std::string;
-
- namespace skgLogger{
-
- typedef int LogLevelType;
-
- const LogLevelType INFO_LOG_LEVEL = 0x03; // 0011
- const LogLevelType ERROR_LOG_LEVEL = 0x02; // 0010
- const LogLevelType WARN_LOG_LEVEL= 0x01; // 0001
- const LogLevelType NONE_LOG_LEVEL = 0x00; // 0000
- //const LogLevelType LEVEL_TRACE= 0x04 // 0100 ===== another output way
-
-
- typedef std::ios::openmode LOG_OPEN_MODE_TYPE;
-
-
- #define LOG_TRACE_MACRO_BODY(logEvent) \
- do { \
- if(Logger::isTraceable()) { \
- std::ostringstream _out_buf; \
- _out_buf << logEvent << "\n"; \
- TRACE((_out_buf.str().append(__FILE__).append(__LINE__)).c_str()); \
- } \
- } while (0)
-
- // note that the logEvent argument is string type
- #define LOG_TRACE_MACRO_STR_BODY(logEvent) \
- do { \
- if(Logger::isTraceable()) { \
- TRACE((logEvent.append(__FILE__).append(__LINE__).append("\n")).c_str()) \
- } \
- } while (0)
-
- #define LOG_MACRO_BODY(logger, logEvent, logLevel) \
- do { \
- if((logger)->isEnabledFor(logLevel##_LOG_LEVEL)) { \
- std::ostringstream _out_buf; \
- _out_buf << logEvent; \
- (logger)->WriteLog(logLevel##_LOG_LEVEL, \
- _out_buf.str(), __FILE__, __LINE__); \
- } \
- } while (0)
-
- // if logEvent is a string, then we could call this MACRO instead of LOG_MACRO_BODY()
- // note that the logEvent argument is string type
- #define LOG_MACRO_STR_BODY(logger, logEvent, logLevel) \
- do { \
- if((logger)->isEnabledFor(logLevel##_LOG_LEVEL)) { \
- (logger)->WriteLog(logLevel##_LOG_LEVEL, \
- logEvent, __FILE__, __LINE__); \
- } \
- } while (0)
-
- // LOG_TRACE() 与 LOG_TRACE_STR() 有问题.未进行具体调试.
- #if !defined(LOG_DISABLE_TRACE)
- #define LOG_TRACE(logEvent) \
- LOG_TRACE_MACRO_BODY (logEvent)
- #define LOG_TRACE_STR(logEvent) \
- LOG_TRACE_MACRO_STR_BODY (logEvent)
- #else
- #define LOG_TRACE(logEvent) do { } while (0)
- #define LOG_TRACE_STR(logEvent) do { } while (0)
- #endif
-
-
- #if !defined(LOG_DISABLE_DEBUG)
- #define LOG_DEBUG(logger, logEvent) \
- LOG_MACRO_BODY (logger, logEvent, DEBUG)
- #define LOG_DEBUG_STR(logger, logEvent) \
- LOG_MACRO_STR_BODY (logger, logEvent, DEBUG)
- #else
- #define LOG_DEBUG(logger, logEvent) do { } while (0)
- #define LOG_DEBUG_STR(logger, logEvent) do { } while (0)
- #endif
-
-
- #if !defined(LOG_DISABLE_INFO)
- #define LOG_INFO(logger, logEvent) \
- LOG_MACRO_BODY (logger, logEvent, INFO)
- #define LOG_INFO_STR(logger, logEvent) \
- LOG_MACRO_STR_BODY (logger, logEvent, INFO)
- #else
- #define LOG_INFO(logger, logEvent) do { } while (0)
- #define LOG_INFO_STR(logger, logEvent) do { } while (0)
- #endif
-
-
- #if !defined(LOG_DISABLE_WARN)
- #define LOG_WARN(logger, logEvent) \
- LOG_MACRO_BODY (logger, logEvent, WARN)
- #define LOG_WARN_STR(logger, logEvent) \
- LOG_MACRO_STR_BODY (logger, logEvent, WARN)
- #else
- #define LOG_WARN(logger, logEvent) do { } while (0)
- #define LOG_WARN_STR(logger, logEvent) do { } while (0)
- #endif
-
-
- #if !defined(LOG_DISABLE_ERROR)
- #define LOG_ERROR(logger, logEvent) \
- LOG_MACRO_BODY (logger, logEvent, ERROR)
- #define LOG_ERROR_STR(logger, logEvent) \
- LOG_MACRO_STR_BODY (logger, logEvent, ERROR)
- #else
- #define LOG_ERROR(logger, logEvent) do { } while (0)
- #define LOG_ERROR_STR(logger, logEvent) do { } while (0)
- #endif
-
-
- #if !defined(LOG_DISABLE_FATAL)
- #define LOG_FATAL(logger, logEvent) \
- LOG_MACRO_BODY (logger, logEvent, FATAL)
- #define LOG_FATAL_STR(logger, logEvent) \
- LOG_MACRO_STR_BODY (logger, logEvent, FATAL)
- #else
- #define LOG_FATAL(logger, logEvent) do { } while (0)
- #define LOG_FATAL_STR(logger, logEvent) do { } while (0)
- #endif
-
- /************************************************************************/
- /* define class Logger */
- /************************************************************************/
- class Logger
- {
- public:
- static BOOL InitLogger();
- static Logger* GetInstance(const string& name); // 获得日志类的实例
- static void RemoveInstance(const string& name);
- static void RemoveInstance(const Logger* logger);
- static BOOL isTraceable();
- static void EnableTrace(BOOL traceable);
-
- // LOG_WANR 等宏会调用此函数
- void WriteLog(LogLevelType level, const string& message, const char* file="unkonw",int line=-1); // 日志打印接口
- virtual void PrintLog(const string& message); // 打印输出信息 --- not implemented yet.
-
- // LOG_WANR 等宏会调用此函数
- BOOL isEnabledFor(LogLevelType logLevel);
-
- inline string GetName() const;// the class member 'name' can only be assigned via GetInstance()
- inline LogLevelType GetLogLevel() const;
- inline void SetLogLevel(LogLevelType logLevel);
- BOOL initLogFile(const string& basename,
- long maxFileSize=10*1024*1024, // 10 MB
- BOOL immediateFlush=TRUE,
- LOG_OPEN_MODE_TYPE mode = std::ios::app);// call Open()
-
- // Logger 级别成员
- private:
- BOOL b_inited;//记录是否已经调用过 initLogFile() 方法
- string name;//name of this logger. 若想控制每个文件只对应一个Logger对象,将此变量的值改为basename的值即可.
- LogLevelType m_LogLevel; //日志输出等级, 默认为 LEVEL_INFO
- CRITICAL_SECTION cs_file; // 对象级别的临界区变量
- static CRITICAL_SECTION cs_loggerClassLevel;// 类级别的临界区变量
- static std::vector<Logger*> loggerList;
- static BOOL b_traceable;
-
- // 默认按 %y-%m-%d %H:%M:%S 格式来取得时间
- string GetTimeString(const char* timeFormat="%Y-%m-%d %H:%M:%S"); // 按格式获得日期
-
- // 文件级别成员
- private:
- string openedFilename;// 输出日志文件名 , 文件名格式如 basename_date_seq.log
- string basename;// 用于日志文件更换时,作为基文件名存在. 文件名格式如 basename_date_seq.log .如 srbw_20100901_1.log
- BOOL immediateFlush;
- std::ofstream stream_out;
- char* buffer;
- unsigned long bufferSize;
- long currentFileSize;
- long maxFileSize;
- int currentFileSeq;
- void Open(LOG_OPEN_MODE_TYPE mode);
- BOOL ReOpen();
- BOOL Rollover();// 当前日志文件已记录满,更换日志文件进行存储.
-
- private:
- // Disallow copying of instances of this class
- Logger(const string& name);
- Logger(const Logger&){} ////////////// need code, to prevent someone call this func in this class
- Logger(Logger*){} ////////////// need code, to prevent someone call this func in this class
- Logger& operator=(const Logger&){}////////////// need code, to prevent someone call this func in this class
- // Disallow deleting of instances of this class
- virtual ~Logger();
- };// end class Logger
-
-
- } // end namespace skgLogger
-
- #endif // !defined(AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_)
作者: smallest10 发布时间: 2010-08-31
- /************************************************************************
- *
- * Logger.cpp / Logger.h 定义了日志类与其他一些辅助函数. 用于日志记录.
- *
- * how to use this class:
- * 1. init Logger class
- * Logger::InitLogger();
- * 2. get an instance of Logger class
- * Logger* testLog=Logger::GetInstance("testLogName");
- * 3. init the instance ( here we determine the log filename, max file size,
- * flush mode { immediate flush or not },
- * file open mode { append, trunc, etc. } )
- * testLog->initLogFile("testLogFile",10*1024*1024,TRUE,std::ios::app);
- * 4. set log level
- * testLog->SetLogLevel(skgLogger::LogLevelType::LEVEL_ERROR);
- * 5. now we can log events. do it! ( use LOG_INFO(), LOG_WARN() or LOG_ERROR() )
- * LOG_WARN(testLog,"this is a new log record.")
- * 6. after all thing done,you should delete this instance. use RemoveInstance().
- * RemoveInstance(testLog);
- *
- * Here, everything seems fine. You need test this Logger stuff,.
- *
- *
- *
- *
- *
- *
- *
- *
- *
- ************************************************************************/
-
- // Logger.cpp: implementation of the Logger class.
- //
- //////////////////////////////////////////////////////////////////////
-
- #include "stdafx.h"
- #include "phone.h"
- #include "Logger.h"
- #include <afx.h>
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
-
- namespace skgLogger{
-
- // 在此处对两个 static 成员进行定义
- CRITICAL_SECTION Logger::cs_loggerClassLevel;
- std::vector<Logger*> Logger::loggerList;
- BOOL Logger::b_traceable;
-
- BOOL Logger::InitLogger()
- {
- InitializeCriticalSection(&Logger::cs_loggerClassLevel);
- Logger::b_traceable=FALSE;
- return TRUE;
- }
- void Logger::EnableTrace(BOOL traceable)
- {
- EnterCriticalSection(&cs_loggerClassLevel);
- b_traceable=traceable;
- LeaveCriticalSection(&cs_loggerClassLevel);
- }
- BOOL Logger::isTraceable()
- {
- return b_traceable;
- }
- Logger* Logger::GetInstance(const string& name)
- {
- EnterCriticalSection(&cs_loggerClassLevel);
- // if we find that we have created one instance named '&name' already. just return it.
- for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
- {
- if (!(*iter)->GetName().compare(name))
- {
- LeaveCriticalSection(&cs_loggerClassLevel);
- return (*iter);
- }
- }
-
- // else we will simply create a new instance and return it.
- Logger* instance=new Logger(name);
- loggerList.push_back(instance);
- LeaveCriticalSection(&cs_loggerClassLevel);
- return instance;
- }
- void Logger::RemoveInstance(const Logger* logger)
- {
- EnterCriticalSection(&cs_loggerClassLevel);
- for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
- {
- if ((*iter)==logger)
- {
- delete logger;
- loggerList.erase(iter);
- break;
- }
- }
- LeaveCriticalSection(&cs_loggerClassLevel);
- }
- void Logger::RemoveInstance(const string& name)
- {
- EnterCriticalSection(&cs_loggerClassLevel);
- for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
- {
- if (!(*iter)->GetName().compare(name))
- {
- delete iter;
- loggerList.erase(iter);
- break;
- }
- }
- LeaveCriticalSection(&cs_loggerClassLevel);
- }
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- Logger::Logger( const string& name )
- {
- this->name=name;
- InitializeCriticalSection(&cs_file);
- buffer=NULL;
- bufferSize=1024;// for test
- b_inited=FALSE;
- m_LogLevel=skgLogger::INFO_LOG_LEVEL;
- }
- Logger::~Logger()
- {
- EnterCriticalSection(&cs_file);
- stream_out.close();
- delete[] buffer;
- buffer=NULL;
- bufferSize=0;
- LeaveCriticalSection(&cs_file);
- TRACE("loger deleted!\n");
- }
-
- string Logger::GetName() const
- {
- return name;
- }
- void Logger::SetLogLevel( LogLevelType logLevel )
- {
- EnterCriticalSection(&cs_file);
- m_LogLevel=logLevel;
- LeaveCriticalSection(&cs_file);
- }
- LogLevelType Logger::GetLogLevel() const
- {
- return m_LogLevel;
- }
- BOOL Logger::isEnabledFor(LogLevelType logLevel)
- {
- EnterCriticalSection(&cs_file);// must need ?
- if ((m_LogLevel&logLevel)==logLevel)// m_LogLevel 包含 logLevel , 说明此级可用.
- {
- LeaveCriticalSection(&cs_file);
- return TRUE;
- }
- LeaveCriticalSection(&cs_file);
- return FALSE;
- }
-
- string Logger::GetTimeString( const char* timeFormat )
- {
- CString t=CTime::GetCurrentTime().Format(timeFormat);
- string strNowTime=(LPTSTR)(LPCTSTR)t;
- return strNowTime;
- }
-
- void Logger::PrintLog( const string& message )
- {
- // not implemented yet.
- }
-
- BOOL Logger::initLogFile( const string& basename, long maxFileSize/*=10*1024*1024*/, /* 10 MB */ BOOL immediateFlush/*=TRUE*/, LOG_OPEN_MODE_TYPE mode /*= ios::app*/ )
- {
- EnterCriticalSection(&cs_file);
- if (b_inited)
- {
- delete[] buffer;
- buffer=NULL;
- b_inited=FALSE;
- }
- this->basename=basename;//再加上日期 格式成为 (文件名+日期+序号).log
- this->maxFileSize=maxFileSize;
- this->immediateFlush=immediateFlush;
- currentFileSeq=0;
- Open(mode);
- b_inited=TRUE;
- LeaveCriticalSection(&cs_file);
- return TRUE;
- }
- static BOOL FileExist(const char* strFileName)
- {
- CFileFind fFind;
- return fFind.FindFile(strFileName);
- }
-
- // does not need to be locked since it is called by initLogFile() and ReOpen() which perform the locking
- void Logger::Open(LOG_OPEN_MODE_TYPE mode)
- {
- char strSeq[10];
- itoa(currentFileSeq,strSeq,10);
- openedFilename=basename+"_"+strSeq+".txt";
- while (FileExist(openedFilename.c_str()))
- {
- currentFileSeq++;
- itoa(currentFileSeq,strSeq,10);
- openedFilename=basename+"_"+strSeq+".txt";
- }
- stream_out.open(openedFilename.c_str(),mode);
- if (bufferSize!=0)
- {
- TRACE("set buf\n");
- this->buffer=new char[bufferSize];
- stream_out.rdbuf()->pubsetbuf(buffer,bufferSize);
- }
- }
- BOOL Logger::ReOpen()
- {
- stream_out.close();
- stream_out.clear();
- stream_out.open(openedFilename.c_str());
- if (stream_out.tellp()>maxFileSize)
- {
- Open(std::ios::app);
- }
- if (stream_out.good())
- {
- return TRUE;
- }
- return FALSE;
- }
- BOOL Logger::Rollover()
- {
- EnterCriticalSection(&cs_file);
- // just use another new file (filename).
- stream_out.close();
- stream_out.clear();
- Open(std::ios::app);
- LeaveCriticalSection(&cs_file);
- return TRUE;
- }
- static string LL2String(LogLevelType level)
- {
- string str_logLevel;
- switch(level)
- {
- case skgLogger::NONE_LOG_LEVEL:
- str_logLevel="NONE";
- break;
- case skgLogger::WARN_LOG_LEVEL:
- str_logLevel="WARNING";
- break;
- case skgLogger::ERROR_LOG_LEVEL:
- str_logLevel="ERROR";
- break;
- case skgLogger::INFO_LOG_LEVEL:
- str_logLevel="INFO/ALL";
- break;
- default:
- str_logLevel="UNKNOWN";
- }
- return str_logLevel;
- }
- void Logger::WriteLog( LogLevelType level, const string& message, const char* file/*=NULL*/,int line/*=-1*/ )
- {
- EnterCriticalSection(&cs_file);
- if (!stream_out.good())
- {
- TRACE("stream_out is not good()\n");
- if (!ReOpen())
- {
- TRACE("file is not open--ReOpen():%s\n",openedFilename.c_str());
- LeaveCriticalSection(&cs_file);
- return;
- }
- }
- // format the message, and then put it into the stream
- stream_out << GetTimeString()
- << " | "
- << LL2String(level)
- << " | "
- << message
- << " || file: " << file
- << ", line: " << line << "\n";
- if (immediateFlush)
- {
- TRACE("flush\n");
- stream_out.flush();
- }
- if (stream_out.tellp()>maxFileSize)
- {
- this->Rollover();
- }
- LeaveCriticalSection(&cs_file);
- }
-
-
- } // end namespace skgLogger
作者: smallest10 发布时间: 2010-08-31
自己搞定了,
run time library 选错了。
改成 multithreaded DLL 就好了。
run time library 选错了。
改成 multithreaded DLL 就好了。
作者: smallest10 发布时间: 2010-08-31
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28