2013-08-01 4 views
0

Я понимаю, что следующее не будет работать, но есть ли эквивалент?Глобальная переменная в основном с конкатенацией?

const char *foo = "foo"; 
static char *end = sprintf ("%s_bar", foo); 

То, что я хочу сделать, это конкатенации строк, а затем сделать этот сцепленную строку статическую переменную так, что она становится глобальной переменной. Также мне не нравится присваивать память символу. Мне нужно это сделать в main(), потому что мне нужно использовать функцию (sprintf) для слияния двух строк.

+2

Вы можете использовать оператор '##' в макросе –

+0

@alk - а как насчет когда есть переменная? Итак, «_bar» - это действительно переменная строка ... – user983223

+1

Обратите внимание, что на 64-битной машине вы выделили 12 байтов для поддержки 'foo': 8 байт для указателя и 4 байта для строки. Если вы получаете что-то для работы, у вас есть 16 байт, выделенных для 'end': 8 байтов для указателя и 8 байтов для строки. Вы должны указать 8 байтов для строки как-то. Обратите внимание, что использование 'const char foo [] =" foo ";' выделяет только 4 байта для строки, а 'const char end [] =" foo_bar ";' только выделяет 8 байтов для строки. –

ответ

1

sprintf объявлен как int sprintf (char * str, const char формат, ...); char* str - это буфер, на который будет записываться вывод, однако злоумышленники могут помещать больше в этот буфер, чем размер этого буфера, поэтому можно также использовать snprintf, который включает в себя параметр, который содержит размер выходного буфера, поэтому потоки bufferoverflow не будут выполняться. То, что вы должны отметить, возвращает количество записанных байтов, поэтому вы не можете назначить его char или char [].

const char* foo = "foo"; 
static char end[BUFSIZE]; 
snprintf(end, BUFSIZE, ""%s_bar", foo); 

Я предпочитаю использовать snprintf для него не так легко привести к переполнению буфера, который является ошибка безопасности. Теперь он может исправить BUFSIZ символов до end, вы можете посмотреть, удалось ли выполнить конкатенацию, если snprintf возвращает strlen («s_bar») + strlen («foo»);

Что вы можете сделать, это:

char end[BUFSIZE] = "foo_"; 
strncat(end, "_bar", BUFSIZ); 

, который, возможно, больше, чем вам нравится.

+1

Вы хотели написать' char end [BUFSIZE] ... '? – alk

+0

@alk oops your right right edit ;-) – hetepeperfan

1

Поверхностно, вы могли бы пересмотреть код следующим образом:

#define FOO_INITIALIZER "foo" 

const char *foo = FOO_INITIALIZER; 
static char *end = FOO_INITIALIZER "_bar"; 

Я не знаю, сколько он покупает вам, но он должен собрать и избежать повторения строк. Он использует смежную строковую конкатенацию строк, которая является стандартной в C89 и более поздних версиях (но не в предварительных стандартных компиляторах).

1

Я думаю, вы можете сделать это с помощью оператора строчки.

#define STR_CONCAT(x, y)  #x#y 

static char *end = STR_CONCAT(foo, _bar); 

int main(void) 
{ 
    printf("%s", end); // prints out "foo_bar" 
    getchar(); 
    return 0; 
} 
+2

Вы не можете использовать '##' для конкатенации строк (или, по крайней мере, ваш компилятор не должен позволять вам это делать) - и вам не нужно это делать потому что конкатенация строк происходит автоматически. –

+0

@JonathanLeffler: Это было фактически протестировано (MS VS2010). Поэтому я могу это сделать. :) – abelenky

+2

Вам нужно получить рабочий, совместимый со стандартом компилятор! GCC говорит «cat.c: 3: 1: error: inserting» «foo» и «» _bar »« не дает действительного токена предварительной обработки ». –

Смежные вопросы