2009-11-23 48 views
0

我已阅读整个文件到从存储器映射文件赢APIC++解析一个线路输出一个大文件的

CreateFile("WarandPeace.txt", GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0) 

等字符串...

每一行端接一个CRLF 。我需要在“我喜欢垃圾邮件和鸡蛋”一行中找到类似于“垃圾邮件”的行(并将整行(不含CRLF))返回到字符串中(或指向字符串中的位置的指针)。原始字符串不能改变

编辑:。

事情是这样的:

string ParseStr(string sIn, string sDelim, int nField) 
{ 
    int match, LenStr, LenDelim, ePos, sPos(0), count(0); 
    string sRet; 

     LenDelim = sDelim.length(); 
     LenStr = sIn.length(); 
     if(LenStr < 1 || LenDelim < 1) return ""; // Empty String 
     if(nField < 1) return ""; 
     //=========== cout << "LenDelim=" << LenDelim << ", sIn.length=" << sIn.length() << endl; 


     for(ePos=0; ePos < LenStr; ePos++) // iterate through the string 
     { // cout << "sPos=" << sPos << ", LenStr=" << LenStr << ", ePos=" << ePos << ", sIn[ePos]=" << sIn[ePos] << endl; 
      match = 1; // default = match found 
      for(int k=0; k < LenDelim; k++) // Byte value 
      { 
       if(ePos+k > LenStr) // end of the string 
        break; 
       else if(sIn[ePos+k] != sDelim[k]){ // match failed 
        match = 0; break; } 
      } 
      //=========== 

      if(match || (ePos == LenStr-1)) // process line 
      { 
       if(!match) ePos = LenStr + LenDelim; // (ePos == LenStr-1) 
       count++; // cout << "sPos=" << sPos << ", ePos=" << ePos << " >" << sIn.substr(sPos, ePos-sPos) << endl; 
       if(count == nField){ sRet = sIn.substr(sPos, ePos-sPos); break; } 
       ePos = ePos+LenDelim-1; // jump over Delim 
       sPos = ePos+1; // Begin after Delim 
      } // cout << "Final ePos=" << ePos << ", count=" << count << ", LenStr=" << LenStr << endl; 
     }// next 

    return sRet;  
} 

如果你喜欢它,投上一票。如果没有,那么让我们来看看你得到了什么

+1

CreateFile()没有内存映射文件。它只会打开它。之后你真的调用CreateFileMapping()和MapViewOfFile()吗? – 2009-11-24 14:38:31

+1

另一个令人困惑的方面:如果你真的存储映射文件,为什么将它复制到一个字符串呢? – 2009-11-24 14:40:03

+0

这是一个解析练习。但有些时候,你需要从内存映射文件中解析出线路,甚至是从HTTP请求中解析响应等。 – 2009-11-25 10:06:30

回答

2

如果。你正试图匹配更复杂的模式那么你总是可以回退到boost的正则表达式库。

参见:http://www.boost.org/doc/libs/1_41_0/libs/regex/doc/html/index.html

#include <iostream> 
#include <string> 
#include <boost/regex.hpp> 

using namespace std; 

int main() 
{ 
    std::string s; 
    std::string sre("Spam"); 
    boost::regex re; 

    ifstream in("main.cpp"); 
    if (!in.is_open()) return 1; 

    string line; 
    while (getline(in,line)) 
    { 
     try 
     { 
     // Set up the regular expression for case-insensitivity 
     re.assign(sre, boost::regex_constants::icase); 
     } 
     catch (boost::regex_error& e) 
     { 
     cout << sre << " is not a valid regular expression: \"" 
      << e.what() << "\"" << endl; 
     continue; 
     } 
     if (boost::regex_match(line, re)) 
     { 
     cout << re << " matches " << line << endl; 
     } 
    } 
} 
+0

该库的效率如何? – 2009-11-24 01:22:01

+0

sre从未初始化;并且模式从不使用。 – ScottJ 2009-11-24 01:29:13

+0

@ScottJ,感谢它是伪代码,我已经更新它。 – chollida 2009-11-24 15:57:27

-1

系统( “grep的......”);

+0

不只是返回一个计数?也许你可以扩展... – 2009-11-24 01:44:26

+0

它在Windows(Win API)中。肯定没有“grep”... – billyswong 2009-11-24 01:45:55

0

你真的必须用C++来做吗?也许你可以使用更适合文本处理的语言,比如Perl,并应用一个正则表达式。

无论如何,如果在C++中执行此操作,通过Prev_delim_position = sIn.find(sDelim, Prev_delim_position)循环看起来是一个很好的方法。

+0

是C++是我必须使用的语言。你的方法的这个概念是我想到的,但使用指针而不是.find() – 2009-11-24 23:16:06