Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/61.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C语言中打开4个字符的字符串?_C_String_Macros_Switch Statement - Fatal编程技术网

如何在C语言中打开4个字符的字符串?

如何在C语言中打开4个字符的字符串?,c,string,macros,switch-statement,C,String,Macros,Switch Statement,我需要根据4个字符的字符串进行切换。我把字符串放在一个并集中,这样我至少可以将它称为32位整数 union { int32u integer; char string[4]; }software_version; 但现在我不知道在案件陈述中写什么。我需要某种宏来将4个字符的字符串文字转换为整数。例如 #define STRING_TO_INTEGER(s) ?? What goes here ?? #define VERSION_2_3_7 S

我需要根据4个字符的字符串进行切换。我把字符串放在一个并集中,这样我至少可以将它称为32位整数

union
{
    int32u  integer;
    char    string[4];
}software_version;
但现在我不知道在案件陈述中写什么。我需要某种宏来将4个字符的字符串文字转换为整数。例如

#define STRING_TO_INTEGER(s)    ?? What goes here ??
#define VERSION_2_3_7           STRING_TO_INTEGER("0237")
#define VERSION_2_4_1           STRING_TO_INTEGER("0241")

switch (array[i].software_version.integer)
{
    case VERSION_2_3_7:
        break;

    case VERSION_2_4_1:
        break;
}
是否有一种方法可以生成字符串\u to \u INTEGER()宏。还是有更好的方法来处理开关?

更新:

#define VERSION_2_3_7 '0237'

您可以像这样打开四个字符的代码

switch (fourcc) {
case 'FROB':
}
请注意区别:
“XXXX”
是一个字符串,
“XXXX”
是一个字符/整数文本

但是,我建议您使用单独的版本号,例如:

struct Version {
    int major, minor, patch;
};

bool smaller (Version lhs, Version rhs) {
    if (lhs.major < rhs.major) return true;
    if (lhs.major > rhs.major) return false;
    if (lhs.minor < rhs.minor) return true;
    if (lhs.minor > rhs.minor) return false;
    if (lhs.patch < rhs.patch) return true;
    if (lhs.patch > rhs.patch) return false; // redundant, for readabiltiy

    return false; // equal
}
struct版本{
int大调、小调、面片;
};
bool更小(lhs版、rhs版){
如果(左S.major<右S.major)返回true;
如果(左S.major>右S.major)返回false;
如果(左S.minor<右S.minor)返回true;
如果(左S小调>右S小调)返回false;
如果(lhs.patchrhs.patch)返回false;//冗余,以确保可读性
返回false;//等于
}
编辑:

可移植示例代码:

#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#define CHARS_TO_U32(c1, c2, c3, c4) (((uint32_t)(uint8_t)(c1) | \
    (uint32_t)(uint8_t)(c2) << 8 | (uint32_t)(uint8_t)(c3) << 16 | \
    (uint32_t)(uint8_t)(c4) << 24))

static inline uint32_t string_to_u32(const char *string)
{
    assert(strlen(string) >= 4);
    return CHARS_TO_U32(string[0], string[1], string[2], string[3]);
}

#define VERSION_2_3_7 CHARS_TO_U32('0', '2', '3', '7')
#define VERSION_2_4_1 CHARS_TO_U32('0', '2', '4', '1')

int main(int argc, char *argv[])
{
    assert(argc == 2);
    switch(string_to_u32(argv[1]))
    {
        case VERSION_2_3_7:
        case VERSION_2_4_1:
        puts("supported version");
        return 0;

        default:
        puts("unsupported version");
        return 1;
    }
}
#包括
#包括
#包括
#包括
#定义字符到字符32(c1、c2、c3、c4)(c1)\


(uint32_t)(uint8_t)(c2)他需要从一个字符串到另一个数字,而不是从一个数字到另一个字符串。问题的方向正好相反。@SethCarnegie,请看上面的评论人员,停止投票。这实际上是正确的答案。@Rocketmagnet,这个答案有缺陷,不要这样使用。包含多个字符的字符常量,如建议的
'0237'
是特定于编译器的。此外,如果您真的对单个定义感到满意,那么就没有理由使用这样的cruft。只需将其定义为长的无符号十进制数,例如
237UL
。您是否知道这不能跨端性边界移植?最好只定义一个版本整数这是从程序开始时的数字版本开始递增或计算的。我不认为你可以在编译时从字符串->数字。为什么你坚持用宏从字符串转换你的
版本
常量?你可以简单地…你知道…直接输入整数(例如
#定义版本_2_3_7 237
)…@SethCarnegie One可以使用
sscanf
解析字符串中的整数。还请注意,如果您坚持使用版本的字符数组表示,并且需要4个字符,则应将结构的字符串元素定义为5个字符,其中一个字符表示空值。您误解了标准。访问的不是如果值恰好是另一种类型的陷阱表示,则最后写入的ne仅为UB。
int32u
(我想这与
uint32\t
相同)没有陷阱表示法。我不明白这对我的switch语句有什么帮助。@Rocketmagnet:你只能切换整数类型,切换字符串/字符数组没有定义。@Jens:我将删除该短语。谢谢你的提示。@phresnel是的,我知道这一点,从我的问题中可以明显看出。这就是为什么我想要一种自动转换字符串/字符数组的方法字符串转换为整数。不,这不起作用,因为它不能在case语句中使用。是的,它可以,只在case中使用数字ID。它们应该是文本,程序员会仔细地将它们与相应的代码块匹配。当一个数字同样可读且错误较少时,为什么要使用字符串作为case标签rone?如果字符串包含字母怎么办?例如“ABC1”->0x41424331嗯,您必须解析它,不是吗?而且在项目的中期危机中更改命名/编号方案似乎没有多大意义。类似的方案应该是稳定的。重点是将字符串的4x8位重新解释为32位整数。不要解析字符串。任何4个字符的字符串,包括g“0_?Q”可以重新表示为整数。但是,只有数字字符串可以解析为整数。
#define STRING_TO_INTEGER(s)    versionstring_to_int(s)
#define VERSION_2_3_7           237
#define VERSION_2_4_1           241

switch ( STRING_TO_INTEGER( array[i].software_version.string) )
{
case VERSION_2_3_7:
    break;

case VERSION_2_4_1:
    break;
}
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>

#define CHARS_TO_U32(c1, c2, c3, c4) (((uint32_t)(uint8_t)(c1) | \
    (uint32_t)(uint8_t)(c2) << 8 | (uint32_t)(uint8_t)(c3) << 16 | \
    (uint32_t)(uint8_t)(c4) << 24))

static inline uint32_t string_to_u32(const char *string)
{
    assert(strlen(string) >= 4);
    return CHARS_TO_U32(string[0], string[1], string[2], string[3]);
}

#define VERSION_2_3_7 CHARS_TO_U32('0', '2', '3', '7')
#define VERSION_2_4_1 CHARS_TO_U32('0', '2', '4', '1')

int main(int argc, char *argv[])
{
    assert(argc == 2);
    switch(string_to_u32(argv[1]))
    {
        case VERSION_2_3_7:
        case VERSION_2_4_1:
        puts("supported version");
        return 0;

        default:
        puts("unsupported version");
        return 1;
    }
}