LINUX.ORG.RU

snscanf

 ,


0

1

Где брать snscanf для си? такого вида

int snscanf(const char *str, size_t size, const char *format, ...);

★★

Последнее исправление: punya (всего исправлений: 1)

Ответ на: комментарий от beastie

в const строке есть указатель на подстроку и известна ее длина. в подстроке нужно чего-то найти. делать дубликат этой подстроки с терминатором и искать в нем (так обычно все делают) - оверхед бессмысленный

punya ★★
() автор топика
Последнее исправление: punya (всего исправлений: 2)
Ответ на: комментарий от beastie

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

punya ★★
() автор топика
Ответ на: комментарий от punya

Если мне не именяет склероз, sscanf возвращает первое, что найдёт (в null-terminated-strings). В таком случае и ограничивать не имеет никокого смысла.

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

const char s[] = "10 20 30 40";

int
main()
{
        int a, b;

        sscanf(s + 3, "%d %d", &a, &b);

        printf("%d %d\n", a, b);

        return 0;
}
beastie ★★★★★
()
Ответ на: комментарий от beastie

Что эквивалентно (для legacy-code из win32):

#define snscanf(data, size, format, ...) sscanf(data, format, __VA_ARGS__)

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

из мана

These functions return the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero in the event of an early matching failure.

нужно ограничивать

punya ★★
() автор топика
Последнее исправление: punya (всего исправлений: 1)
Ответ на: комментарий от punya
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

int
snscanf(const char *str, size_t len, const char *format, ...)
{
        int ret;
        char *p;
        va_list ap;

        if (strlen(str) < len)
                return 0;

        p = strdup(str);
        if (!p)
                return -1;

        p[len + 1] = '\0';

        va_start(ap, format);
        ret = vsscanf(p, format, ap);
        va_end(ap);

        free(p);

        return ret;
}

PS: не там ты IMHO проблемы ищешь.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)

Слабонервным не читать:

#include <stdio.h>
#include <stdarg.h>

static int n;

#define snscanf(s, sz, fmt, ...) _snscanf(s, sz, fmt "%n", __VA_ARGS__, &n)

int _snscanf(const char *s, int sz, const char *fmt, ...) {
	va_list ap;
	va_start(ap, fmt);
	int res = vsscanf(s, fmt, ap);
	va_end(ap);

	if (n > sz)
		return -1;

	return res;
}

int main(void) {
	const char s[] = "1 2";
	int x, y;
	printf("%d %d\n",
		sscanf(s, "%d %d", &x, &y),
		snscanf(s, 1, "%d %d", &x, &y));
}

const86 ★★★★★
()
Ответ на: комментарий от const86

вот это хороший годный костыль. спс =)

punya ★★
() автор топика
Ответ на: комментарий от const86

return -1; нарушает логику работы функции.

Число sz может быть меньше длины строки. Кроме того функция может удачно прочитать данные за пределами выделенного массива и вернуть res > 0. Проверял с gcc.

anonymous
()
Ответ на: комментарий от anonymous

Это далеко не все проблемы этого костыля. Но стоит ли даже начинать их перечислять, когда код и так каждой своей строчкой кричит, что запускать его не надо?

const86 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.