Khan's Notebook GCC/GNU/Linux Delphi/Window Java/Anywhere

路漫漫,长修远,我们不能没有钱
随笔 - 172, 文章 - 0, 评论 - 257, 引用 - 0
数据加载中……

[C++] 使用ifstream.seekg犯的错误

使用ifstream的时候,可以用seekg进行重定位,但有一个需要注意的地方。
如果想重定位到文件头,应该用:
mFile.seekg(0, ios_base::beg);
而不是
mFile.seekg(ios_base::beg);
我实验的结果是,后者会定位到文件头后面一个字符,也就是说,第一个字符被吃掉了。

我要记得,每一个指针在申明d时候就必须要初始化啊初始化,调试了1个工作日.

读日志文件的一个类

//pchar.hpp
 1 #include <string.h>
 2 
 3 void trimLeft(char * p_char){
 4   char szBuff[1024];
 5   memset(szBuff, 0sizeof(szBuff));
 6   char *pBuff = p_char;
 7   while*pBuff == ' '){
 8     ++ pBuff;
 9   }
10 
11   strncpy(szBuff, pBuff, sizeof(szBuff) -1);
12   strncpy(p_char, szBuff, strlen(szBuff));
13   p_char[strlen(szBuff)] = 0x0;
14 }
15 
16 
17 void trimRight(char * p_char){
18   for(int i = strlen(p_char) - 1; i >= 0; i-- ){
19     if*(p_char + i) == ' ') {
20       *(p_char + i ) = '\0';
21     }else break;
22   }
23 }
24 
25 void trim(char * p_char){
26   trimLeft(p_char);
27   trimRight(p_char);
28 }
29 
30 



 1 //IniFile.hpp
 2 
 3 #include <unistd.h>
 4 #include <stdio.h>
 5 #include <stdlib.h>
 6 #include <string>
 7 #include <fstream>
 8 
 9 using namespace std;
10 
11 #ifndef INIFILE_HPP_
12 #define INIFILE_HPP_
13 
14 
15 class IniFile {
16 
17   public:
18     IniFile(){ m_bOpened= false;}
19 
20     IniFile(const char * p_szFileName);
21     ~IniFile();
22 
23   public:
24     void setFileName(const char * p_szFileName);
25     int openIni();
26     int getPchar (const char *p_szSection, const char *p_szKey, char *p_szDefaultValue);
27     int getInt   (const char *p_szSection, const char *p_szKey, int& p_iDefaultValue);
28     int getBool  (const char *p_szSection, const char *p_szKey, int& p_iDefaultValue);
29     int getString(string p_strSection, string p_strKey, string& p_strDefaultValue);
30 
31   protected:
32 
33 
34   private:
35     ifstream inFile;
36     char m_szFileName[256];
37     char m_szSection[32];
38     bool m_bOpened;
39 };
40 
41 #endif //INIFILE_HPP_
42 
43 


  1 //IniFile.cpp
  2 
  3 #include "../include/IniFile.hpp"
  4 #include "../include/pchar.hpp"
  5 
  6 
  7 IniFile::IniFile(const char * p_szFileName){
  8   m_bOpened = false;
  9   setFileName(p_szFileName);
 10 }
 11 
 12 IniFile::~IniFile(){
 13   inFile.close();
 14   printf("ini文件句柄释放!\n");
 15 }
 16                          
 17 void IniFile::setFileName(const char * p_szFileName){
 18   memset( m_szFileName, 0sizeof(m_szFileName) );
 19   strncpy( m_szFileName, p_szFileName, sizeof(m_szFileName)-1 );
 20 }
 21 
 22 
 23 
 24 
 25 int IniFile::openIni(){
 26   inFile.open(m_szFileName, ios::in);
 27   if (! inFile.good()){
 28     return -1;
 29     m_bOpened= false;
 30   }
 31 
 32   m_bOpened= true;
 33   return 0;
 34 }
 35 
 36 
 37 int IniFile::getPchar(const char *p_szSection, const char *p_szKey, char *p_szDefaultValue){
 38   char szBuff[1024];
 39   char szKey[32] ;
 40   char szDefaultValue[64] ;
 41   char szCurrentSection[32];
 42   string strLine;
 43   int iLen = 0, bInSelfSection = 0 ;
 44   char * pStrValue = NULL ;
 45                                        
 46   memset(m_szSection, 0sizeof(m_szSection) ) ;
 47   strncpy(m_szSection, p_szSection, sizeof(m_szSection)-1);
 48   
 49   memset(szKey, 0sizeof(szKey));
 50   strncpy(szKey, p_szKey, sizeof(szKey) - 1);
 51 
 52   memset(szDefaultValue, 0sizeof(szDefaultValue));
 53   strncpy(szDefaultValue, p_szDefaultValue, sizeof(szDefaultValue)-1);
 54 
 55   inFile.seekg(0, ios_base::beg); //将文件指针指向最开始d位置
 56   while(!inFile.eof()){
 57     getline(inFile, strLine);
 58 
 59     memset(szBuff, 0sizeof(szBuff));
 60     snprintf(szBuff, sizeof(szBuff)-1"%s", strLine.c_str());
 61     trim(szBuff);
 62 
 63     if ( (szBuff[0== '#'|| (strlen(szBuff) < 3) ) { //取消对注释和无用数据的解析,
 64       continue;
 65     }
 66 
 67     iLen = strlen(szBuff);
 68     if (szBuff[iLen-1== 0x0D//将每一行配置的换行符后数据去掉
 69       szBuff[iLen-1= 0x0;
 70 
 71     iLen = strlen(szBuff);
 72     if (szBuff[0== '[' && szBuff[iLen-1== ']') { //判断是否为Section  [MOSERVER]
 73       if (bInSelfSection)
 74         bInSelfSection = 0;
 75 
 76       szBuff[iLen-1= 0x0;
 77       memset(szCurrentSection, 0sizeof(szCurrentSection));
 78       strcpy(szCurrentSection, szBuff + 1); //取出section名
 79 
 80       if (strcasecmp(m_szSection, szCurrentSection) == 0) {  //如果是自己需要的section则做好标记
 81         bInSelfSection = 1;
 82         continue;
 83       }
 84     }
 85 
 86     if (!bInSelfSection)  //如果没有读到需要的section则继续找
 87       continue;
 88 
 89     if (pStrValue == NULL){
 90       pStrValue = strchr(szBuff, '=');  //查找'='的位置,没有找到则读下一条
 91     }
 92 
 93     if (pStrValue == NULL){
 94       continue;
 95     }
 96     *pStrValue = 0//将'='变为'0'来分割value和key
 97     pStrValue++;
 98     if (*pStrValue == 0){//如果没有读到value则继续读下一条
 99       continue;
100     }
101     if (bInSelfSection) {
102       if(strcasecmp(szKey,szBuff)==0){
103         strncpy(p_szDefaultValue, pStrValue, 64 - 1);
104         return 0;
105       }
106     }
107     pStrValue = NULL;
108   }
109   return -1;
110 }
111 
112 
113 int IniFile::getString(string p_strSection, string p_strKey, string& p_strDefaultValue){
114   inFile.seekg(0, ios_base::beg);
115   char szDefaultValue[64];
116   memset(szDefaultValue, 0sizeof(szDefaultValue));
117   getPchar(p_strSection.c_str(), p_strKey.c_str(), szDefaultValue);
118   getPchar("MOSERVER""TIMEOUT", szDefaultValue);
119   //printf("getchar: %s\n", szDefaultValue);//
120   p_strDefaultValue = szDefaultValue;
121   return 0;
122 
123 
124 


 1 //测试程序
 2 
 3 #include "../include/IniFile.hpp"
 4 
 5 int main(){
 6   printf("开始分析ini文件!\n");
 7   IniFile ini;
 8   char szPort[64];
 9   memset(szPort, 0sizeof(szPort));
10 
11   ini.setFileName("../config/inifile.ini");
12   ini.openIni();
13   ini.getPchar("MOSERVER""MAXCONNECTED", szPort);
14   printf("ini文件装载完成!\n");
15 
16   string timeout;
17   ini.getString("MOSERVER""TIMEOUT", timeout);
18 
19   printf("MAXCONNECTED:%s\n", szPort);
20   printf("TIMEOUT:%s\n", timeout.c_str());
21 
22   return 0;
23 }



inifile.ini文件格式

#为注释,处理时自动去掉前后空格
#######################################################################
# the configuration for MOServer
# by Khan.Lau (Lau.Khan#gmail.com)
# 2006-04-12
#######################################################################

[MOSERVER]
LISTENPORT=8097
WHITEIP=192.168.1.122;127.0.0.1;
MAXCONNECTED=50
MAXCONSINGLEIP=5
TIMEOUT=60
DBHOST=127.0.0.1
DBNAME=smstest
DBPORT=9055
DBUID=postgres
DBPWD=

posted on 2006-05-24 15:48 Khan 阅读(10270) 评论(8)  编辑 收藏 引用 所属分类: GCC/G++

评论

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

大意了大意了,缺了一个
public void closeIni(){
inFile.close();
printf("ini文件句柄释放!\n");
}
2006-05-24 15:54 | Khan's Notebook

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

少一个pchar.h
2006-05-24 19:03 | xds2000

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

已经添加了 pchar.h 主要是几个字符串处理函数
2006-05-25 12:45 | Khan's Notebook

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

lz用的是什么编译器?
seekg(ios_base::beg)
相当于
seekg(ios_base::beg, ios_base::beg)
在vc7.1跟gcc3.42里面都是移动到文件头的啊,因为在它们里面ios_base::beg的值其实是0
2006-05-29 20:24 | 3×7=51

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

我用的是gcc 3.42
2006-05-30 10:33 | Khan's Notebook

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

……我在mingw里面(使用gcc3.42)里面试怎么是移动到文件头一个字节……
2006-05-30 10:48 | 3×7=51

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

我用cygwin ,估计是rp吧......
2006-05-30 10:50 | Khan's Notebook

# re: [C++] 使用ifstream.seekg犯的错误   回复  更多评论   

mFile.seekg(ios_base::beg);
我实验的结果是,后者会定位到文件头后面一个字符,也就是说,第一个字符被吃掉了。

因为一般的ios_base::beg都是定义的0x01,然后你刚刚的写法就正好定位到第一个字节去了~不是被库吞吃了哦~
2009-11-03 13:47 | Kouga

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理