这个扫描仪在做什么?

What is this sscanf doing?

本文关键字:什么 扫描仪      更新时间:2023-10-16

我正在处理的代码是打开一个未初始化的文件并扫描以下变量。我想弄清楚它在做什么,但我不明白FSYM和ISYM格式(?)试图做什么,除了可能将它们声明为float或int字符串。

sscanf(line, "%"ISYM" %"ISYM" %"ISYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM" %"FSYM,
   &idummy, // nt   - skip
   &idummy, // l    - skip
   &idummy, // lev  - skip
   rad+nl,  // x    = radial coordinate
   vel+nl,  // xdot = radial velocity
   den+nl,  // rho  = density
   &dummy,  // tev  - skip temperature (eV)
   pre+nl   // p    = pressure
   );

行是打开文件的第一行,然后扫描到变量中。知道发生了什么吗?

假设它们是在代码中定义的宏,它们扩展为包含scanf字符串所需说明符的字符串字面量。比如

#define ISYM "d" // integer symbol for scanf
#define FSYM "f" // floating-point symbol for scanf

这样展开后参数变成

"%""d"" %""d"" %""d"" %""f"" %""f"" %""f"" %""f"" %""f"

和,因为连续的字符串字面值被连接成一个字符串,所以这相当于

"%d %d %d %f %f %f %f %f"

如果您想更改类型,这可能很有用:

#ifdef BIG_TYPES
    typedef long   i_type;
    typedef double f_type;
    #define ISYM "ld"
    #define FSYM "lf"
#else
    typedef int   i_type;
    typedef float f_type;
    #define ISYM "d"
    #define FSYM "f"
#endif

当然,c++有类型安全的I/O来避免所有这些废话:

std::istringstream ss(line);
ss >> idummy;
// and so on

这是预处理字符串连接。它们必须在其他地方定义为字符串;当CPP遇到多个相邻字符串时,它将它们连接在一起,因此代码使用预处理器从预定义的部分构建更长的字符串。