使用 C++Builder 项目读取字符串中的文件时出错

Getting Error when reading file in string using C++Builder Project

我想将整个文件读入一个字符串。我正在使用 Embarcadero C++Builder XE。

当我在我的项目中使用以下代码时,出现错误:

#include <iostream>
#include <iomanip>
#include <iterator>
#include <fstream>

std::ifstream in(Path);
std::string s((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
[ILINK32 Error] Error: Unresolved external 'std::_Mutex::_Lock()' 
[ILINK32 Error] Error: Unresolved external 'std::_Mutex::_Unlock()' 
[ILINK32 Error] Error: Unresolved external 'std::char_traits::eq_int_type(const int&, const int&)' 
[ILINK32 Error] Error: Unresolved external 'std::char_traits::not_eof(const int&)' 
[ILINK32 Error] Error: Unresolved external 'std::char_traits::to_char_type(const int&)'
[ILINK32 Error] Error: Unresolved external 'std::char_traits::eof()' 
[ILINK32 Error] Error: Unresolved external 'std::char_traits::to_int_type(const char&)' 
[ILINK32 Error] Error: Unresolved external 'std::locale::id::operator unsigned int()' 
[ILINK32 Error] Error: Unresolved external 'std::locale::name() const' 
[ILINK32 Error] Error: Unresolved external 'std::codecvt_base::codecvt_base(unsigned int)' 
[ILINK32 Error] Error: Unresolved external 'std::locale::facet::_Incref()' 
[ILINK32 Error] Error: Unresolved external 'std::ios_base::ios_base()' 
[ILINK32 Error] Error: Unresolved external 'std::ios_base::getloc() const' 
[ILINK32 Error] Error: Unresolved external 'std::ctype::_Getcat(std::locale::facet * *, std::locale *)' 
[ILINK32 Error] Error: Unresolved external 'std::ctype::widen(char) const' 
[ILINK32 Error] Error: Unresolved external 'std::ios_base::rdstate() const' 
[ILINK32 Error] Error: Unable to perform link

还有其他将文件读入字符串的解决方案吗?

让我们创建一个空的 VCL 表单应用程序并在其上添加一个 TMemo 控件。 IDE 会自动将其命名为 Memo1 。 Memo 对象是具有 2 个重要属性的文本编辑器:

  1. Memo1->Text

    TextSystem::String(来自 VCL 的可自动重新分配的字符串 class,包含备忘录的整个文本。String 有一个 Length() 函数返回存在的字符数,并且使用 [] 运算符访问每个字符,如下所示(从 1 开始索引!!!):

    String s = _D("123456"); // set some string to s
    int l = s.Length(); // get its length
    for (int i = 1; i <= l; i++) s[i] = '0'; // change all the chars to zeros
    Memo1->Text = s; // feed it to Memo
    

    里面有很多支持函数String,对你来说最重要的是格式化输出:

    Memo1->Text = String().sprintf(_D("float number: %7.3f"), float(123.456));
    

    您也可以使用 String 作为局部变量:

    String s = _D("some text");
    Memo1->Text = s;
    

    同样为了向后兼容,如果你需要一个 char* 用于某些功能,那么只需将 String 分配给一个 AnsiString 并调用它的 c_str() 方法:

    String s = _D("some text");
    AnsiString as = s;
    char *txt = as.c_str();
    

    但注意不要覆盖未分配的 space,或在 as 内的任何重新分配后或 as 超出范围后使用该指针。这主要用作 Win32 API 函数、C 函数、非 VCL LIBs/DLLs 等的输入参数

  2. Memo1->Lines

    这是一个 TStrings class,它包含一个 String 的动态数组。在 TMemo 中,每个元素代表 Text 中的一行。您可以像这样动态地向 Memo1 添加行:

    Memo1->Lines->Add(_D("text 1"));
    Memo1->Lines->Add(_D("text 2"));
    Memo1->Lines->Add(_D("text 3"));
    

    您可以 load/save 整个备忘录内容如下:

    Memo1->Lines->LoadFromFile("file1.txt");
    Memo1->Lines->SaveToFile("file1.txt");
    

    Memo1->Lines 中的任何更改也会更改 Memo1->Text,反之亦然,因为它们都代表同一事物。您可以隐藏您的备忘录(不可见)并在您不想显示您在做什么的情况下仍然使用它...

您还可以使用不带任何 VCL 组件的文件访问函数将整个文件加载到 char[] 缓冲区中,如下所示:

int hnd = FileOpen("file1.txt", fmOpenRead); // open file hnd>=0 if all OK
int siz = FileSeek(hnd, 2, 0); // point to end of file and return position = file size
FileSeek(hnd, 0, 0); // point back to start of file
char *txt = new char[siz+1] // allocate space for text and null terminator
FileRead(hnd, txt, siz); // load the file into memory at once
FileClose(hnd); // close file as we do not need it anymore

txt[siz] = 0; // add null termination just to be safe (text files do not contains zeros usually)
// do your thing with txt[siz]

delete[] txt;

或:

TFileStream *strm = new TFileStream("file1.txt", fmOpenRead); // open file
int siz = strm->Size; // file size
char *txt = new char[siz+1] // allocate space for text and null terminator
strm->ReadBuffer(txt, siz); // load the file into memory at once
delete strm; // close file as we do not need it anymore

// do your thing with txt[siz]

delete[] txt;

或:

TMemoryStream *strm = new TMemoryStream;
strm->LoadFromFile("file1.txt"); // open file

// do your thing with strm->Memory up to strm->Size bytes...

delete strm;

std::fstream 不同,这些适用于任何文件......即使持有控制代码。