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

时间:2017-06-06 11:34:22

标签: c++ c++builder vcl c++builder-xe

我想将整个文件读成字符串。我正在使用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

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

1 个答案:

答案 0 :(得分:0)

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

  1. <强> Memo1->Text

    Text是一个System::String(来自 VCL 的自动重新分配字符串类,其中包含备忘录的全文。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();
    

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

  2. <强> Memo1->Lines

    这是一个TStrings类,它包含String s的动态数组。在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,反之亦然,因为它们都代表相同的内容。您可以将您的备忘录隐藏(隐藏)并仍然使用它,以防您不想显示您在做什么...

  3. 您还可以使用文件访问功能将整个文件加载到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不同,它们适用于任何文件......即使持有控制代码。