Как изменить значение спецификатора формата во время выполнения?

я использую sscanf в моем проекте, чтобы скопировать строки из исходного буфера в целевой буфер.
Например:

char* target;
target = (char*)malloc(100 * sizeof(char));
char* source = "Hello World";
sscanf(source, "%[^\t\n]", target); // trying to copy "Hello World" into target.
printf("%s\n", target);//this will print "Hello World".

Но этот способ кодирования стиля не принят. Мой менеджер хочет, чтобы я сделал что-то вроде:

sscanf(source, "%11[^\t\n]", target); // NOTE: I've written "%11". here, 11 == length of hello world.

Это означает, что он хочет, чтобы я также предоставил спецификаторы формата. (% 11 в этом случае).

Но проблема в том, что источник может иметь разную длину, и я не знаю, как написать правильный спецификатор формата для каждой строки переменной длины.

1

Решение

Использование:

sscanf(source, "%*[^\t\n]", maxlen, target)

где maxlen — размер, который вы хотите прочитать.

Кажется, нет простого способа сделать строку формата для sscanf (или любой из его братьев и сестер) принимают произвольную максимальную длину входной строки. Предложение было основано на printf быть ортогональным к scanfчто оказывается не так.

Вы можете найти, что вам повезло больше, используя strtok и либо strncpy или же strdup скопировать токен.

Однако, поскольку он помечен C ++, почему бы не использовать:

std::stringstream ss(source);
std::string target;
getline(ss, target, "\t");
7

Другие решения

Для копирования строки используйте strcpy(), Он не выделяет пространство, поэтому вы должны также предоставить второй буфер. Есть также strncpy() который не будет копировать больше, чем указанные символы.

Если вы хотите сделать копию строки за один раз, вы можете использовать strdup(), только не забудьте потом освободить память.

0

Сначала используйте strcpy () для этого.

Во-вторых, спецификатор формата — это просто строка, поэтому просто используйте sprintf (), чтобы сделать это после получения strlen () нужной вам строки.

0

использование target = strdup(source) или если все еще обязан использовать sscanf():

динамично создать формат.

const char* source = "Hello World";
size_t n = 10;  // See note below
char* target;
target = (char*) malloc(n);  // (char *) is needed for C++, but not C
char format[1+20+5+1];
sprintf(format, "%%" "%zu" "[^\t\n]", n - 1);
sscanf(source, format, target); // trying to copy "Hello World" into target.
printf("%s\n", source);//this will print "Hello World".
printf("%s\n", target);//this will print "Hello Wor".

Вы, вероятно, захотите n = strlen(source) + 1, но выше показывает, как динамически созданный спецификатор формата для scanf() предотвращает переполнение буфера в target,

0
По вопросам рекламы [email protected]