[英]How to choose fscanf format based on the type of the variable?
Let's say I'm implementing a matrix and I want my struct to use scalar_t
, where scalar_t
can be float
or double
. 假设我正在实现一个矩阵,并且希望我的结构使用scalar_t
,其中scalar_t
可以是float
或double
。
Then, let's say I want to scan some text file and load it into my matrix: 然后,假设我要扫描一些文本文件并将其加载到矩阵中:
// Inner loop:
fscanf(mdata, format, &m->data[i * m->cols + j]);
If scalar_t *
is float *
, format
should be "%f"
. 如果scalar_t *
为float *
,则format
应为"%f"
。 In case of double *
it's "%lf"
. 如果为double *
, "%lf"
。
How do I condition the format on the type of scalar_t
? 如何根据scalar_t
的类型设置scalar_t
? I know that I could compare sizeof
but is there a general solution? 我知道我可以比较sizeof
但是有一个通用的解决方案吗?
The designers of C99's <inttypes.h>
had a similar problem. C99的<inttypes.h>
的设计人员也遇到了类似的问题。 They defined types like int32_t
with some specific properties, and allowed each implementation to typedef it as int
or long
as necessary. 他们使用一些特定的属性定义了诸如int32_t
类的类型,并允许每个实现将其typedef定义为int
或所需的long
。 But then printf and scanf formats became platform-specific. 但是后来printf和scanf格式成为特定于平台的格式。
Their solution was to define a set of macros along with each type, like SCNd32
which will be "d"
or "ld"
to match int
or long
for the typedef. 他们的解决方案是为每种类型定义一组宏,例如SCNd32
,将其为"d"
或"ld"
以匹配typedef的int
或long
。
Usage looks like 用法看起来像
int32_t i;
scanf("%"SCNd32, &i);
For each type, there's a separate macro for every conversion that you might want to do with the type (so not just d
but also x
for hex, etc.) 对于每种类型,对于您可能要与该类型进行的每次转换,都有一个单独的宏(因此,不仅是d
而且还有x
代表十六进制,等等)
You can do the same for your custom types. 您可以对自定义类型执行相同的操作。 In the header: 在标题中:
#if something
typedef float scalar_t;
#define SCNfSCALAR "f"
#else
typedef double scalar_t;
#define SCNfSCALAR "lf"
#endif
And in the calling code: 并在调用代码中:
scalar_t x;
scanf("%"SCNfSCALAR, &x);
Given that 鉴于
You are going to need a union
that has a float
and a double
. 您将需要一个union
,有一个float
和double
。
The C standard requires a double
to be a superset of a float
. C标准要求double
是float
的超集。
Increasingly, platforms are setting float
and double
to the same thing, although they are required to be separate types, much along the lines of char
, unsigned char
, and signed char
are always three separate types. 尽管要求平台是独立的类型,但越来越多的平台将float
和double
设置为相同的类型,在很多方面, char
, unsigned char
和signed char
始终是三种独立的类型。
by far the best thing to do here is to use a double
. 到目前为止,最好的方法是使用double
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.