Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/delphi/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi 我的US Ini文件是否适用于欧洲格式的浮点_Delphi_C++builder_Ini - Fatal编程技术网

Delphi 我的US Ini文件是否适用于欧洲格式的浮点

Delphi 我的US Ini文件是否适用于欧洲格式的浮点,delphi,c++builder,ini,Delphi,C++builder,Ini,我正在Windows 32位VCL平台上使用C++Builder XE4 我正在设置.INI文件,其中包括使用句点()作为小数分隔符的浮点数。在欧洲,他们使用逗号(,)作为十进制分隔符 我使用的是C++Builder内置的TIniFile类 TIniFile是否会在欧洲阅读下面的文件条目?我是否需要第二个.INI文件,以逗号作为分隔符 读取浮点值时,故障保护返回值也使用句点()。在下面的代码中 ReadFloat("Forex", "Size", 0.01 ); 0.01是故障安全返回

我正在Windows 32位VCL平台上使用C++Builder XE4

我正在设置
.INI
文件,其中包括使用句点(
)作为小数分隔符的浮点数。在欧洲,他们使用逗号(
)作为十进制分隔符

我使用的是C++Builder内置的
TIniFile

TIniFile
是否会在欧洲阅读下面的文件条目?我是否需要第二个
.INI
文件,以逗号作为分隔符

读取浮点值时,故障保护返回值也使用句点(
)。在下面的代码中

ReadFloat("Forex", "Size",  0.01   ); 
0.01是故障安全返回值

这在欧洲行得通吗

例如:

MyList.ini:

[Forex]
Size=0.0001
Value=10.5
OffSet=0.01


//Read TIniFile
MyList = new TIniFile("C:\\MyList.ini");
double r_Size = MyList->ReadFloat("Forex", "Size", 0.01);
double r_Value = MyList->ReadFloat("Forex", "Value", 10.0);
double r_OffSet = MyList->ReadFloat("Forex", "OffSet", 0.01);  
编辑如下

您在回答中指出了文件是否在正确读取的位置写入和读取。是否可以打开并重新保存我的.INI文件一次,将其转换为本地格式?然后我可以使用我的当前代码而不做任何更改。对于.INI文件中的每个浮点,我将在循环中执行以下三个步骤。这可以重新格式化.INI文件吗

我只需要调整故障保护返回值就可以使用本地分隔符

步骤1)检查分离器的本地值
步骤2)使用US格式(.)分隔符加载浮动
步骤3)使用本地分隔符重新保存

void __fastcall ConvertToLocalSeparator( ){ 

//1 Check Local Value of Seperator
TFormatSettings fmt = TFormatSettings::Create();
UnicodeString Local = fmt.DecimalSeparator;
UnicodeString Euro    = ",";

if( CompareText(Local, Euro )==0 ){ //Local DecimalSeparator is Coma(,)

//2 Load Float using US format (.) Separator
TFormatSettings USfmt = TFormatSettings::Create(); // get defaults
USfmt.DecimalSeparator = '.';
USfmt.ThousandSeparator = '\0'; //'\0' to disable

TIniFile *MyList;
MyList = new TIniFile("C:\\MyList.ini");
double r_Size = StrToFloatDef(MyList->ReadString("Forex", "Size", ""), 0.01, USfmt);
delete MyList;
MyList=NULL;

//3 Re-Save with local Separator
MyList = new TIniFile("C:\\MyList.ini");
MyList->WriteFloat("Forex", "Size",  r_Size   );
delete MyList;
MyList=NULL;
}

}

在内部,
ReadFloat()
使用
ReadString()
,然后调用
StrToFloat()
的非
t格式设置
版本,将
字符串
转换为
double
。同样,
WriteFloat()
调用
FloatToStr()
的非
t格式设置
版本,将
double
转换为
字符串
,然后调用
WriteString()

那些版本的
StrToFloat()
FloatToStr()
取决于
SysUtils
单元中的全局
DecimalSeparator
变量,该变量取决于区域设置。因此,,当在使用不同语言环境的系统上调用
ReadFloat()
而不是调用
WriteFloat()
的系统时,现有代码将无法正常工作

要解决此问题,您有两个选择:

  • 将全局
    小数分隔符
    变量的值更改为
    。不推荐,但可以这样做

  • 完全忘记
    WriteFloat()
    ReadFloat()
    。直接使用
    WriteString()
    ReadString()
    ,自己处理浮点转换,这样您就可以使用在所有系统上一致的任何固定格式

    //写入文件
    tformatsetings fmt=tformatsetings::Create();//获取默认值
    fmt.DecimalSeparator=_D('.');
    fmt.ThousandSeparator=_D(',);//或“\0”以禁用
    MyList=新文件(\u D(“C:\\MyList.ini”);
    MyList->WriteString(_D(“外汇”)、_D(“大小”)、FloatToStr(r_大小,fmt));
    MyList->WriteString(_D(“外汇”)、_D(“价值”)、FloatToStr(r_值,fmt));
    MyList->WriteString(_D(“外汇”)、_D(“对冲”)、FloatToStr(r_对冲,fmt));
    

    //读取文件
    TFormatSettings fmt=TFormatSettings::Create();
    fmt.DecimalSeparator=_D('.');
    fmt.ThousandSeparator=_D(',);//或“\0”以禁用
    MyList=新文件(\u D(“C:\\MyList.ini”);
    双r_Size=StrToFloatDef(MyList->ReadString(_D(“外汇”),_D(“大小”),_D(“”),0.01,fmt);
    双r_值=StrToFloatDef(MyList->ReadString(_D(“外汇”),_D(“值”),_D(“”),10.0,fmt);
    双r_OffSet=StrToFloatDef(MyList->ReadString(_D(“外汇”),_D(“OffSet”),_D(“”),0.01,fmt);
    

  • 更新:如果您想使用本地格式(我不推荐使用这种格式)读取并重新保存文件,您可以尝试以下方法:

    t格式设置USFmt;
    t格式设置EuroFmt;
    void uu fastcall InitFormats()
    {
    USFmt=t格式设置::Create();
    USFmt.DecimalSeparator=_D('.');
    USFmt.ThousandSeparator=_D('\0');
    EuroFmt=t格式设置::Create();
    EuroFmt.DecimalSeparator=_D(',');
    EuroFmt.000分隔符=_D('\0');
    }
    void\uu fastcall CheckLocalFormat(TCustomIniFile*Ini,字符串部分,字符串名称,双默认值)
    {
    双重价值;
    字符串s=Ini->ReadString(节,名称,_D(“”);
    如果(!TryStrToFloat(s,值))
    {
    如果(!TryStrToFloat(s,value,USFmt)和&!TryStrToFloat(s,value,EuroFmt))
    值=默认值;
    Ini->WriteFloat(节、名称、值);
    }
    }
    void\uu快速调用CheckLocalFormat()
    {
    TIniFile*MyList=新的TIniFile(_D(“C:\\MyList.ini”);
    CheckLocalFormat(MyList,_D(“外汇”),_D(“大小”),0.01);
    CheckLocalFormat(MyList,_D(“外汇”),_D(“价值”),10.0);
    CheckLocalFormat(MyList,_D(“外汇”),_D(“对冲”),0.01);
    删除MyList;
    }
    
    当然,使用
    t格式设置::Invariant
    进行书写和阅读也可以。它在任何地方都是一样的(或多或少与美国格式设置相同,AFAIK)。然后,不需要设置十进制和千位分隔符。我不确定XE4中是否已经提供了这种功能,但我想是的。我在TMemIniFile和tini文件上测试了这个解决方案,它似乎可以正确地处理这两个文件。谢谢,我的朋友,你能解释一下为什么在你的例子中使用_D吗?我在Embarcadero维基上找到了关于TStringBuilder的有限文档,但我并不真正了解它在做什么_D似乎仅与引号中的文本一起使用。“@homebase
    \u D()
    将字符串/字符文字映射到
    System::char
    System::string
    类型本机使用的数据类型(当前在Windows上为
    wchar\u t
    ,在其他平台上为
    char16\u t
    )。您的原始代码正在将Ansi文本传递给