免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4482 | 回复: 3
打印 上一主题 下一主题

使用ofstream出错,谁能帮帮我~ [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-08-31 19:34 |只看该作者 |倒序浏览
本帖最后由 smallest10 于 2010-08-31 19:37 编辑

很简单的一段代码
  1. std::ofstream outp;
  2. outp.open("omg.txt");
  3. outp<<"oh my god,what's the hell";
  4. outp.flush();
  5. outp.close();
复制代码
情况是这样的,我们之前做了一个软件,用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了,希望这个项目尽快完结。

论坛徽章:
0
2 [报告]
发表于 2010-08-31 19:35 |只看该作者
本帖最后由 smallest10 于 2010-08-31 19:37 编辑
  1. // Logger.h: interface for the Logger class.
  2. //
  3. //////////////////////////////////////////////////////////////////////

  4. #if !defined(AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_)
  5. #define AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_

  6. #if _MSC_VER > 1000
  7. #pragma once
  8. #endif // _MSC_VER > 1000

  9. #include <string>
  10. #include <fstream>
  11. #include <vector>
  12. #include <sstream>
  13. using std::string;

  14. namespace skgLogger{

  15.         typedef int LogLevelType;

  16.         const LogLevelType INFO_LOG_LEVEL        = 0x03; // 0011
  17.         const LogLevelType ERROR_LOG_LEVEL        = 0x02; // 0010
  18.         const LogLevelType WARN_LOG_LEVEL= 0x01; // 0001
  19.         const LogLevelType NONE_LOG_LEVEL        = 0x00; // 0000
  20.         //const LogLevelType LEVEL_TRACE= 0x04  // 0100  ===== another output way


  21.         typedef std::ios::openmode LOG_OPEN_MODE_TYPE;


  22. #define LOG_TRACE_MACRO_BODY(logEvent)                \
  23.         do {                                                                \
  24.                 if(Logger::isTraceable()) {    \
  25.                         std::ostringstream _out_buf;                   \
  26.                         _out_buf << logEvent << "\n";                                 \
  27.                         TRACE((_out_buf.str().append(__FILE__).append(__LINE__)).c_str());              \
  28.                 }                                                               \
  29.         } while (0)

  30. // note that the logEvent argument is string type
  31. #define LOG_TRACE_MACRO_STR_BODY(logEvent)                \
  32.         do {                                                                \
  33.                 if(Logger::isTraceable()) {    \
  34.                         TRACE((logEvent.append(__FILE__).append(__LINE__).append("\n")).c_str())             \
  35.                 }                                                               \
  36.         } while (0)

  37. #define LOG_MACRO_BODY(logger, logEvent, logLevel)                \
  38.         do {                                                                \
  39.                 if((logger)->isEnabledFor(logLevel##_LOG_LEVEL)) {    \
  40.                         std::ostringstream _out_buf;                   \
  41.                         _out_buf << logEvent;                                 \
  42.                         (logger)->WriteLog(logLevel##_LOG_LEVEL,         \
  43.                                                                 _out_buf.str(), __FILE__, __LINE__);              \
  44.                 }                                                               \
  45.         } while (0)

  46. // if logEvent is a string, then we could call this MACRO instead of LOG_MACRO_BODY()
  47. // note that the logEvent argument is string type
  48. #define LOG_MACRO_STR_BODY(logger, logEvent, logLevel)                \
  49.         do {                                                                \
  50.                 if((logger)->isEnabledFor(logLevel##_LOG_LEVEL)) {    \
  51.                         (logger)->WriteLog(logLevel##_LOG_LEVEL,         \
  52.                                                                 logEvent, __FILE__, __LINE__);              \
  53.                 }                                                               \
  54.         } while (0)

  55. // LOG_TRACE() 与 LOG_TRACE_STR() 有问题.未进行具体调试.
  56. #if !defined(LOG_DISABLE_TRACE)
  57. #define LOG_TRACE(logEvent)                               \
  58.     LOG_TRACE_MACRO_BODY (logEvent)
  59. #define LOG_TRACE_STR(logEvent)                           \
  60.     LOG_TRACE_MACRO_STR_BODY (logEvent)
  61. #else
  62. #define LOG_TRACE(logEvent) do { } while (0)
  63. #define LOG_TRACE_STR(logEvent) do { } while (0)
  64. #endif


  65. #if !defined(LOG_DISABLE_DEBUG)
  66. #define LOG_DEBUG(logger, logEvent)                               \
  67.     LOG_MACRO_BODY (logger, logEvent, DEBUG)
  68. #define LOG_DEBUG_STR(logger, logEvent)                           \
  69.     LOG_MACRO_STR_BODY (logger, logEvent, DEBUG)
  70. #else
  71. #define LOG_DEBUG(logger, logEvent) do { } while (0)
  72. #define LOG_DEBUG_STR(logger, logEvent) do { } while (0)
  73. #endif


  74. #if !defined(LOG_DISABLE_INFO)
  75. #define LOG_INFO(logger, logEvent)                                \
  76.     LOG_MACRO_BODY (logger, logEvent, INFO)
  77. #define LOG_INFO_STR(logger, logEvent)                            \
  78.     LOG_MACRO_STR_BODY (logger, logEvent, INFO)
  79. #else
  80. #define LOG_INFO(logger, logEvent) do { } while (0)
  81. #define LOG_INFO_STR(logger, logEvent) do { } while (0)
  82. #endif


  83. #if !defined(LOG_DISABLE_WARN)
  84. #define LOG_WARN(logger, logEvent)                                \
  85.     LOG_MACRO_BODY (logger, logEvent, WARN)
  86. #define LOG_WARN_STR(logger, logEvent)                            \
  87.     LOG_MACRO_STR_BODY (logger, logEvent, WARN)
  88. #else
  89. #define LOG_WARN(logger, logEvent) do { } while (0)
  90. #define LOG_WARN_STR(logger, logEvent) do { } while (0)
  91. #endif


  92. #if !defined(LOG_DISABLE_ERROR)
  93. #define LOG_ERROR(logger, logEvent)                               \
  94.     LOG_MACRO_BODY (logger, logEvent, ERROR)
  95. #define LOG_ERROR_STR(logger, logEvent)                           \
  96.     LOG_MACRO_STR_BODY (logger, logEvent, ERROR)
  97. #else
  98. #define LOG_ERROR(logger, logEvent) do { } while (0)
  99. #define LOG_ERROR_STR(logger, logEvent) do { } while (0)
  100. #endif


  101. #if !defined(LOG_DISABLE_FATAL)
  102. #define LOG_FATAL(logger, logEvent)                               \
  103.     LOG_MACRO_BODY (logger, logEvent, FATAL)
  104. #define LOG_FATAL_STR(logger, logEvent)                           \
  105.     LOG_MACRO_STR_BODY (logger, logEvent, FATAL)
  106. #else
  107. #define LOG_FATAL(logger, logEvent) do { } while (0)
  108. #define LOG_FATAL_STR(logger, logEvent) do { } while (0)
  109. #endif

  110. /************************************************************************/
  111. /* define class Logger                                                  */
  112. /************************************************************************/
  113.         class Logger  
  114.         {
  115.         public:
  116.                 static BOOL InitLogger();
  117.         static Logger* GetInstance(const string& name); // 获得日志类的实例
  118.                 static void RemoveInstance(const string& name);
  119.                 static void RemoveInstance(const Logger* logger);
  120.                 static BOOL isTraceable();
  121.                 static void EnableTrace(BOOL traceable);
  122.                
  123.                 // LOG_WANR 等宏会调用此函数
  124.         void WriteLog(LogLevelType level, const string& message, const char* file="unkonw",int line=-1); // 日志打印接口
  125.                 virtual void PrintLog(const string& message); // 打印输出信息 --- not implemented yet.

  126.                 // LOG_WANR 等宏会调用此函数
  127.                 BOOL isEnabledFor(LogLevelType logLevel);

  128.                 inline string GetName() const;// the class member 'name' can only be assigned via GetInstance()
  129.                 inline LogLevelType GetLogLevel() const;
  130.                 inline void SetLogLevel(LogLevelType logLevel);
  131.                 BOOL initLogFile(const string& basename,
  132.                                                         long maxFileSize=10*1024*1024, // 10 MB
  133.                                                         BOOL immediateFlush=TRUE,
  134.                                                         LOG_OPEN_MODE_TYPE mode = std::ios::app);// call Open()

  135.         // Logger 级别成员
  136.         private:
  137.                 BOOL b_inited;//记录是否已经调用过 initLogFile() 方法
  138.                 string name;//name of this logger. 若想控制每个文件只对应一个Logger对象,将此变量的值改为basename的值即可.
  139.                 LogLevelType m_LogLevel; //日志输出等级, 默认为 LEVEL_INFO
  140.                 CRITICAL_SECTION cs_file; // 对象级别的临界区变量
  141.                 static CRITICAL_SECTION cs_loggerClassLevel;// 类级别的临界区变量
  142.                 static std::vector<Logger*> loggerList;
  143.                 static BOOL b_traceable;

  144.                 // 默认按 %y-%m-%d  %H:%M:%S 格式来取得时间
  145.                 string GetTimeString(const char* timeFormat="%Y-%m-%d  %H:%M:%S"); // 按格式获得日期

  146.         // 文件级别成员
  147.         private:
  148.                 string openedFilename;// 输出日志文件名 , 文件名格式如 basename_date_seq.log
  149.                 string basename;// 用于日志文件更换时,作为基文件名存在. 文件名格式如 basename_date_seq.log .如 srbw_20100901_1.log
  150.                 BOOL immediateFlush;
  151.                 std::ofstream stream_out;
  152.                 char* buffer;
  153.                 unsigned long bufferSize;
  154.                 long currentFileSize;
  155.                 long maxFileSize;
  156.                 int currentFileSeq;
  157.                 void Open(LOG_OPEN_MODE_TYPE mode);
  158.                 BOOL ReOpen();
  159.                 BOOL Rollover();// 当前日志文件已记录满,更换日志文件进行存储.

  160.         private:
  161.                 // Disallow copying of instances of this class
  162.                 Logger(const string& name);
  163.                 Logger(const Logger&){}                          ////////////// need code, to prevent someone call this func in this class
  164.                 Logger(Logger*){}                                  ////////////// need code, to prevent someone call this func in this class
  165.                 Logger& operator=(const Logger&){}////////////// need code, to prevent someone call this func in this class
  166.                 // Disallow deleting of instances of this class
  167.                 virtual ~Logger();
  168.         };// end class Logger


  169. } // end namespace skgLogger

  170. #endif // !defined(AFX_LOGGER_H__5C97FAE9_F998_42F3_B797_ADC910889447__INCLUDED_)
复制代码

论坛徽章:
0
3 [报告]
发表于 2010-08-31 19:36 |只看该作者
  1. /************************************************************************
  2. *   
  3. *   Logger.cpp / Logger.h  定义了日志类与其他一些辅助函数. 用于日志记录.
  4. *   
  5. * how to use this class:
  6. *   1.  init Logger class
  7. *                        Logger::InitLogger();
  8. *   2.  get an instance of Logger class
  9. *                        Logger* testLog=Logger::GetInstance("testLogName");
  10. *   3.  init the instance ( here we determine the log filename, max file size,
  11. *                                                                flush mode { immediate flush or not },
  12. *                                                                file open mode { append, trunc, etc. } )
  13. *                        testLog->initLogFile("testLogFile",10*1024*1024,TRUE,std::ios::app);
  14. *   4.  set log level
  15. *                        testLog->SetLogLevel(skgLogger::LogLevelType::LEVEL_ERROR);
  16. *   5.  now we can log events. do it! ( use LOG_INFO(), LOG_WARN() or LOG_ERROR() )
  17. *                        LOG_WARN(testLog,"this is a new log record.")
  18. *   6.  after all thing done,you should delete this instance.  use RemoveInstance().
  19. *                        RemoveInstance(testLog);
  20. *   
  21. *   Here, everything seems fine. You need test this Logger stuff,.
  22. *   
  23. *   
  24. *   
  25. *   
  26. *   
  27. *   
  28. *   
  29. *   
  30. *   
  31. ************************************************************************/

  32. // Logger.cpp: implementation of the Logger class.
  33. //
  34. //////////////////////////////////////////////////////////////////////

  35. #include "stdafx.h"
  36. #include "phone.h"
  37. #include "Logger.h"
  38. #include <afx.h>

  39. #ifdef _DEBUG
  40. #undef THIS_FILE
  41. static char THIS_FILE[]=__FILE__;
  42. #define new DEBUG_NEW
  43. #endif

  44. namespace skgLogger{

  45.         // 在此处对两个 static 成员进行定义
  46.         CRITICAL_SECTION Logger::cs_loggerClassLevel;
  47.         std::vector<Logger*> Logger::loggerList;
  48.         BOOL Logger::b_traceable;

  49. BOOL Logger::InitLogger()
  50. {
  51.         InitializeCriticalSection(&Logger::cs_loggerClassLevel);
  52.         Logger::b_traceable=FALSE;
  53.         return TRUE;
  54. }
  55. void Logger::EnableTrace(BOOL traceable)
  56. {
  57.         EnterCriticalSection(&cs_loggerClassLevel);
  58.         b_traceable=traceable;
  59.         LeaveCriticalSection(&cs_loggerClassLevel);
  60. }
  61. BOOL Logger::isTraceable()
  62. {
  63.         return b_traceable;
  64. }
  65. Logger* Logger::GetInstance(const string& name)
  66. {
  67.         EnterCriticalSection(&cs_loggerClassLevel);
  68.         // if we find that we have created one instance named '&name' already. just return it.
  69.         for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
  70.         {
  71.                 if (!(*iter)->GetName().compare(name))
  72.                 {
  73.                         LeaveCriticalSection(&cs_loggerClassLevel);
  74.                         return (*iter);
  75.                 }
  76.         }

  77.         // else we will simply create a new instance and return it.
  78.         Logger* instance=new Logger(name);
  79.         loggerList.push_back(instance);
  80.         LeaveCriticalSection(&cs_loggerClassLevel);
  81.         return instance;
  82. }
  83. void Logger::RemoveInstance(const Logger* logger)
  84. {
  85.         EnterCriticalSection(&cs_loggerClassLevel);
  86.         for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
  87.         {
  88.                 if ((*iter)==logger)
  89.                 {
  90.                         delete logger;
  91.                         loggerList.erase(iter);
  92.                         break;
  93.                 }
  94.         }
  95.         LeaveCriticalSection(&cs_loggerClassLevel);
  96. }
  97. void Logger::RemoveInstance(const string& name)
  98. {
  99.         EnterCriticalSection(&cs_loggerClassLevel);
  100.         for (std::vector<Logger*>::iterator iter=loggerList.begin();iter!=loggerList.end();iter++)
  101.         {
  102.                 if (!(*iter)->GetName().compare(name))
  103.                 {
  104.                         delete iter;
  105.                         loggerList.erase(iter);
  106.                         break;
  107.                 }
  108.         }
  109.         LeaveCriticalSection(&cs_loggerClassLevel);
  110. }
  111. //////////////////////////////////////////////////////////////////////
  112. // Construction/Destruction
  113. //////////////////////////////////////////////////////////////////////
  114. Logger::Logger( const string& name )
  115. {
  116.         this->name=name;
  117.         InitializeCriticalSection(&cs_file);
  118.         buffer=NULL;
  119.         bufferSize=1024;// for test
  120.         b_inited=FALSE;
  121.         m_LogLevel=skgLogger::INFO_LOG_LEVEL;
  122. }
  123. Logger::~Logger()
  124. {
  125.         EnterCriticalSection(&cs_file);
  126.         stream_out.close();
  127.         delete[] buffer;
  128.         buffer=NULL;
  129.         bufferSize=0;
  130.         LeaveCriticalSection(&cs_file);
  131.         TRACE("loger deleted!\n");
  132. }

  133. string Logger::GetName() const
  134. {
  135.         return name;
  136. }
  137. void Logger::SetLogLevel( LogLevelType logLevel )
  138. {
  139.         EnterCriticalSection(&cs_file);
  140.         m_LogLevel=logLevel;
  141.         LeaveCriticalSection(&cs_file);
  142. }
  143. LogLevelType Logger::GetLogLevel() const
  144. {
  145.         return m_LogLevel;
  146. }
  147. BOOL Logger::isEnabledFor(LogLevelType logLevel)
  148. {
  149.         EnterCriticalSection(&cs_file);// must need ?
  150.         if ((m_LogLevel&logLevel)==logLevel)// m_LogLevel 包含 logLevel , 说明此级可用.
  151.         {
  152.                 LeaveCriticalSection(&cs_file);
  153.                 return TRUE;
  154.         }
  155.         LeaveCriticalSection(&cs_file);
  156.         return FALSE;
  157. }

  158. string Logger::GetTimeString( const char* timeFormat )
  159. {
  160.         CString t=CTime::GetCurrentTime().Format(timeFormat);
  161.         string strNowTime=(LPTSTR)(LPCTSTR)t;
  162.         return strNowTime;
  163. }

  164. void Logger::PrintLog( const string& message )
  165. {
  166.         // not implemented yet.
  167. }

  168. BOOL Logger::initLogFile( const string& basename, long maxFileSize/*=10*1024*1024*/, /* 10 MB */ BOOL immediateFlush/*=TRUE*/, LOG_OPEN_MODE_TYPE mode /*= ios::app*/ )
  169. {
  170.         EnterCriticalSection(&cs_file);
  171.         if (b_inited)
  172.         {
  173.                 delete[] buffer;
  174.                 buffer=NULL;
  175.                 b_inited=FALSE;
  176.         }
  177.         this->basename=basename;//再加上日期 格式成为 (文件名+日期+序号).log
  178.         this->maxFileSize=maxFileSize;
  179.         this->immediateFlush=immediateFlush;
  180.         currentFileSeq=0;
  181.         Open(mode);
  182.         b_inited=TRUE;
  183.         LeaveCriticalSection(&cs_file);
  184.         return TRUE;
  185. }
  186. static BOOL FileExist(const char* strFileName)
  187. {
  188.         CFileFind fFind;
  189.         return fFind.FindFile(strFileName);
  190. }

  191. // does not need to be locked since it is called by initLogFile() and ReOpen() which perform the locking
  192. void Logger::Open(LOG_OPEN_MODE_TYPE mode)
  193. {
  194.         char strSeq[10];
  195.         itoa(currentFileSeq,strSeq,10);
  196.         openedFilename=basename+"_"+strSeq+".txt";
  197.         while (FileExist(openedFilename.c_str()))
  198.         {
  199.                 currentFileSeq++;
  200.                 itoa(currentFileSeq,strSeq,10);
  201.                 openedFilename=basename+"_"+strSeq+".txt";
  202.         }
  203.         stream_out.open(openedFilename.c_str(),mode);
  204.         if (bufferSize!=0)
  205.         {
  206.                 TRACE("set buf\n");
  207.                 this->buffer=new char[bufferSize];
  208.                 stream_out.rdbuf()->pubsetbuf(buffer,bufferSize);
  209.         }
  210. }
  211. BOOL Logger::ReOpen()
  212. {
  213.         stream_out.close();
  214.         stream_out.clear();
  215.         stream_out.open(openedFilename.c_str());
  216.         if (stream_out.tellp()>maxFileSize)
  217.         {
  218.                 Open(std::ios::app);
  219.         }
  220.         if (stream_out.good())
  221.         {
  222.                 return TRUE;
  223.         }
  224.         return FALSE;
  225. }
  226. BOOL Logger::Rollover()
  227. {
  228.         EnterCriticalSection(&cs_file);
  229.         // just use another new file (filename).
  230.         stream_out.close();
  231.         stream_out.clear();
  232.         Open(std::ios::app);
  233.         LeaveCriticalSection(&cs_file);
  234.         return TRUE;
  235. }
  236. static string LL2String(LogLevelType level)
  237. {
  238.         string str_logLevel;
  239.         switch(level)
  240.         {
  241.         case skgLogger::NONE_LOG_LEVEL:
  242.                 str_logLevel="NONE";
  243.                 break;
  244.         case skgLogger::WARN_LOG_LEVEL:
  245.                 str_logLevel="WARNING";
  246.                 break;
  247.         case skgLogger::ERROR_LOG_LEVEL:
  248.                 str_logLevel="ERROR";
  249.                 break;
  250.         case skgLogger::INFO_LOG_LEVEL:
  251.                 str_logLevel="INFO/ALL";
  252.                 break;
  253.         default:
  254.                 str_logLevel="UNKNOWN";
  255.         }
  256.         return str_logLevel;
  257. }
  258. void Logger::WriteLog( LogLevelType level, const string& message, const char* file/*=NULL*/,int line/*=-1*/ )
  259. {
  260.         EnterCriticalSection(&cs_file);
  261.         if (!stream_out.good())
  262.         {
  263.                 TRACE("stream_out is not good()\n");
  264.                 if (!ReOpen())
  265.                 {
  266.                         TRACE("file is not open--ReOpen():%s\n",openedFilename.c_str());
  267.                         LeaveCriticalSection(&cs_file);
  268.                         return;
  269.                 }
  270.         }
  271.         // format the message, and then put it into the stream
  272.         stream_out << GetTimeString()
  273.                                 << "  |  "
  274.                                 << LL2String(level)
  275.                                 << "  |  "
  276.                                 << message
  277.                                 << "     ||  file: " << file
  278.                                 << ",    line: " << line << "\n";
  279.         if (immediateFlush)
  280.         {
  281.                 TRACE("flush\n");
  282.                 stream_out.flush();
  283.         }
  284.         if (stream_out.tellp()>maxFileSize)
  285.         {
  286.                 this->Rollover();
  287.         }
  288.         LeaveCriticalSection(&cs_file);
  289. }


  290. } // end namespace skgLogger
复制代码

论坛徽章:
0
4 [报告]
发表于 2010-08-31 19:49 |只看该作者
自己搞定了,
run time library 选错了。
改成 multithreaded DLL 就好了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP