0

我想将整个文件读入一个字符串。我正在使用 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 错误] 错误:未解析的外部 'std::_Mutex::_Lock()'
[ILINK32 错误] 错误:未解析的外部 'std::_Mutex::_Unlock()'
[ILINK32 错误] 错误:未解析的外部 'std::char_traits::eq_int_type(const int&, const int&)'
[ILINK32 错误] 错误:未解析的外部 'std::char_traits::not_eof(const int&)'
[ILINK32 错误] 错误:未解析的外部 'std::char_traits::to_char_type(const int&)'
[ILINK32 错误] 错误:未解析的外部 'std::char_traits::eof()'
[ILINK32 错误] 错误:未解析的外部 'std::char_traits::to_int_type(const char&)'
[ILINK32 错误] 错误:未解析的外部 'std::locale::id::operator unsigned int()'
[ILINK32 错误] 错误:未解析的外部 'std::locale::name() const'
[ILINK32 错误] 错误:未解析的外部 'std::codecvt_base::codecvt_base(unsigned int)'
[ILINK32 错误] 错误:未解析的外部 'std::locale::facet::_Incref()'
[ILINK32 错误] 错误:未解析的外部 'std::ios_base::ios_base()'
[ILINK32 错误] 错误:未解析的外部 'std::ios_base::getloc() const'
[ILINK32 错误] 错误:未解析的外部 'std::ctype::_Getcat(std::locale::facet * *, std::locale *)'
[ILINK32 错误] 错误:未解析的外部 'std::ctype::widen(char) const'
[ILINK32 错误] 错误:未解析的外部 'std::ios_base::rdstate() const'
[ILINK32 错误] 错误:无法执行链接

将文件读入字符串的任何其他解决方案?

4

1 回答 1

0

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

  1. Memo1->Text

    Text是一个(来自VCLSystem::String的自动重新分配字符串类,包含备忘录的整个文本。具有返回存在字符数的函数,并且每个字符都可以使用这样的运算符访问(从 1 开始!!!):StringLength()[]

    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;
    

    同样为了向后兼容,如果您需要 achar*用于某些功能,则只需将 a 分配String给 anAnsiString并调用其c_str()方法:

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

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

  2. Memo1->Lines

    这是一个TStrings类,其中包含Strings 的动态数组。在 TMemo 中,每个元素代表Text. 您可以Memo1像这样动态添加行:

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

    您可以像这样加载/保存整个备忘录内容:

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

    任何变化Memo1->Lines也会改变Memo1->Text,反之亦然,因为它们都代表相同的东西。你可以隐藏你的备忘录(不可见)并且仍然使用它,以防你不想显示你在做什么......

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

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的是,它们适用于任何文件……即使持有控制代码。

于 2017-06-07T11:21:02.317 回答