sscanf не двигается, сканируя одно и то же целое число каждый раз

У меня есть строка, содержащая целые числа, и я пытаюсь получить все целые числа в другой массив. когдаsscanf не может найтиint Я хочу, чтобы цикл прекратился. Итак, я сделал следующее:

int i;
int getout = 0;
for (i = 0; i < bsize && !getout; i++) {
    if (!sscanf(startbuffer, "%d", &startarray[i])) {
        getout = 1;
    }
}
//startbuffer is a string, startarray is an int array.

Это приводит к тому, что все элементыstartarray быть первым символом вstartbuffer. sscanf работает нормально, но не переходит к следующему, а просто остается на первой позиции.

Есть идеи, что не так? Благодарю.

 sashoalm30 янв. 2015 г., 11:16
возможный дубликатGet number of characters read by sscanf?

Ответы на вопрос(4)

Это правильное поведение sscanf. Sscanf работает наconst char*, а не входной поток из файла, поэтому он не будет хранить информацию о том, что он использовал.

Что касается решения, вы можете использовать%n в строке формата, чтобы получить количество символов, которые оно уже использовало (это определено в стандарте C89).

напримерsscanf("This is a string", "%10s%10s%n", tok1, tok2, &numChar); numChar будет содержать количество символов, потребляемых до сих пор. Вы можете использовать это как смещение, чтобы продолжить сканирование строки.

Если строка содержит только целые числа, которые не превышают максимальное значение типа long (или long long), используйтеstrtol или жеstrtoll, Остерегайтесь этогоlong Тип может быть 32-битным или 64-битным, в зависимости от системы.

Преобразуйте строку в поток, затем вы можете использовать fscanf для получения целых чисел. Попробуй это. http://www.gnu.org/software/libc/manual/html_node/String-Streams.html

 31 мая 2012 г., 05:33
Интересно, что это было добавлено в POSIX-2008:pubs.opengroup.org/onlinepubs/9699919799/functions/…

Ты прав:sscanf на самом деле не «двигается», потому что двигаться нечего. Если вам нужно отсканировать кучу целых, вы можете использоватьstrtol - он сообщает вам, сколько он прочитал, чтобы вы могли передать следующий указатель на функцию на следующей итерации.

char str[] = "10 21 32 43 54";
char *p = str;
int i;
for (i = 0 ; i != 5 ; i++) {
    int n = strtol(p, &p, 10);
    printf("%d\n", n);
}
Решение Вопроса

Один и тот же указатель строки передается каждый раз, когда вы звонитеsscanf, Если бы это было "переместить" входные данные, он должен был бы перемещать все байты строки каждый раз, что было бы медленно для длинных строк. Кроме того, это будет перемещать байты, которыеweren't отсканированы.

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

int nums_now, bytes_now;
int bytes_consumed = 0, nums_read = 0;

while ( ( nums_now = 
        sscanf( string + bytes_consumed, "%d%n", arr + nums_read, & bytes_now )
        ) > 0 ) {
    bytes_consumed += bytes_now;
    nums_read += nums_now;
}
 14 нояб. 2014 г., 22:58
Я получаю фиктивные значения дляnums_now когдаbytes_consumed == strlen(string) (при последнем вызове, который должен разорвать цикл). Этого тоже следовало ожидать?
 16 нояб. 2014 г., 16:50
Ах ах! Поэтому очень важно, чтобы num_rows былsigned целое число. Это довольно тонко.
 15 нояб. 2014 г., 01:25
@mangledorf Согласноspec, & quot; Если ввод заканчивается до того, как завершено первое преобразование (если оно есть), и при отсутствии соответствующего сбоя, должен быть возвращен EOF. & quot; Это звучит как ноль, по сути, переназначается на отрицательный

Ваш ответ на вопрос