| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > fscanf как работает? |
| Автор: nns2009 14.2.2009, 13:17 | ||
| У меня программа должна уметь сохранять, а через некоторое время читать информацию из файла в формате .csv(значения разделённые ;). (Чтобы можно было через Excel открывать). В файле хранится: версия программы, количество типов содержимого ячеек таблицы, типы содержимого ячеек таблицы, размер таблицы, таблица В общем, пример содержимого файла я прикрепил. Его создаёт такой код
Вопрос в том, как можно произвести обратное действие? 1. Можно построчно читать файл и разбирать строки на составляющие вручную. 2. Думаю с помощью функции fscanf() это можно реализовать удобнее, но как? На сколько я понял сканф останавливает сканирование как только находит пробел и уже при первом вызове, строка, которую он создаёт, содержит только один символ "V"(что для меня не очень удобно). |
| Автор: andrew_121 14.2.2009, 18:31 | ||
Не верно! |
| Автор: Earnest 15.2.2009, 16:44 |
| csv-файл удобнее всего читать построчно и разбирать каждую строку на лексемы, разделеные заданным символом (;). Это элементарно написать самому, но есть и готовые функции, нарпимер strtok. А уже отдельные слова интерпретировать вообще пустяк. scanf удобно использовать тогда, когда формат абсолютно фиксирован и точно известен. |
| Автор: Earnest 16.2.2009, 18:15 |
Если есть "кол-во данных", а потом "данные" в этом самом количестве, то нет. Как ты формат для scanf запишешь, если во время компиляции неизвестно сколько "данных" читать? Ну то есть можно поизвращаться, но разбор на лексемы проще и нагляднее по результирующему коду. |
| Автор: nns2009 16.2.2009, 23:07 | ||||||
Но ведь по идее данные серавно читаются в цикле, даже если их известное количество изначально, а внутренняя часть цикла одинакова для известного числа чтений:
Можете привести пример кода(с использованием fscanf()), который читает данные из файла, созданного функцией SaveTable() (в моём первом сообщении) для определённого числа данных, предположим трёх. |
| Автор: inside_pointer 17.2.2009, 13:37 |
| через strtok |
| Автор: inside_pointer 17.2.2009, 13:39 | ||
вывод
|
| Автор: inside_pointer 18.2.2009, 05:06 | ||
| подредактировал чтобы читала построчно и разбирала каждую строку через strtok вывод
ни strtok ни fscanf не могут залезть между ;; и вывести, что там ничего нет, если юзать fscanf, её работа будет сведена к посимвольному разбору (то есть то же самое, что просто символы анализировать); многие путают и думают что fscanf это обратный аналог к fprintf, на самом деле это совершенно различные функции и их следует изучать по отдельности, иначе будет путаница |
| Автор: Earnest 18.2.2009, 10:50 | ||
strtok может, а вот scanf действительно нет. |
| Автор: nns2009 19.2.2009, 15:35 | ||||||
Я тоже так думал. А есть ли тогда обратный аналог fprintf();
На сколько я понял strtok(); возвращает строку до разделителя, а в строке, переданной через параметр, обрезает её с разделителем
А зачем эти функции были написаны? А также зачем вот это: Print(""); |
| Автор: inside_pointer 20.2.2009, 05:36 | ||||
новая версия теперь через fscanf (сохраняет лексемы в массив, выводит пустоты как пустоты)
strtok не может пролезть между ;;;, т.к. она вместо каждого разделителя записывает нуль-символ и переводит указатель поиска на следующую лексему после него, если встречает конец строки возвращает нулевой указатель Добавлено через 2 минуты и 11 секунд
она может вывести что угодно, то есть множество обратных аналогов стремится к бесконечности, потому наверное и нету |
| Автор: inside_pointer 20.2.2009, 06:08 |
| там баг с последним значением |
| Автор: Earnest 20.2.2009, 10:59 | ||
Бог ты мой какие сложности! |
| Автор: math64 20.2.2009, 11:51 |
| strtok() заменяет разделители нулями, поэтому если есть разные разделители, невозожно определить какой он был. Кроме того, он портит исходную строку, поэтому иногда её нужно предварительно скопировать. Другие функции, которые можно использовать вместо неё для поиска разделителей: strspn(), strcspn(), strchr(), strstr() |
| Автор: Earnest 20.2.2009, 12:14 | ||
Это правда, но здесь-то разделитель один... |
| Автор: inside_pointer 21.2.2009, 03:24 | ||
она за один шаг проскакивает все повторы, заменяет их нулями, если учесть вычисление разности адресов
strtok возвращает адрес символа o, а у себя там сохраняет адрес символа t (заменив все разделители нулями), при следующем вызове вернёт адрес символа t, а сохранит адрес нуль-символа (из-за которого и вернёт потом NULL и так всё время) ясно, как через strtok, но я хочу через sscanf попробовать, потому что весь файл читать через fscanf неправильно, даже если она всё правильно будет учитывать при переводах, так как строки имеют единый формат; нужно писать функцию по обработке одной строки про strstr тоже неясно, вместо strchr юзать её ? |
| Автор: inside_pointer 21.2.2009, 05:15 | ||
| здесь с sscanf вывод
|
| Автор: nns2009 27.2.2009, 23:27 |
| А какие бывают форматы в функциях fscanf(), sscanf() и подобных? |
| Автор: inside_pointer 28.2.2009, 03:00 |
| printf http://bookc.narod.ru/bb12.html scanf http://bookc.narod.ru/bb13.html хорошо написано всё, но в самой книге не хватает страниц (по крайней мере в бумажной у меня хоть и были несколько утеряных строк или ошибки печати, но вот чтобы страниц не было - это нонсенс) |
| Автор: nns2009 7.3.2009, 16:45 |
| Спасибо всем, теперь всё правильно читает. Реализовал с помощью fscanf(); |