Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > C/C++: Общие вопросы > Чтение и поиск в больших файлов на Си |
Автор: ejikbeznojek 16.06.14, 11:19 |
ОС: любая компилятор: Dev C++ Задача состоит в следующем: Добрый день. Возникла потребность написания приложения для сканирования. Для начала хотя бы наброска этой программы. 1. Я формирую в 1С файл выгрузки(формат может быть разным, xml или dbf на каком смогу работать в Си), допустим в формате DBF. Файл будет отсортирован по штрих-коду. В первой строчке файла, я думаю указать количество строк. Содержащий колонки - Штрих-код, Наименование. Файл достаточно большой, чтобы не грузить его в оперативную память (может достигать 500 тысяч строк). 2. Далее в приложении которое я хочу написать, вводится путь к файлу. 3. Последовательно начинают вводиться штрих-коды. 4. Приложение ищет по штрих-коду - Наименование. И если наименование найдено, то добавляет в массив строку с найденным товаром. Я только начал программировать на Си, и у меня не получается разобраться с чтениями из DBF. Если кто-то подскажет, буду очень благодарен ☺. Получается я хочу считать из 1й строчки, что у меня 500 тысяч строк в файле. Потом сравнить штрих-код 250000й строчки с введённым. Если введённый штрих-код меньше, то сравнить со 125000й строчкой и т.д. Как считать энную строчку из файла DBF? Или хотя бы где можно прочитать про это. Попытки поиска меня приводили либо к кускам кода на С++(а мне нужен именно С). Либо к работе с текстовым файлом. |
Автор: shm 16.06.14, 11:29 |
это не компилятор. По всему остальному. Я так понял, что записи в файле отсортированы, иначе без индексного файла поиск будет ну очень долгий. Второе условие - все записи должны иметь фиксированный размер. Тогда функция fseek тебе в помощь. |
Автор: ejikbeznojek 16.06.14, 11:36 |
Да, записи сортированы по штрих-коду Штрих-код имеет фиксированный размер - 13 символов. Наименование - переменной длинны. Получается строчку я выбираю смещением? И смещение идёт всегда горизонтально? (т.е. если есть 2 строчки по 10 байт, а я сместился на 15 байт от начала, то я примерно в середине 2й строчки?) |
Автор: shm 16.06.14, 11:40 |
Так не получится. Вычислять вычисления смещения каждой новой строки надо считать предыдущую, а это жутко долго. Для начала конвертируй в файл с фиксированной длиной (остаток строки можно заполнить нулями, пробелами, etc...) Добавлено Кстати оригинальный DBF (dBase, Paradox) имеет поля фиксированного размера. А у тебя просто какой-то txt получается. |
Автор: Step 16.06.14, 13:18 |
Зависит от требуемой производительности. Можно и в csv выгрузить (если можно, с 1С никогда не работал), читать его построчно и каким-нибудь регулярным выражением парсить. Если хочешь побыстрее то нужен индексный файл, лучше даже в виде хэш-таблицы. |
Автор: Kray74 16.06.14, 15:45 |
Цитата ejikbeznojek @ Файл достаточно большой, чтобы не грузить его в оперативную память (может достигать 500 тысяч строк). Если предположить среднюю длину строки равной 50 символов, то Вам понадобится: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> 500000 * 50 = 25000000 ≈ 24 Мегабайта Не так уж и много. |
Автор: korvin 16.06.14, 16:53 |
Цитата shm @ Кстати оригинальный DBF (dBase, Paradox) имеет поля фиксированного размера. А у тебя просто какой-то txt получается. Насколько я помню, данные произвольно длины хранятся в отдельном MEMO-файле или как-то так, а не в самой DBF-ке. Хотя, что там намутили в 1С — хз. =) |
Автор: ejikbeznojek 17.06.14, 10:52 |
Вроде бы какой то результат получился. Я могу вывести все штрих-кода из файла. <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> char str[50],mystr[50]; int i; printf ("Opening file\n"); mf=fopen ("myfile/boxes.DBF","r+"); for(i=0;i<15;i++) { ////////////// ШК1 if (fseek (mf,209+i*111,SEEK_SET)==0) printf ("Search text complete\n"); else printf ("Error search\n"); printf ("Reading: "); if (fgets (str, 14, mf)==NULL) printf ("Read error\n"); else printf ("%s\n",str); ////////////// ШК 1 Но почему то не получается сравнить их с введённым мною через сканф штрих-кодом. Всегда разные, даже если я ввожу штрих-код из тех, что выводит. <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> scanf("%s",&str1); .... if (str==str1) |
Автор: shm 17.06.14, 10:55 |
Интересно, а что ты хочешь получить, сравнивая 2 указателя? |
Автор: ejikbeznojek 17.06.14, 11:13 |
Получается лучше сравнивать посимвольно? (str[0]==str1[0])&&(str[1]==str1[1])....&&(str[12]=str1[12]) Так вроде заработало. Но наверное есть какой-то способ по рациональнее?) |
Автор: Kray74 17.06.14, 11:35 |
Есть такая функция strcmp |
Автор: Qraizer 17.06.14, 11:56 |
M Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила! |
Автор: ejikbeznojek 17.06.14, 13:31 |
Всем спасибо, вроде всё заработало как надо) |
Автор: Artemonchik 28.01.16, 22:00 |
Да, нужно было считать и сравнить строки M Бессмысленный некропост на форуме не приветствуется. Предупреждение выдано. |