C ++从大文件中解析一行

时间:2009-11-23 21:52:47

标签: c++ windows parsing

我已将整个文件读入内存映射文件Win API

中的字符串
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;      
} 

如果您喜欢,请将其投票。如果没有,让我们看看你得到了什么。

3 个答案:

答案 0 :(得分:2)

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

请参阅: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;
      }
    }
}

答案 1 :(得分:0)

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

无论如何,如果在C ++中这样做,Prev_delim_position = sIn.find(sDelim, Prev_delim_position)上的循环看起来就像是一个很好的方法。

答案 2 :(得分:-1)

system(“grep ....”);