我能确定一个参数是字符串? [英] Can I determine if an argument is string literal?

查看:100
本文介绍了我能确定一个参数是字符串?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否有可能确定在宏或函数传递参数是一个字符串常量在编译时或运行时?

Is it possible to determine if an argument passed in macro or function is a string literal at compile time or run time ?

例如,

#define is_string_literal(X)
...
...   

is_string_literal("hello") == true;
const char * p = "hello";
is_string_literal(p) == false;

bool is_string_literal(const char * s);

is_string_literal("hello") == true;
const char * p = "hello";
is_string_literal(p) == false;

感谢。

推荐答案

YES! (感谢詹姆斯McNellis 并的 GMAN 的更正已更新至正确处理级联文字像你好,世界!这在连接前得到stringized。)

YES! (Thanks to James McNellis and GMan for corrections. Updated to correctly handle concatenated literals like "Hello, " "World!" which get stringized before concatenation.)

#define is_literal_(x) is_literal_f(#x, sizeof(#x) - 1)
#define is_literal(x) is_literal_(x)

bool is_literal_f(const char *s, size_t l)
{
    const char *e = s + l;
    if(s[0] == 'L') s++;
    if(s[0] != '"') return false;
    for(; s != e; s = strchr(s + 1, '"'))
      {
        if(s == NULL) return false;
        s++;
        while(isspace(*s)) s++;
        if(*s != '"') return false;
      }
    return true;
}

这将字符串化的参数传递给函数之前,因此,如果该参数是一个字符串,传递给我们的函数的参数将与引号括起来。

This will stringify the argument before passing it to the function, so if the argument was a string literal, the argument passed to our function will be surrounded with quote characters.

如果您认为这是一个字符串:

If you consider this a string literal:

const char *p = "string";
// should is_literal(p) be true or false?

我也帮不了你。你也许可以使用一些实现定义(或*不寒而栗*未定义)行为来测试一个字符串是否存储在只读存储器,但在一些(可能是较旧的)系统 P 可以修改。

对于那些谁怀疑使用这种功能,可以考虑:

For those who question the use of such a function, consider:

enum string_type { LITERAL, ARRAY, POINTER };

void string_func(/*const? */char *c, enum string_type t);

而不是明确指定的第二个参数 string_function 在每次调用, is_literal 让我们可以用它包装宏:

Rather than explicitly specifying the second argument to string_function on every call, is_literal allows us to wrap it with a macro:

#define string_func(s) \
    (string_func)(s, is_literal(s)  ? LITERAL :
        (void *)s == (void *)&s ? ARRAY : POINTER)

我无法想象为什么它会有所作为,除了在普通的C文字的地方都没有常量,由于某种原因,你不希望/罐T写函数作为采取为const char * ,而不是字符。但也有各种各样的原因想要做的事。有一天你也可能觉得有必要诉诸一个可怕的黑客。

I can't imagine why it would make a difference, except in plain C where literals aren't const and for some reason you don't want to/can't write the function as taking a const char * instead of a char. But there are all kinds of reasons to want to do something. Someday you, too may feel the need to resort to a horrible hack.

这篇关于我能确定一个参数是字符串?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆