How to Initialize char array from a string

后端 未结 11 1994
时光说笑
时光说笑 2020-12-14 09:19

I want to do the following

char a[] = { \'A\', \'B\', \'C\', \'D\'};

But I do not want to write these characters separately. I want somethi

相关标签:
11条回答
  • 2020-12-14 09:46

    You can't - in C. In C initializing of global and local static variables are designed such that the compiler can put the values statically into the executable. It can't handle non-constant expressions as initializers. And only in C99, you can use non-constant expression in aggregate initializers - not so in C89!

    In your case, since your array is an array containing characters, each element has to be an arithmetic constant expression. Look what it says about those

    An arithmetic constant expression shall have arithmetic type and shall only have operands that are integer constants, floating constants, enumeration constants, character constants, and sizeof expressions.

    Surely this is not satisfied by your initializer, which uses an operand of pointer type. Surely, the other way is to initialize your array using a string literal, as it explains too

    All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

    All quotes are taken out of the C99 TC3 committee draft. So to conclude, what you want to do - using non-constant expression - can't be done with C. You have several options:

    • Write your stuff multiple times - one time reversed, and the other time not reversed.
    • Change the language - C++ can do that all.
    • If you really want to do that stuff, use an array of char const* instead

    Here is what i mean by the last option

    char const c[] = "ABCD";
    char const *f[] = { &c[0], &c[1], &c[2], &c[3] };
    char const *g[] = { &c[3], &c[2], &c[1], &c[0] };
    

    That works fine, as an address constant expression is used to initialize the pointers

    An address constant is a null pointer, a pointer to an lvalue designating an object of static storage duration, or a pointer to a function designator; it shall be created explicitly using the unary & operator or an integer constant cast to pointer type, or implicitly by the use of an expression of array or function type. The array-subscript [] and member-access . and -> operators, the address & and indirection * unary operators, and pointer casts may be used in the creation of an address constant, but the value of an object shall not be accessed by use of these operators.

    You may have luck tweaking your compiler options - another quote:

    An implementation may accept other forms of constant expressions.

    0 讨论(0)
  • 2020-12-14 09:47

    Weird error.

    Can you test this?

    const char* const S = "ABCD";
    char t[] = { S[0], S[1], S[2], S[3] };
    char u[] = { S[3], S[2], S[1], S[0] };
    
    0 讨论(0)
  • 2020-12-14 09:47

    I'm not sure what your problem is, but the following seems to work OK:

    #include <stdio.h>
    
    int main()
    {
        const char s0[] = "ABCD";
        const char s1[] = { s0[3], s0[2], s0[1], s0[0], 0 };
    
        puts(s0);
        puts(s1);
        return 0;
    }
    
    
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.
    cl /Od /D "WIN32" /D "_CONSOLE" /Gm /EHsc /RTC1 /MLd /W3 /c /ZI /TC
       .\Tmp.c
    Tmp.c
    Linking...
    
    Build Time 0:02
    
    
    C:\Tmp>tmp.exe
    ABCD
    DCBA
    
    C:\Tmp>
    

    Edit 9 June 2009

    If you need global access, you might need something ugly like this:

    #include <stdio.h>
    
    const char *GetString(int bMunged)
    {
        static char s0[5] = "ABCD";
        static char s1[5];
    
        if (bMunged) {
            if (!s1[0])  {
                s1[0] = s0[3]; 
                s1[1] = s0[2];
                s1[2] = s0[1];
                s1[3] = s0[0];
                s1[4] = 0;
            }
            return s1;
        } else {
            return s0;
        }
    }
    
    #define S0 GetString(0)
    #define S1 GetString(1)
    
    int main()
    {
        puts(S0);
        puts(S1);
        return 0;
    }
    
    0 讨论(0)
  • 2020-12-14 09:52

    Here is obscure solution: define macro function:

    #define Z(x) \
            (x==0 ? 'A' : \
            (x==1 ? 'B' : \
            (x==2 ? 'C' : '\0')))
    
    char x[] = { Z(0), Z(1), Z(2) };
    
    0 讨论(0)
  • 2020-12-14 09:58

    That's one of the cases a script to generate the appropriate code might help.

    0 讨论(0)
  • 2020-12-14 10:03

    The compilation problem only occurs for me (gcc 4.3, ubuntu 8.10) if the three variables are global. The problem is that C doesn't work like a script languages, so you cannot take for granted that the initialization of u and t occur after the one of s. That's why you get a compilation error. Now, you cannot initialize t and y they way you did it before, that's why you will need a char*. The code that do the work is the following:

    #include <stdio.h>
    #include <stdlib.h>
    
    #define STR "ABCD"
    
    const char s[] = STR;
    char* t;
    char* u;
    
    void init(){
        t = malloc(sizeof(STR)-1);
        t[0] = s[0];
        t[1] = s[1];
        t[2] = s[2];
        t[3] = s[3];
    
    
        u = malloc(sizeof(STR)-1);
        u[0] = s[3];
        u[1] = s[2];
        u[2] = s[1];
        u[3] = s[0];
    }
    
    int main(void) {
        init();
        puts(t);
        puts(u);
    
        return EXIT_SUCCESS;
    }
    
    0 讨论(0)
提交回复
热议问题