在 C++ Builder 中不使用可视化组件在内存中搜索文本

Searching Text in Memory without Visual Component in C++ Builder

我在 VCL 32 位平台上使用 C++Builder 10.3。我需要知道在内存中搜索文本文件的最佳方式。我写了下面的代码,它在 RichEdit 组件中打开一个文本文件并搜索并选择一些文本。 RichEdit 旨在用作可视化组件。 TMemoryStream 和 TStringStream 在内存中使用,但不提供 FindText、SelStart、SelLength 和 SelText 方法。你能展示如何在内存中做到这一点吗?

UnicodeString MyCrumb;
int StartPos=0, ToEnd=0, FoundAt=0, StartCrumb=0;
TSearchTypes mySearchTypes = TSearchTypes();


RichEdit1->Lines->LoadFromFile( "CrumbFile.txt" );

ToEnd = RichEdit1->Text.Length();

FoundAt  = RichEdit1->FindText(L"CrumbStore", StartPos, ToEnd, mySearchTypes);
StartPos = FoundAt+10;
FoundAt  = RichEdit1->FindText("crumb", StartPos, ToEnd, mySearchTypes);
StartPos = FoundAt+8;

StartCrumb = FoundAt+8;
FoundAt  = RichEdit1->FindText("}", StartPos, ToEnd, mySearchTypes);
EndPos = FoundAt-1;

RichEdit1->SelStart  = StartPos;
RichEdit1->SelLength = ( EndPos-StartPos );
MyCrumb = RichEdit1->SelText;

VCL方式是使用TStringListclass代替可视化组件。但是,整个文件将加载到内存中。

#include <iostream>
#include <memory>
using namespace std;
void FindTextVcl() 
{
    unique_ptr<TStringList> txt(new TStringList());
    txt->LoadFromFile(L"Example.txt"); // Use appropriate TEncoding if need
    for (int line_num = 0; line_num != txt->Count; line_num++)
    {
        int pos = txt->Strings[line_num].Pos("there");
        if (pos > 0)
        {
            cout << "Found at line " << line_num + 1 << ", position " << pos << endl;
            break;
        }
    }
}

标准库方式如下例(使用 wstringwifstream 用于 UTF-16)。 这适用于大文件,因为内存中只加载当前字符串。

#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void FindTextStd()
{
    ifstream txt("Example.txt");
    if (txt.is_open())
    {
        size_t pos = 0;
        size_t line_num = 0;
        string line;
        while (getline(txt, line))
        {
            line_num++;
            pos = line.find("there");
            if (pos != string::npos)
            {
                cout << "Found at line " << line_num << ", position " << pos + 1 << endl;
                break;
            }
        }
    }
}