На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Чтение и поиск в больших файлов на Си , Приложение для сканирования
    ОС: любая
    компилятор: Dev C++
    Задача состоит в следующем:

    Добрый день.
    Возникла потребность написания приложения для сканирования.
    Для начала хотя бы наброска этой программы.

    1. Я формирую в 1С файл выгрузки(формат может быть разным, xml или dbf на каком смогу работать в Си), допустим в формате DBF. Файл будет отсортирован по штрих-коду. В первой строчке файла, я думаю указать количество строк.
    Содержащий колонки - Штрих-код, Наименование. Файл достаточно большой, чтобы не грузить его в оперативную память (может достигать 500 тысяч строк).

    2. Далее в приложении которое я хочу написать, вводится путь к файлу.
    3. Последовательно начинают вводиться штрих-коды.
    4. Приложение ищет по штрих-коду - Наименование. И если наименование найдено, то добавляет в массив строку с найденным товаром.

    Я только начал программировать на Си, и у меня не получается разобраться с чтениями из DBF. Если кто-то подскажет, буду очень благодарен ☺.
    Получается я хочу считать из 1й строчки, что у меня 500 тысяч строк в файле. Потом сравнить штрих-код 250000й строчки с введённым. Если введённый штрих-код меньше, то сравнить со 125000й строчкой и т.д.

    Как считать энную строчку из файла DBF?
    Или хотя бы где можно прочитать про это. Попытки поиска меня приводили либо к кускам кода на С++(а мне нужен именно С). Либо к работе с текстовым файлом.
      Цитата ejikbeznojek @
      компилятор: Dev C++

      это не компилятор.
      По всему остальному. Я так понял, что записи в файле отсортированы, иначе без индексного файла поиск будет ну очень долгий. Второе условие - все записи должны иметь фиксированный размер. Тогда функция fseek тебе в помощь.
      Сообщение отредактировано: shm -
        Да, записи сортированы по штрих-коду
        Штрих-код имеет фиксированный размер - 13 символов. Наименование - переменной длинны.

        Получается строчку я выбираю смещением? И смещение идёт всегда горизонтально? (т.е. если есть 2 строчки по 10 байт, а я сместился на 15 байт от начала, то я примерно в середине 2й строчки?)
          Цитата ejikbeznojek @
          Наименование - переменной длинны

          Так не получится. Вычислять вычисления смещения каждой новой строки надо считать предыдущую, а это жутко долго. Для начала конвертируй в файл с фиксированной длиной (остаток строки можно заполнить нулями, пробелами, etc...)

          Добавлено
          Кстати оригинальный DBF (dBase, Paradox) имеет поля фиксированного размера. А у тебя просто какой-то txt получается.
          Сообщение отредактировано: shm -
            Зависит от требуемой производительности. Можно и в csv выгрузить (если можно, с 1С никогда не работал), читать его построчно и каким-нибудь регулярным выражением парсить. Если хочешь побыстрее то нужен индексный файл, лучше даже в виде хэш-таблицы.
              Цитата ejikbeznojek @
              Файл достаточно большой, чтобы не грузить его в оперативную память (может достигать 500 тысяч строк).

              Если предположить среднюю длину строки равной 50 символов, то Вам понадобится:
              ExpandedWrap disabled
                500000 * 50 = 25000000 ≈ 24 Мегабайта

              Не так уж и много.
                Цитата shm @
                Кстати оригинальный DBF (dBase, Paradox) имеет поля фиксированного размера. А у тебя просто какой-то txt получается.

                Насколько я помню, данные произвольно длины хранятся в отдельном MEMO-файле или как-то так, а не в самой DBF-ке. Хотя, что там намутили в 1С — хз. =)
                  Вроде бы какой то результат получился.
                  Я могу вывести все штрих-кода из файла.

                  ExpandedWrap disabled
                    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


                  Но почему то не получается сравнить их с введённым мною через сканф штрих-кодом. Всегда разные, даже если я ввожу штрих-код из тех, что выводит.
                  ExpandedWrap disabled
                    scanf("%s",&str1);
                    ....
                    if (str==str1)
                  Сообщение отредактировано: Qraizer -
                    Цитата ejikbeznojek @
                    if (str==str1)

                    Интересно, а что ты хочешь получить, сравнивая 2 указателя?
                      Получается лучше сравнивать посимвольно?
                      (str[0]==str1[0])&&(str[1]==str1[1])....&&(str[12]=str1[12])


                      Так вроде заработало. Но наверное есть какой-то способ по рациональнее?)
                      Сообщение отредактировано: ejikbeznojek -
                        Есть такая функция strcmp :whistle:
                          M
                          Используем тег [code] для добавления текста программы в пост! Устное предупреждение! Читаем правила!
                            Всем спасибо, вроде всё заработало как надо)
                              Да, нужно было считать и сравнить строки
                              M
                              Бессмысленный некропост на форуме не приветствуется.
                              Предупреждение выдано.
                              Сообщение отредактировано: JoeUser -
                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                              0 пользователей:


                              Рейтинг@Mail.ru
                              [ Script execution time: 0,0497 ]   [ 18 queries used ]   [ Generated: 28.03.24, 18:49 GMT ]