2009-06-08 28 views
14

que quiero hacer la siguientecómo inicializar matriz de caracteres de una cadena

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

Pero no quiero escribir estos caracteres por separado. Quiero algo como

#define S "ABCD" 

char a[] = { S[0], S[1], S[2], S[3] }; 

Pero esto no se compilará (gcc dice 'el elemento de inicialización no es constante').

he intentado reemplazar la línea #define con

const char S[] = "ABCD"; 

Pero eso no parece ayudar.

¿Cómo puedo hacer esto (o algo similar) que me permite escribir el "ABCD" como una 'cadena' normal, y no como cuatro caracteres separados?

P.S. Parece que la gente no lee correctamente la pregunta ...

no puedo obtener el código siguiente para compilar:

const char S[] = "ABCD"; 
char t[] = { S[0], S[1], S[2], S[3] }; 
char u[] = { S[3], S[2], S[1], S[0] }; 
+4

¿por qué no usar simplemente el carácter a [] = "ABCD"; –

+0

Definitivamente debería funcionar. ¿Cómo compilaste? ¿Qué opciones pasas a gcc? – qrdl

+1

Explica por qué quieres que se copie/asigne una cadena de caracteres a otra cadena de caracteres usando la asignación de caracteres individual. – nik

Respuesta

18

no se puede - en C. En C inicialización de variables estáticas globales y locales están diseñados de tal manera que el compilador puede poner los valores estáticamente en el ejecutable. No puede manejar expresiones no constantes como inicializadores. Y solo en C99, puede usar expresiones no constantes en inicializadores agregados, ¡no así en C89!

En su caso, dado que su matriz es una matriz que contiene caracteres, cada elemento tiene que ser una expresión de aritmética constante. Mira lo que dice acerca de los

Una expresión aritmética constante deberá tener tipo aritmético y sólo tendrá operandos que son constantes enteras, constantes flotantes, las constantes de enumeración, carácter constantes y expresiones sizeof.

Seguramente esto no está satisfecho con su inicializador, que utiliza un operando del tipo de puntero. Seguramente, la otra forma es inicializar su matriz usando un literal de cadena, como también explica

Todas las expresiones en un inicializador para un objeto que tiene una duración de almacenamiento estática deben ser expresiones constantes o literales de cadena.

Todas las comillas se extraen del borrador del comité C99 TC3. Para concluir, lo que quiere hacer - el uso de la expresión no constante - no se puede hacer con C. Tiene varias opciones:

  • ESCRIBE cosas varias veces - una vez revertida, y la otra vez no invertido
  • Cambiar el idioma - C++ puede hacer eso.
  • Si realmente quiere hacer esas cosas, utilizar una matriz de char const* lugar

Esto es lo que quiero decir con la última opción

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] }; 

que funciona bien, como una constante de direcciones expresión se utiliza para inicializar los punteros

Una constante de dirección es un puntero nulo, un puntero a un lvalue que designa una n objeto de duración de almacenamiento estático, o un puntero a un designador de función; se creará explícitamente utilizando el operador unario & o una conversión de entero a tipo de puntero, o implícitamente mediante el uso de una expresión de matriz o tipo de función. El conjunto de subíndices [] y el acceso de miembro. y -> operadores, la dirección & e indirección * operadores unarios, y los moldes de puntero pueden usarse en la creación de una constante de dirección, pero no se debe acceder al valor de un objeto mediante el uso de estos operadores.

puede tener más suerte ajustar sus opciones de compilación - otra cita:

Una implementación puede aceptar otras formas de expresiones constantes.

+1

+1 gran explicación y solución. –

3

Simplemente

const char S[] = "ABCD"; 

debería funcionar.

¿Cuál es su compilador?

+0

Tenga en cuenta que esto inicializa una matriz de 5 elementos. También está el \ 0 al final. Si no lo quiere, conviértalo en un const char S [sizeof ("ABCD") - 1] = "ABCD" – laalto

+0

Sí, solo especificando el tamaño a 4 hará que el compilador omita el \ 0. La elección depende de lo que realmente quieras hacer. –

+0

¿Has probado esto? Lo intenté con - ARM ADS 1.2 y gcc (para x86), y el resultado es el mismo: ambos compiladores se quejan de que la entrada ** no es ** const. –

0

Este compila bien en la versión de gcc 4.3.3 (Ubuntu 4.3.3-5ubuntu4).

const char s[] = "cheese"; 

int main() 
{ 
    return 0; 
} 
+0

Duh :-) Pero agregue una línea char t [] = {s [0], s [1]}; porque eso es lo que trato de hacer! –

+0

Arnaud: Entonces su problema es con esa línea. ¿Por qué quieres hacer eso? ¿Qué es exactamente lo que estás tratando de lograr? –

+1

Quiero tener DOS matrices de caracteres, con los mismos contenidos, pero en un orden diferente. Y esta orden se conoce en tiempo de compilación, ¡así que no quiero mezclar nada en el tiempo de ejecución! –

-1

Tal vez su matriz de caracteres debe ser constante. Ya que está inicializando su matriz con caracteres de una cadena constante, su matriz debe ser constante. Prueba esto:

#define S "ABCD" 
const char a[] = { S[0], S[1], S[2], S[3] }; 
+0

Gracias, pero no. Intenté esto y obtuve el mismo error, que es lógico, porque el compilador se queja de que mis 'elementos de inicialización' no son const! –

+0

Hm, pero "ABCD" [0] debería devolver un carácter const, ¿verdad? –

+0

Debería, es por eso que no entiendo que no funciona :-) –

0
const char S[] = "ABCD"; 

Esto debería funcionar. uso esta notación solamente y funciona perfectamente bien para mí. No sé cómo estás usando.

+0

Aparentemente no formulé mi pregunta muy claramente. Intente compilar las siguientes ** dos ** líneas: const char S [] = "ABCD"; char t [] = {S [0], S [1]}; –

+0

y cuál es la necesidad de que char s [] = "ABCD" solo no funcione para usted? cuál es el requisito exacto –

0

Aquí es solución oscura: definir la función macro:

#define Z(x) \ 
     (x==0 ? 'A' : \ 
     (x==1 ? 'B' : \ 
     (x==2 ? 'C' : '\0'))) 

char x[] = { Z(0), Z(1), Z(2) }; 
+0

Muévalos fuera de la función 'main'. No funcionarán como vars globales. –

+0

Es exactamente como Mehrdad dice: mi problema no ocurre dentro de una función, pero cuando estas variables son globales (o estáticas, pero no forman parte de una función) –

+0

@Mehrdad, @Arnaud: Ok, ya veo. Ahora cambié la solución a otra. –

0

error extraños.

se puede probar esto?

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

Ya lo intenté. No funciona tambien –

0

no estoy seguro de cuál es su problema, pero el siguiente parece funcionar bien:

#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> 

Editar 9 de junio de 2009

Si necesita acceso global, es posible que tenga algo feo como este:

#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

No funcionará si s1 será global. –

+0

Esta respuesta ya se intentó :-) ¡El problema es que la matriz debe ser global! –

0

El problema de compilación solo se produce para mí (gcc 4.3, ubuntu 8.10) si los tres va riables son globales.El problema es que C no funciona como un script de idiomas, por lo que no se puede dar por hecho que la inicialización de uy t ocurra después de la de s. Es por eso que obtienes un error de compilación. Ahora, no puede inicializar t e y de la forma en que lo hizo antes, es por eso que necesitará un char *. El código que haga el trabajo es el siguiente:

#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

Ese es uno de los casos en que una secuencia de comandos para generar el código apropiado podría ayudar.

2

Otra opción es usar sprintf.

Por ejemplo,

char buffer[50]; 
sprintf(buffer, "My String"); 

Buena suerte.

Cuestiones relacionadas