1

我的一个项目的 C++ 源代码中有一个愚蠢的错误。我在这部分做源 I/O 操作。我有一个愚蠢的错误,我打印 fscanf 读取值。在这部分的下面:首先,我没有读取好的值,当我打印一个浮点值时,我得到一个带有逗号','而不是点'的十进制值。在整数部分和浮点部分之间。

FILE* file3;
file3=fopen("test.dat","r");
float test1;
fscanf(file3," %f ",&test1);
printf("here %f\n",test1);
float test3 = 1.2345;
printf("here %f\n",test3);
fclose(file3);        

其中test.dat文件包含“1.1234”,我得到执行:

here 1,000000
here 1,234500

所以,我做了一个用 g++ 编译的简单测试 C 程序:

#include <stdio.h>
#include <stdlib.h>

int main()
{
  FILE* file3;
  float test3;
  file3=fopen("test.dat","r");
  fscanf(file3,"%f",&test3);
  printf("here %f\n",test3);
  fclose(file3);
}

它给出了:

here 1.123400

这是我第一次遇到这样的错误。任何人都可以看到有什么问题吗?

4

3 回答 3

2

您的 C++ 语言环境是否以某种方式设置为使用欧洲约定?他们使用逗号,我们使用点和点作为千位分隔符。

查看环境变量的设置

LANG LC_CTYPE LC_ALL

尝试设置 en_GB 或 en_US。确定这是一个语言环境问题后,接下来决定什么行为是有意义的。显示 1224,45 是一个错误吗?用户设置了区域设置是有原因的。

于 2012-11-21T09:26:03.843 回答
1

您正在使用为程序环境设置区域设置的代码。在某些语言环境中,例如在法语语言环境中,逗号是小数点分隔符。所以这段代码正在做它的语言环境可能告诉它的事情。

在您的简单代码中,您尚未初始化语言环境支持,因此不会发生这种情况。

假设一个类 Unix 环境,环境变量 LANG 的值是多少,以及各种 LC_* 环境变量?

环境 | grep -e ^LANG -e ^LC_

对于一些背景阅读,尝试一些 GNU Libc 手册(语言环境和国际化)

http://www.gnu.org/software/libc/manual/html_node/Locales.html#Locales

于 2012-11-21T09:41:37.243 回答
0

我的猜测是应用程序正在根据用户偏好设置区域设置,使用std::locale::global( std::locale( "" ) ). 这是控制台应用程序应该 做的,永远;他们也应该灌输std::cin,std::coutstd::cerr使用这个语言环境。大多数语言社区使用逗号代替小数点,而不是小数点。(对于恶魔进程,通常更适合使用"C"语言环境,或者"Posix"Unix 下的语言环境,而不管服务器实际运行在哪里。由于"C"语言环境是默认设置,所以对于恶魔和服务器来说,什么都不做通常没问题。)

全局语言环境会影响所有C 样式的输入和输出,这也是使用 C++ iostream 的另一个原因。使用 std::ifstream,只需在进行第一次输入之前将写入文件的语言环境灌输给流。对于机器生成的文件,"C"语言环境是通常的默认值,因此您的代码将变为:

std::ifstream file3( "test.dat" );
if ( ! file3.is_open() ) {
    //  error handling...
}
file3.imbue( std::locale( "C" ) );
float test1;
file3 >> test1;
//  ...

对于终端的输出,期望遵循语言环境约定。并设置环境变量以指定您要查看的语言环境。

于 2012-11-21T10:11:31.187 回答