лучший способ объединить несколько строк в с? - PullRequest
23 голосов
/ 05 мая 2011

Есть ли лучший способ объединить несколько строк в c, кроме нескольких вызовов strcat () все подряд, как показано ниже?

char prefix[100] = "";
strcat(prefix, argv[0]);
strcat(prefix, ": ");
strcat(prefix, cmd_argv[0]);
strcat(prefix, ": ");
strcat(prefix, cmd_argv[1]);
perror(prefix);

Ответы [ 8 ]

21 голосов
/ 05 мая 2011
sprintf(prefix,"%s: %s: %s",argv[0],cmd_argv[0],cmd_argv[1]);

или snprintf для предотвращения переполнения буфера.

11 голосов
/ 05 мая 2011

snprintf будет лучшим и простым в использовании вариантом, хотя он может быть и не «быстрым». Вы не указали свои критерии. Простота, безусловно, такова:

snprintf(prefix, sizeof(prefix), "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);
5 голосов
/ 05 мая 2011

Я мог бы получить репутацию за это, но какого черта.Худшее, что может случиться, это то, что я чему-то научусь.

В настоящее время я действительно не использую C, и обычно я не использую строки в стиле C в C ++.Но у меня есть одна идея - написать модифицированный strcpy (), который возвращает конец строки:

char* my_strcpy(char*dest, const char* src)
{
    while ((*dest = *src++))
        ++dest;
    return dest;
}

Теперь Шлемиэль может взять с собой свое ведро:

char prefix[100] = "";
char* bucket = my_strcpy(prefix, argv[0]);
bucket = my_strcpy(bucket, ": ");
bucket = my_strcpy(bucket, cmd_argv[0]);
bucket = my_strcpy(bucket, ": ");
bucket = my_strcpy(bucket, cmd_argv[1]);
perror(prefix);

Iне проверял это.Комментарии?

РЕДАКТИРОВАТЬ: Удалена ненужная функция my_strcat().Также оказывается, что это то же самое, что и stpcpy(), который, по-видимому, является частью POSIX с 2008 года. См. http://www.manpagez.com/man/3/stpcpy/.

4 голосов
/ 05 мая 2011

Я бы использовал sprintf(), как предлагали другие, но для полноты:

Если у вас есть stpcpy(), то вы можете сделать:

char prefix[100] = "";
stpcpy(stpcpy(stpcpy(sptcpy(stpcpy(prefix, argv[0]), ": "),
        cmd_argv[0]), ": "), cmd_argv[1]);
perror(prefix);

Удобство с stpcpy() состоит в том, что он может быть "цепочкой", как указано выше.Кроме того, поскольку stpcpy() возвращает указатель на конец результирующей строки, последующим вызовам stpcpy() не нужно проходить старые данные снова и снова.Таким образом, он более эффективен, чем несколько strcat() с, и, вероятно, более эффективен, чем sprintf().stpcpy() - это POSIX: 2008.

2 голосов
/ 13 декабря 2014

Предполагая, что у вас есть символ [fixed_size] в качестве отправленного, а не символ *, вы можете использовать один творческий макрос, чтобы делать все это одновременно с упорядоченным образом, а не с разрозненным форматом стиля printf.Если вы работаете со встроенными системами, этот метод позволит вам исключить большое семейство функций printf, таких как snprintf() (это также не дает жаловаться на dietlibc) и даже не требует malloc() или каких-либо функций из <string.h>.

#include <unistd.h> //for write
//note: you should check if offset==sizeof(buf) after use
#define strcpyALL(buf, offset, ...) do{ \
    char *bp=(char*)(buf+offset); /*so we can add to the end of a string*/ \
    const char *s, \
    *a[] = { __VA_ARGS__,NULL}, \
    **ss=a; \
    while((s=*ss++)) \
         while((*s)&&(++offset<(int)sizeof(buf))) \
            *bp++=*s++; \
    if (offset!=sizeof(buf))*bp=0; \
}while(0)

char buf[100];
int len=0;
strcpyALL(buf,len, argv[0],": ", cmd_argv[0],": ",cmd_argv[1]);
if (len==sizeof(buf))write(2,"error\n",6);
else write(1,buf,len); 
  • Примечание 1, вы можете использовать любую функцию, которая выводит символ *, включая нестандартные функции, такие как itoa (), для преобразования целых чисел в строковые типы.
  • Примечание 2,если вы используете общую библиотеку или уже используете функцию стиля printf где-либо в вашей статически скомпилированной программе, единственная причина не использовать snprintf () (так как скомпилированный код будет больше при использовании этого метода), заключается в том, что он встроени не вызывает никаких внешних функций, поэтому он должен быть относительно быстрым.
2 голосов
/ 05 мая 2011

вы можете использовать snprintf function

char prefix[100];
snprintf(prefix, 100, "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);
2 голосов
/ 05 мая 2011

Если вы пытаетесь построить строку из других строк (что предлагает ваш пример), тогда вы можете использовать snprintf.

char prefix[100] = "";
snprintf( prefix, sizeof(prefix), "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);

Если вы пытаетесь выполнить конкатенацию существующей строки, где вы не можете использовать форматный подход, то вы, вероятно, застряли с несколькими вызовами strcat, хотя я настоятельно рекомендую вам рассмотреть вместо этого используйте strncat и убедитесь, что у вас нет переполнения буфера.

0 голосов
/ 15 мая 2019

Не могли бы вы использовать макрос.

#include <stdio.h>
#include <string.h>

#define a argv[0]
#define b argv[1]
#define c argv[2]
#define strcat1(a,b,c) strcat(prefix, a);\
                       strcat(prefix, ": ");\
                       strcat(prefix, b);\
                       strcat(prefix, ": ");\
                       strcat(prefix, c);\
                       perror(prefix);\



int main(int argc, char *argv[]){
    char prefix[100] = "";
    strcat1(a,b,c);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...