Как инициализировать массив char из строки
Я хочу сделать следующее
char a[] = { 'A', 'B', 'C', 'D'};
Но я не хочу писать эти персонажи отдельно. Я хочу что-то вроде
#define S "ABCD"
char a[] = { S[0], S[1], S[2], S[3] };
Но это не скомпилируется (gcc говорит, что элемент инициализации не является константой).
Я попытался заменить строку #define на
const char S[] = "ABCD";
Но это не помогает.
Как я могу это сделать (или что-то подобное), что позволяет мне записывать "ABCD" как обычную "строку", а не как четыре отдельных символа?
P.S. Кажется, что люди не правильно читают вопрос...
Я не могу получить следующий код для компиляции:
const char S[] = "ABCD";
char t[] = { S[0], S[1], S[2], S[3] };
char u[] = { S[3], S[2], S[1], S[0] };
Ответы
Ответ 1
Вы не можете - в C. В C инициализация глобальных и локальных статических переменных сконструирована таким образом, что компилятор может статически ставить значения в исполняемый файл. Он не может обрабатывать не константные выражения в качестве инициализаторов. И только в C99 вы можете использовать непостоянное выражение в агрегатных инициализаторах - не так в C89!
В вашем случае, поскольку ваш массив представляет собой массив, содержащий символы, каждый элемент должен быть арифметическим константным выражением. Посмотрите, что он говорит о тех
Арифметическое константное выражение должно иметь арифметический тип и должно иметь операнды, которые являются целыми константами, текущими константами, константами перечисления, характером константы и выражения sizeof.
Конечно, это не выполняется вашим инициализатором, который использует операнд типа указателя. Конечно, другим способом является инициализация вашего массива с использованием строкового литерала, так как он также объясняет
Все выражения в инициализаторе для объекта с длительностью статического хранения должны быть постоянными выражениями или строковыми литералами.
Все цитаты взяты из проекта комитета C99 TC3. Итак, в заключение, то, что вы хотите сделать - использование непостоянного выражения - не может быть выполнено с C. У вас есть несколько вариантов:
- Напиши свой материал несколько раз - один раз перевернутый, а другой раз не обратный.
- Измените язык - С++ может сделать все.
- Если вы действительно хотите это сделать, используйте массив
char const*
вместо
Вот что я хочу сказать по последней опции
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] };
Это работает отлично, поскольку выражение константы адреса используется для инициализации указателей
Константа адреса является нулевым указателем, указателем на lvalue, обозначающим объект статической продолжительности хранения, или указателем на указатель функции; он должен быть явно создан с использованием унарного и оператора или целочисленной константы, переданной в тип указателя, или неявно с помощью выражения типа массива или типа функции. Массив-индекс [] и член-доступ. и → операторы, унарные операторы адреса и истребителя *, а также приведения указателей могут быть использованы при создании константы адреса, но с помощью этих операторов нельзя получить доступ к значению объекта.
Возможно, вам повезло настроить ваши параметры компилятора - еще одна цитата:
Реализация может принимать другие формы постоянных выражений.
Ответ 2
Просто
const char S[] = "ABCD";
должен работать.
Что ваш компилятор?
Ответ 3
Другой вариант - использовать sprintf.
Например,
char buffer[50];
sprintf( buffer, "My String" );
Удачи.
Ответ 4
Это компилируется в gcc версии 4.3.3 (Ubuntu 4.3.3-5ubuntu4).
const char s[] = "cheese";
int main()
{
return 0;
}
Ответ 5
const char S[] = "ABCD";
Это должно сработать. Я использую только эти обозначения, и он отлично работает для меня. Я не знаю, как вы используете.
Ответ 6
Вот неясное решение: определить макрофункцию:
#define Z(x) \
(x==0 ? 'A' : \
(x==1 ? 'B' : \
(x==2 ? 'C' : '\0')))
char x[] = { Z(0), Z(1), Z(2) };
Ответ 7
Странная ошибка.
Вы можете проверить это?
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] };
Ответ 8
Я не уверен, в чем проблема, но, похоже, работает нормально:
#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>
Редактировать 9 июня 2009 г.
Если вам нужен глобальный доступ, вам может понадобиться что-то некрасивое:
#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;
}
Ответ 9
Проблема компиляции возникает только для меня (gcc 4.3, ubuntu 8.10), если три переменные глобальны. Проблема в том, что C не работает как языки script, поэтому вы не можете считать само собой разумеющимся, что инициализация u и t происходит после одного из s. Вот почему вы получаете ошибку компиляции. Теперь вы не можете инициализировать t и y, как вы это делали раньше, поэтому вам понадобится char *. Код, выполняющий работу, следующий:
#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;
}
Ответ 10
Что один из случаев, когда script генерирует соответствующий код, может помочь.
Ответ 11
Возможно, ваш массив символов должен быть постоянным. Поскольку вы инициализируете свой массив символами из константной строки, ваш массив должен быть постоянным. Попробуйте следующее:
#define S "ABCD"
const char a[] = { S[0], S[1], S[2], S[3] };