Может ли fscanf () читать пробелы? - PullRequest
6 голосов
/ 23 декабря 2009

У меня уже есть некоторый код для чтения текстового файла с использованием fscanf(), и теперь мне нужно его изменить, чтобы поля, которые ранее были свободными от пробелов, должны разрешать пробелы. Текстовый файл в основном имеет вид:

название: ДАННЫЕ
название: ДАННЫЕ
и т.д ...

который в основном анализируется с использованием fgets(inputLine, 512, inputFile); sscanf(inputLine, "%*s %s", &data);, считывая поля DATA и игнорируя заголовки, но теперь некоторые поля данных должны оставлять пробелы. Мне все еще нужно игнорировать заголовок и пробел сразу после него, но затем прочитать оставшуюся часть строки, включая пробел.

Есть ли способ сделать это с помощью функции sscanf()?

Если нет, то какое наименьшее изменение я могу внести в код для правильной обработки пробелов?

ОБНОВЛЕНИЕ: я отредактировал вопрос, чтобы заменить fscanf () на fgets () + sscanf (), что фактически использует мой код. Я действительно не думал, что это уместно, когда я впервые написал вопрос, поэтому я упростил его до fscanf ().

Ответы [ 6 ]

13 голосов
/ 23 декабря 2009

Если вы не можете использовать fgets(), используйте спецификатор преобразования %[ (с «опцией исключения»):

char buf[100];
fscanf(stdin, "%*s %99[^\n]", buf);
printf("value read: [%s]\n", buf);

Но fgets() намного лучше.


Редактировать: версия с fgets() + sscanf()

char buf[100], title[100];
fgets(buf, sizeof buf, stdin); /* expect string like "title: TITLE WITH SPACES" */
sscanf(buf, "%*s %99[^\n]", title);
3 голосов
/ 23 декабря 2009

Если вы настаиваете на использовании scanf и предполагаете, что хотите использовать символ новой строки в качестве терминатора, вы можете сделать это:

scanf("%*s %[^\n]", str);

Обратите внимание, однако, что вышеприведенное, используемое в точности так, как написано, является плохой идеей, потому что нет ничего, что могло бы защитить от переполнения str (так как scanf не знает его размера). Конечно, вы можете установить предопределенный максимальный размер и указать его, но тогда ваша программа может работать некорректно на некоторых допустимых входных данных.

Если размер строки, как определено форматом ввода, не ограничен, то ваш единственный практический вариант - использовать fgetc для чтения данных char по char, периодически перераспределяя буфер по мере продвижения. Если вы сделаете это, то измените его, чтобы отбрасывать все символы чтения до тех пор, пока первый пробел не станет достаточно тривиальным.

3 голосов
/ 23 декабря 2009

Самое простое было бы выдать

fscanf("%*s");

чтобы отказаться от первой части, а затем просто вызвать fgets:

fgets(str, stringSize, filePtr);
3 голосов
/ 23 декабря 2009

Я настоятельно рекомендую вам прекратить использовать fscanf() и начать использовать fgets() (который читает целую строку), а затем проанализировать прочитанную строку.

Это позволит вам значительно больше свободы при разборе не точно отформатированного ввода.

2 голосов
/ 23 декабря 2009

Спецификатор %s в fscanf пропускает любые пробелы на входе, затем читает строку символов, не являющихся пробелами, вплоть до следующего пробела, не включая его.

Если вы хотите прочитать до новой строки, вы можете использовать %[^\n] в качестве спецификатора. Кроме того, символ '' в строке формата пропустит пробел на входе. Так что если вы используете

fscanf("%*s %[^\n]", &str);

он прочитает первое в строке до первого пробела («title:» в вашем случае) и выбросит его, затем прочитает пробелы и выбросит их, затем прочтет все символы до перевод строки на str, которая звучит как то, что вы хотите.

Будьте осторожны, чтобы str не переполнялся - вы можете использовать

fscanf("%*s %100[^\n]", &str)

для ограничения максимальной длины строки, которую вы будете читать (100 символов, не считая здесь завершающего NUL).

1 голос
/ 23 декабря 2009

Вы бежите за пределы того, для чего хороша семья *scanf. С довольно минимальными изменениями вы можете попробовать использовать модули сканирования строк из C интерфейсов и реализаций Дейва Хэнсона . Этот материал представляет собой модификацию языка программирования Icon , чрезвычайно простого и мощного языка обработки строк, над которым Хансон и другие работали в Аризоне. Отклонение от sscanf не будет слишком серьезным, оно будет проще, проще в работе и более мощным, чем регулярные выражения. Единственным недостатком является то, что без книги трудно следовать коду - но если вы много программируете на С, книга стоит того, чтобы ее иметь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...