Как я могу получить, сколько байтов sscanf_s прочитал в своей последней операции? - PullRequest
2 голосов
/ 23 июля 2010

Я написал класс для чтения быстрой памяти, который эмулирует те же функции, что и fread и fscanf.

В основном я использовал memcpy и увеличил внутренний указатель для чтения данных, например fread, но у меня есть вызов fscanf_s.Я использовал sscanf_s, за исключением того, что он не говорит мне, сколько байтов он считал из данных.

Есть ли способ определить, сколько байтов sscanf_s прочитано в последней операции, чтобы увеличить внутренний указатель устройства чтения строк?Спасибо!

РЕДАКТИРОВАТЬ:

И примерный формат, который я читаю, таков: |172|44|40|128|32|28|

fscanf отлично читает, как и sscanfЕдинственная причина в том, что если бы это было:

|0|0|0|0|0|0|

Длина была бы другой.Мне интересно, как fscanf знает, куда поместить указатель на файл, а sscanf нет.

Ответы [ 3 ]

7 голосов
/ 23 июля 2010

С scanf и семьей, используйте %n в строке формата.Он не будет ничего читать, но приведет к тому, что количество символов, прочитанных до сих пор (с помощью этого вызова), будет сохранено в соответствующем параметре (ожидается int*).

2 голосов
/ 23 июля 2010

Может быть, я глупый, но я все равно попробую. Из веток комментариев кажется, что все еще есть какое-то заблуждение. Вам нужно знать количество байтов. Но метод возвращает только количество прочитанных полей или EOF.

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

sscanf_s(source, "%d%d"...) 

будет успешным на обоих входах "123 456" и "10 \ t30", которые имеют различную длину. В этих случаях невозможно определить размер, если вы не конвертируете его обратно. Итак: используйте поле фиксированного размера или оставьте в забвении ....

Важное примечание: помните, что при использовании %c это единственный способ включить разделители полей (перевод строки, табуляция и пробел) в вывод. Все остальные будут пропускать границы поля, затрудняя поиск нужного количества байтов.

EDIT:
Из "C ++ The Complete Reference" я только что прочитал:

%n Получает целочисленное значение, равное количество прочитанных символов

Разве это не то, что вы хотели? Просто добавьте его в строку формата. Это подтверждено здесь , но я не проверял его с помощью sscanf_s.

0 голосов
/ 23 июля 2010

Из MSDN:

sscanf_s, _sscanf_s_l, swscanf_s, _swscanf_s_l  

Каждая из этих функций возвращает количество успешно преобразованных и назначенных полей;возвращаемое значение не включает поля, которые были прочитаны, но не назначены.Возвращаемое значение 0 указывает, что поля не были назначены.Возвращаемое значение - EOF для ошибки или если конец строки достигнут перед первым преобразованием.

...