Как я могу использовать strncat без проблем переполнения буфера?

У меня есть буфер, я делаю много strncat. Я хочу, чтобы я никогда не переполнял размер буфера.

char buff[64]; strcpy(buff, "String 1"); strncat(buff, "String 2", sizeof(buff)); strncat(buff, "String 3", sizeof(buff)); 

Вместо sizeof (buff), я хочу сказать что-то buff-xxx. Я хочу убедиться, что я никогда не переопределяю буфер

Учитывайте размер существующей строки и нулевой ограничитель

 #define BUFFER_SIZE 64 char buff[BUFFER_SIZE]; //Use strncpy strncpy(buff, "String 1", BUFFER_SIZE - 1); buff[BUFFER_SIZE - 1] = '\0'; strncat(buff, "String 2", BUFFER_SIZE - strlen(buff) - 1); strncat(buff, "String 3", BUFFER_SIZE - strlen(buff) - 1); 

Почему бы не использовать snprintf ? В отличие от strncat он ожидает размер буфера, но что более важно, нет скрытого O (n).

Strcat должен найти нуль-терминатор для каждой строки, которую он объединяет, и каждый раз пробегает весь буфер, чтобы найти конец. Каждый раз, когда строка становится длиннее, strcat замедляется. Sprintf, с другой стороны, может отслеживать конец. вы обнаружите, что

 snprintf(buf, sizeof buf, "%s%s%s", "String1", "String2", "String3"); 

Чаще всего это быстрый, и более читаемый сототон.

То, как вы используете функцию strncat в вашем коде orignal, действительно будет подходящим для другой функции: strlcat (примечание l вместо n ). Функция strlcat не является стандартной, но является популярной заменой для strncat обеспечиваемой strncat . strlcat ожидает, что общий размер всего буфера назначения будет последним аргументом.

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

Я бы предположил, что вместо того, чтобы делать это ужасное злоупотребление strncpy и делать явные rescans с этими вызовами strlen (обе проблемы, представленные в ответе Джо), вы либо используете предоставленный реализацией strlcat либо реализуете его самостоятельно (если ваша реализация не обеспечивает strlcat ).

http://en.wikipedia.org/wiki/Strlcpy

Это лучший способ сделать это. sizeof() просто дает вам размер указателя на данные, если вы не выделяете его локально (в этом случае вы локально локализовались, но лучше сделать это таким образом, и он будет работать, если код будет переупорядочен).

 #define MAXBUFFSIZE 64 char buff[MAXBUFFSIZE]; buff[0] = 0; // or some string strncat(buff, "String x",MAXBUFFSIZE - strlen(buff) - 1); 

Хоган ответил на вопрос достаточно; однако, если вас беспокоит переполнение буфера в strcat(...) вы также должны быть обеспокоены переполнением буфера во всех остальных строковых функциях.

Используйте strnlen(...) и strncpy(...) чтобы убедиться, что вы остаетесь в своем буфере. Если у вас нет функции strnlen(...) , напишите ее.