简体   繁体   English

如何根据变量类型选择fscanf格式?

[英]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可以是floatdouble

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的intlong

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 鉴于

  1. You are going to need a union that has a float and a double . 您将需要一个union ,有一个floatdouble

  2. The C standard requires a double to be a superset of a float . C标准要求doublefloat的超集。

  3. 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. 尽管要求平台是独立的类型,但越来越多的平台将floatdouble设置为相同的类型,在很多方面, charunsigned charsigned char始终是三种独立的类型。

by far the best thing to do here is to use a double . 到目前为止,最好的方法是使用double

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM