How to make a macro that can take a string?

I'm trying to do something really trivial: A macro that takes an string and prints that to NSLog.

Like this:

#define PRINTTHIS(text) \
    NSLog(@"text");

However, when I try to pass a string to this guy I end up getting "text" printed to the console. Aren't all variables replaced on a string-level inside the macro? How to do that right?

Upvotes: 20

Views: 15719

Answers (8)

Mthokozisi
Mthokozisi

Reputation: 168

I am under the impression this is what you mean, and want

You want a string that can take an argument, while containing other strings, something similar to a stringwithformat function.

#define ThisMacro(value) @"Hello my name is %@, and I'm a developer", value

Then to use the macro you just pass it the value to which it adds to the full string

NSLog(ThisMacro(@"Mthokozisi"))

The end result will be, @"Hello my name is Mthokozisi, and I'm a developer"

Upvotes: 1

Hesadanza
Hesadanza

Reputation: 71

It seems like this would work as well.

#define PRINTTHIS(text) NSLog(@#text);

Just tested it, and it seems to work just fine.

Upvotes: 7

Eneko Alonso
Eneko Alonso

Reputation: 19682

I believe is just a matter of being careful with the spaces. This should work fine:

#define PRINTTEXT( msg ) NSLog( (msg) )

Another example:

#define TFCheckPoint( msg ) [TestFlight passCheckpoint: (msg) ];

Upvotes: 1

Jeff
Jeff

Reputation: 181

Use

#define PRINTTHIS(text) \
  do { NSLog(@"%s", #text); } while(0)

That way, text can contain % characters, its 'if-proof', the semi-colons are all in the right place, etc...

Personally, however, I'd say it makes more sense to just use NSLog() directly.

Upvotes: 5

Michael Burr
Michael Burr

Reputation: 340218

You'll want to use the preprocessor's 'stringizing' operator, #, and probably the 'token pasting' operator, '##':

#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)

#define PRINTTHIS(text) \
    NSLog(PASTE( @, STRINGIFY(text)));

I'm not sure if Objective-C requires the '@' to have no whitespace between it and the opening quote - if whitespace is permitted, drop the PASTE() operation.

Note that you'll need the goofy 2 levels of indirection for STRINGIFY() and PASTE() to work properly with macro parameters. And it pretty much never hurts unless you're doing something very unusual (where you don't want macro parameters expanded), so it's pretty standard to use these operators in that fashion.

Upvotes: 13

Chuck
Chuck

Reputation: 237060

Here's one way to write a macro that sticks its argument textually into a string object, though it strikes me as a bit gnarly:

#define PRINTTHIS(text) NSLog((NSString *)CFSTR(#text))

It uses the stringizing operator to turn the argument into a C string, which it then uses to create a CFString, which is toll-free bridged with NSString.

Upvotes: 9

Tim
Tim

Reputation: 60130

I think the problem you're running into is that "text" is inside what appears to the preprocessor as a string literal (the quotation marks, and possibly the @ symbol), so it's not replacing. Just a guess, but would this work?

#define PRINTTHIS(text) \
    NSLog(@"%@", text);

PRINTTHIS(@"string");

You could also define a version that takes C strings instead of ObjC strings:

#define PRINTTHIS_C(text) \
    NSLog(@"%s", text);

PRINTTHIS_C("string");

Upvotes: 3

Jim Lewis
Jim Lewis

Reputation: 45075

Take this with a grain of salt...I'm not an Objective-C developer. But in C function-like macros, macro parameters appearing inside string literals are not replaced by their corresponding actual arguments, so the substitution you're trying to do won't work.

This might work:

#define PRINTTHIS(text) \
    NSLog(@text);

PRINTTHIS("your message here");

(so the quotes are moved out of the macro definition.)

Chuck points out in a comment that in Objective-C, the @ is considered part of the token in this construct. So it might be necessary to use the token pasting operator ## :

#define PRINTTHIS(text) \
        NSLog(@##text);

Upvotes: 0

Related Questions