2013-05-28 2 views
0

Код, над которым я работаю, открывает неинициализированный файл и сканирует следующие переменные. Я пытаюсь понять, что он делает, но я не понимаю, что пытается форматировать FSYM и ISYM (?), Кроме, возможно, объявляя их как float или int strings.Что это за sscanf?

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 
    ); 

line - это первая строка открытого файла, которая затем проверяется на переменные. Любые идеи относительно того, что происходит?

+1

вероятно они являются определяет, оценивающие в строку во время компиляции. – moooeeeep

+2

попробуйте 'printf' те –

ответ

1

Это конкатенация препроцессора. Они должны быть определены как строки в другом месте; когда cpp попадает в несколько соседних строк, он объединяет их вместе, поэтому код использует препроцессор для построения более длинной строки из предопределенных частей.

+0

Это не конкатенация строки препроцессора. –

+1

@NikBougalis: Да, это так. Или вы определяете «предварительную обработку» означает нечто иное, чем «этапы перевода с 1 по 6» (т. Е. Вся обработка, которая идет перед компиляцией)? –

+0

Я определяю конкатенацию препроцессора как 'A ## B', но это может быть слишком педантичным. Соответствует ли стандарт процессу устранения закрывающей двойной кавычки, за которым следуют пробелы, а затем другая двойная кавычка как «конкатенация»? –

7

Предположительно, это макросы, определенные где-то в вашем коде, которые расширяются до строковых литералов, содержащих необходимые спецификаторы для строки 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++ имеет Типобезопасный ввода/вывода, чтобы избежать весь этот бред:

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

или 'ISYM' означает, что символ« i »и« FSYM »означает« f symbol »aka« целочисленный символ »и« float symbol » –

+0

@ 0A0D: Да, по-видимому, они не подходят для« целочисленного символа »и« с плавающей запятой » символ". –

+0

Вы правы, после того, как я немного скорчился, я нашел их в другом файле. Оказывается, вы также были правы в своих определениях по этому вопросу. – Adrian