【问题标题】:Borland BCB5 TInifile ignores Quotation Marks with Readstring()?Borland BCB5 TInifile 使用 Readstring() 忽略引号?
【发布时间】:2016-10-02 09:46:41
【问题描述】:

我对 Borland C++ Builder 5 不太熟悉,遇到了一个问题。

我有一个 INI 文件:

[Section1]
Ident1="myUser1"
Ident2=myPassword

我使用此代码读取了用户名和密码值:

{
auto_ptr<TIniFile> ifile(new TIniFile(myinifile));
AnsiString InternalUser= ifile->ReadString("Section1", "Ident1", "Defaultuser");
AnsiString InternalPassword= ifile->ReadString("Section1", "Ident2","Defaultpassword");
}

这是函数声明:

virtual AnsiString __fastcall ReadString(const AnsiString Section, const AnsiString Ident, const AnsiString Default);

预期输出:

Ident1="myUser1" (with ")
Ident2=myPassword

实际输出:

Ident1=myUser1 (without ")
Ident2=myPassword

在尝试调试时,我收到了很多我不知道且找不到文档的 Delphi 系统调用,例如 LStrToPCharLStrClr 等。

我期待某种Trim(),但我错了。

有人能告诉我这个问题吗?

【问题讨论】:

    标签: c++ delphi c++builder ini vcl


    【解决方案1】:

    这个类是对早已弃用的 Windows INI 文件 API 的封装。读取值的函数是GetPrivateProfileString,它的文档说:

    如果与 lpKeyName 关联的字符串包含在单引号或双引号中,则在 GetPrivateProfileString 函数检索字符串时会丢弃这些标记。

    因此你观察到的行为。

    【讨论】:

    • 如果您不喜欢这种行为,可以使用TMemIniFile 代替TIniFileTMemIniFile 不使用 Microsoft 的 PrivateProfile API,它手动解析 INI 数据,并保留引号。
    • 我完全同意我很久以前就停止使用 WinAPI ini 界面了,它太慢了。我最终编写了我自己的类(基于 AnsiString),它读取整个 ini 以部分列表的形式识别它的结构,还保留任何 rems。对于大约 10KB 的 ini 文件,它比 WinAPI(读取和写入)快 1000 倍左右,由于我的工作,我必须使用多个部分。 WinAPI 加载了几秒钟,而我的班级却在几毫秒内得到了它。
    • 已弃用,但仍由 MS 自己使用,包括 WIn10。只需注意desktop.ini 文件或谷歌ShellClassInfo
    • @JensG 你怎么知道 MS 正在为 INI 文件使用他们自己已弃用的 API。如果他们是的话,我会感到震惊。我认为他们不太可能希望受到所有兼容垫片和该 API 的性能问题的约束。很可能使用 INI 文件而不使用该 API。
    • 许多 THX 家伙!我将 DavidHeffernans 的帖子标记为接受答案。但也感谢@Remy Lebau 让我免于编写解决方法。我希望 Q 不是太笨,因为我永远不会得出这个结论。
    【解决方案2】:

    似乎不是 Borland 引起的问题,而是底层 Windows API 例程的行为。使用 MSVC 进行快速检查会得到相同的结果。

    #include "stdafx.h"
    #include <Windows.h>
    
    int _tmain(int argc, _TCHAR* argv[])
    {    
        TCHAR buf[400];
        GetPrivateProfileString( _T("Test"), _T("Test"), _T("Default"), &buf[0], 400, _T("test.ini"));
        _tprintf(_T("%s\n"),&buf);
    
        return 0;
    }
    

    INI 文件:

    [Test]
    Test="string with quotes"
    

    结果:

    string with quotes
    

    这是documented behavior

    如果与 lpKeyName 关联的字符串包含在单引号或双引号中,则在 GetPrivateProfileString 函数检索字符串时会丢弃这些标记。

    【讨论】:

    • INI 文件中以; 开头的行是注释。为什么您认为 API 允许 INI 创建者将 cmets 写入文件是一个错误?
    • @Remy:也许这个例子并不完美。如果您使用该 API,您会发现一些更“有趣”的行为。例如,尝试在节名中使用 []。这显然是无效的,但写入成功。我相信您也会为此提出一个有效的用例,是吗? :-)。无论如何,我删除了它,因为它不会为问题增加太多价值。感谢您的文档指针,顺便说一句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多