如何定义数组以适应负指数?

时间:2015-02-28 11:29:26

标签: c string c-preprocessor

我正在尝试编写函数,当我在其参数中传递错误时将返回正确的字符串。但是我不清楚如何将负索引分配给字符串(对应于枚举FILE_ERRORS_t),你能澄清一下吗?

typedef enum {
    FOPEN_ERROR=-1,
    FREAD_ERROR=-2,
    FWRITE_ERROR=-3,
    FSEEK_ERROR=-4,
    FCLOSE_ERROR=-5
    } FILE_ERRORS_t;
#define printErr (const char*[5]){"Cannot open file", "Cannot read file", "Cannot write file", "fseek fail", "fclose fail" }

4 个答案:

答案 0 :(得分:2)

你不能创建一个带负数索引的数组,但你可以创建一个指向数组中间的指针,这样当你把它与负索引结合起来时,就会获得一个“常规”C数组的有效元素。方法如下:

static char * real_errors[] = {
    "fclose fail"       // -5
,   "fseek fail"        // -4
,   "Cannot write file" // -3
,   "Cannot read file"  // -2
,   "Cannot open file"  // -1
};
static char **errors = &real_errors[5]; // Point one element past the end

现在你可以这样写:

printf("%s\n", errors[FCLOSE_ERROR]);

它会起作用,因为它相当于

printf("%s\n", real_errors[5+FCLOSE_ERROR]);

Demo.

注意:如果错误指向数组内部或结束时错误,则只能定义良好。否则,它将是未定义的行为。

答案 1 :(得分:1)

尝试按照here描述的绝对值,然后减去一个。然后-1将变为0,-2将变为1,等等。应该按照您的意愿进行映射。所以函数可能看起来像这样:

int errorCodeToIndex(FILE_ERRORS_t errorCode) {
    return abs(errorCode) - 1

您可能需要将errorCode转换为int并记住#include <stdlib.h>

答案 2 :(得分:1)

您可以使用反向字符串顺序的负索引:

#include <stdio.h>

typedef enum {
    FOPEN_ERROR=-1,
    FREAD_ERROR=-2,
    FWRITE_ERROR=-3,
    FSEEK_ERROR=-4,
    FCLOSE_ERROR=-5
    } FILE_ERRORS_t;

#define sup ((const char *[]){"fclose fail", "fseek fail", "Cannot write file" ,"Cannot read file", "Cannot open file", ""} + 5)

int main(void)
{
    puts(sup[FSEEK_ERROR]);
    return 0;
}

Ouptut:

fseek fail

答案 3 :(得分:1)

只需使用类似函数的宏和指定的初始值设定项

#define printErr(E) (const char*const[]){[-FOPEN_ERROR] = "Cannot open file", ... }[-E]

这使得数组尽可能大,并确保每个字符串都放在其中的正确位置。