Разное > Софт и кодинг
C++ или "флудить, так флудить")
nog:
Хм, повторю еще раз:
1. Вместо #include <conio.h> написать #include <stdio.h>
2. Вместо _getch(); getchar();
3. Скомпилировать.
4. Запустить.
5. Радоваться.
_getch() ага, ждет, но conio.h это досовская библиотека, нету её в линуксе.
Желательно скачать и почитать какую-нибудь книжку по синтаксису. Например классику, Страустрап "Язык C++". Джефа Элджера неплохие книжки. Можно почитать Джонсон, Троан "Разработка приложений в Linux". Шилдт неплохо пишет, хотя больше для виндоуса, но разницы в программировании особой нет.
Dajver:
С компиляцией разобрался, активно учу и пишу) Дошёл до работы с файлами и тут возник один щекотливый момент.
Требуется из файла file.txt прочитать текст. Содержимое файла -
Текст1
Текст1 Текст1
Текст1 Текст1 Текст1 Текст1 Текст1 Текст1
Текст2
Текст2 Текст2
Текст2 Текст2 Текст2 Текст2 Текст2 Текст2
и так далее.
Как я понял из учебников - в начале каждого абзаца нужно поставить некий маркер. Потом при обращении к файлу искать этот маркер и выводить текст до следующего маркера.
Вопрос - как именно этот маркер найти? Мне нужно в зависимости от первой строчки абзаца выводитьодин из абзацев. Скажем в файле список фруктов с описанием. Пользователь задаёт в строке значение "яблоко", в файле находится абзац, начинающийся с "яблоко", читается абзац и выводится на экран.
Может немного сумбурно, но как-то так... Заранее всем спасибо)
Andys:
--- Цитата: Dajver от 13 Августа 2012, 23:28:33 ---Требуется из файла file.txt прочитать текст. Содержимое файла ...
--- Конец цитаты ---
Если требуется именно алгоритм. С++ уже не помню, да и времени сейчас не будет конкретную прогу писать.
1. исхожу из того, что
а. нам кто-то дал этот текстовик.
б. текстовик меняется нечасто. как база данных - он есть, а несколько пользователей запрашивают то одно слово, то другое.
2. для облегчения будущих поисков его лучше проиндексировать. Сделать промежуточный файл, в котором будут адреса начал абзацев и ключевое слово. Можно его для простоты (я не считаю что это оптимально, чисто для начала) сделать в формате -
слово1
адрес1
слово2
адрес2
итп...
Заполняется по простому алгоритму -
а. открываешь file.txt в байтовом режиме
б. проверяешь какой конец строки у тебя - односимвольный (\n) или двухсимвольный (\r\n). Если формат оговорен в условии - то не проверяешь...
в. читаешь ключевое слово-строку. пишешь его в индекс-файл без символов конца строки. берешь адрес начала следующей строки (убей не помню как функция называлась, которая возвращаеь текущую позицию в файле), пишешь в тот же индексфайл.
г. читаешь файл пока не будет пустая строка (подряд два символа конца строки, или четыре в зависимости от пункта б).
и в цикле в-г создаешь индекс - чтобы в будущем не просматривать весь исходный файл.
В конце еснно - сохранить файл
И потом основная прога - открывает индекс-файл, читает его (для простоты - в двумерный массив).
Пользователь вводит слово поиска - прога просматривает массив, есть ли такое слово. Если есть - берет соответствующий адрес (который тоже прочитан из того индекса), открывает исходный file.txt, переводит курсор файла (функция fseek, что ли) на соотв. адрес, читает байты пока не найдет конец абзаца (как в предыдущем случае, два конца строки подряд).
Эти байты и будут нужным текстом. Само слово у нас есть из индекса, текст мы прочитали - выводим его и все.
Если исходный file.txt меняется часто (каждый раз), то индекс будет неэффективен, тут просто построчно ищем слово и потом выводим все до пустой строки.
Также для начала можно сделать именно этот простой вариант, просто чтобы попробовать сами функции ввода-вывода. Потом уже, в будущем, заморачиваться индексом итп
п.с. поскольку чтение в байтовом режиме - то делается через буферный массив, типа char[1024], или ещё больше. Прочитал - обрабатываешь проверками посимвольно, конец строки там, или нет.
nog:
Не то чтобы нужно, есть и другие варианты создания простейших таблиц данных ;)
Маркер, любой символ (набор символов), который никогда не будет использоваться в абзацах (во всяком случае не будет первым в строке). Возьми например решетку, текст будет такой:
#Текст1
Текст1 Текст1
Текст1 Текст1 Текст1 Текст1 Текст1 Текст1
#Текст2
Текст2 Текст2
Текст2 Текст2 Текст2 Текст2 Текст2 Текст2
Читаешь первый символ каждой строки, нашел решетку, сравниваешь с ключем. Если совпало, выводишь всё до следующей решетки или конца файла. Если не совпало ищеш следующую.
Можно ключ заключать в квадратные скобки, как делают в ini файлах. Можешь посмотреть на формат xml, но там возможностей слишком много, он больше для хранения древовидных структур произвольных параметров.
Чуть посложнее, но быстрее, как правильно сказал Andys, будет прочитать весь файл в память как массив байт (не забудь выделить память), и потом работать с блоком памяти. Только если у тебя текст в уникоде, не забывай, что нелатинские символы занимают 2 байта.
СпойлерAndys, предлагаешь человеку реализовать cобственный SQL сервер (точнее dbf)? :)
При небольшом количестве записей и размере данных, индексный файл может замедлить обращение к данным. При большой нагрузке лучше индекс строить в памяти при загрузке программы и менять при изменениях. И сам файл можно просто прочитать в память, если конечно file.txt не десяток гиг. Но человек всёже не демона БД пишет.
Вот вопрос с изменениями гораздо серьезнее. Если одновременно могут изменять данные несколько клиентов, тут сначала нужно реализовать блокировку файлов.[свернуть]
New man:
Может быть человек имел ввиду знак EOLN?
вроде символы #10#13
Навигация
Перейти к полной версии