Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use a #defined constant as the max field width in fscanf?

Tags:

c

macros

c89

scanf

All of this is in C89, not C99.

I have a constant.

#define MAX_NAME_LEN 256

I want to use it as the max field width in fscanf, sort of like this.

fscanf(input, "%256s", name);

But I want to use the MAX_NAME_LEN instead of the literal 256 for sake of good style. I have tried all of

fscanf(input, "%MAX_NAME_LENs", name);

char* max_name_len_str = malloc(16 * sizeof *max_name_len_str);
sprintf(max_name_len_str, "%d", MAX_NAME_LEN);
fscanf(input, "%" max_name_len_str "s", name);
free(max_name_len_str);

//works with printf, but has different meaning in scanf
fscanf(input, "%*s", MAX_NAME_LEN, name);

fscanf(input, "%%ds", MAX_NAME_LEN, name);

without success.

char* nameFormat = malloc(16 * sizeof *nameFormat); //I assume I don't ever want more than 10^13 characters in a name
sprintf(nameFormat, "%s%ds", "%", MAX_NAME_LEN);
fscanf(input, nameFormat, name);
free(nameFormat);

does work, but is ungainly as all get out. Is there a more elegant solution?

like image 707
SonicN Avatar asked Jun 21 '17 20:06

SonicN


People also ask

How do you use or a?

Articles are used before nouns or noun equivalents and are a type of adjective. The definite article (the) is used before a noun to indicate that the identity of the noun is known to the reader. The indefinite article (a, an) is used before a noun that is general or when its identity is not known.

When to use a or an before a vowel?

The rule is: Use an before a word beginning with a vowel sound (not letter). It doesn't matter how the word is spelled. It just matters how it is pronounced. Use a before a word with a consonant sound as well as y and w sounds.

How do you use a in a word?

The rule is that you use “a” before words that start with a consonant sound and “an” before words that start with a vowel sound.


1 Answers

You can use this macro:

#define STRINGIFY(X) INDIRECT(X)
#define INDIRECT(X) #X

like this:

#define MAX 10
puts("%"STRINGIFY(MAX)"d");

which will print %10d.

In your case it would be

char name[MAX_NAME_LEN + 1];
fscanf(input, "%"STRINGIFY(MAX_NAME_LEN)"s", name);

The # in the macro stringifies (makes " around it) whatever is after it. So the macro must be the decimal number only.
The level of indirection is needed to expand MAX_NAME_LEN to 256. INDIRECT(MAX_NAME_LEN) would expand to "MAX_NAME_LEN".

like image 62
mch Avatar answered Sep 18 '22 05:09

mch