Страница 2 из 2
Re: Файловый вывод
Добавлено: 07 апр 2016, 14:14
Kazanove
Да было именно дело в переменной
i. заработало
переделал под считывание целой строки, а потом разбираю на столбцы
Код: Выделить всё
while ((fgets(arr, 100, pFile) != NULL)){
istr = strtok(arr, "|");
j = 0;
while (istr != NULL){
switch (j){
case 0:
strcpy(book[i].UDK, istr);
break;
case 1:
strcpy(book[i].FullName, istr);
break;
case 2:
strcpy(book[i].BookName, istr);
break;
case 3:
book[i].cost = atof(istr);
break;
case 4:
book[i].quantity = atoi(istr);
break;
default:
break;
}
istr = strtok(NULL, "|");
j++;
}
i++;
}
да так немного проще
Re: Файловый вывод
Добавлено: 07 апр 2016, 14:42
Romeo
В памяти структура заполнена правильно. А вот ту первую строку, которая тебя смущает, формирует вот этот код:
Код: Выделить всё
case 0:
printf("%s", istr); // ВОТ ЭТОТ!
strcpy(book[i].UDK, istr);
break;
Если бы ты в дебагере во время пошагового выполнения программы переключился бы в консоль и посмотрел, что и в какой момент туда выводится, то ты бы это и сам понял

Re: Файловый вывод
Добавлено: 07 апр 2016, 15:54
Kazanove
а можно прочитать определенную строку из файла (к примеру 2-ю строку) не читая весь файл?
или нужно все ровно загружать построчно (через цикл) и когда дойду до той строки которая мне нужно,просто выйти из цикла?
и можно ли прочитать файл с конца в начало?
или же опять прочитать файл в массив, а массив перевернуть?
Re: Файловый вывод
Добавлено: 07 апр 2016, 21:02
Decoder
Прочитать вторую строку с начала файла довольно просто. Достаточно всего два раза вызвать функцию fgets() и дальше можно не читать. Читать файл с конца в начало в принципе тоже можно, но только если заранее знаешь, сколько байт тебе нужно отступать от конца файла. Иначе овчинка выделки не стоит, только усложнишь себе задачу.
Re: Файловый вывод
Добавлено: 08 апр 2016, 00:28
Romeo
Надеюсь, ты понимаешь, что понятие "строка" существует только в текстовом редакторе (который открывает и вычитывает весь файл в момент запуска, так что может посчитать переводы кареток во всём тексте).
По факту же, все функции, которые читают данные из файла, не могут сразу переходить на строку с определённым номером, так как пока байты из файла не извлечены, определить где заканчивается одна строка и начинается следующая невозможно.
Если же ты знаешь линейную позицию символа в файле (то есть номер байта от начала файла, к которому нужно перейти), то тогда ты действительно можешь пропустить все предыдущие байты, вызвав
fseek.
Из этого, кстати, сам собой напрашивается вывод. Если ты будешь дополнять все строки в своём файле пробелами так, чтобы они все были гарантированной длины, то ты без проблем сможешь вычислять необходимые смещения от конца файла и как бы "бегать" по строкам с помощью fseek.
Код: Выделить всё
1234 |safdasdf |sadfsda |333,00 |2 |
1234 |asdff |sadfasdf |3334,00 |12 |
1233 |qweerr |sadfsgad sadgsdfg |233,00 |3244 |
12344 |wqerasdfasdf |sadfasd asdf asdf adsf |123456,00 |123 |
Код: Выделить всё
// Opening of the file.
FILE* fl = fopen(...);
// Line number that must be read (0-based).
int line_number = 3;
// 64 symbols in one line, plus 2 system sybmols for line returning (0xD, 0xA - carriage return and line feed).
// And all this stuff is to be multiplied by the number of lines.
int offset = (64 + 2) * line_number;
// Move file pointer to the calculated position.
fseek(fl, offset, SEEK_SET);
// Read 3-th line.
fgets(..., fl);
Re: Файловый вывод
Добавлено: 08 апр 2016, 09:55
WinMain
Есть другой способ: если сам программно пишешь строки в текстовый файл, то можно параллельно записывать смещения и длины строк в отдельный индексный файл. Т.е. это бинарный файл, в котором будут последовательно записаны структуры типа
Код: Выделить всё
typedef struct STRING_INDEX_STRUCT
{
long offset; // смещение внутри файла
long length; // длина строки
} STRING_INDEX;
В этом случае у тебя будет полная информация о расположении текстовых строк внутри файла, соответственно появится возможность читать строки из файла в произвольном порядке.
Если же у тебя нет такого индексного файла, то его можно будет создать с помощью несложной утилитки, которая будет предварительно читать "сырой" текстовый файл построчно и записывать в индексный файл информацию о расположении строк.
Re: Файловый вывод
Добавлено: 08 апр 2016, 11:02
Romeo
Ну, наверное, это не самый удачный приём, хотя он и имеет право на жизнь. Дело в том, что он представляет собой нечто среднее между двумя крайностями - чисто текстовым подходом (медленное позиционирование, но возможность править файл руками) и чисто бинарным подходом (быстрое позиционирование, но отсутствие возможности править руками). Включал бы предложенный метод плюсы от двух крайностей - цены бы ему не было. Но он включает только минусы, так как файл руками не поправишь, но при этом позиционирование не такое быстрое, как у чисто бинарного подхода, и, ко всеми прочему, ещё и нужен какой-то дополнительный файл, постоянно нуждающийся в обновлении.
Для того, чтобы решить, каким подходом лучше всего пользоваться, предлагаю в первую очередь определить нужна ли тебе возможность править файл базы данных руками. Если нужна - то используй чисто текстовый подход. Если не нужна - чисто бинарный. Промежуточные подходы, как показывает практика - от лукавого
P.S. Если что, под чисто бинарным подходом я подразумеваю оперирование данными с помощью
fread/
fwrite.
P.P.S. И если уж совсем о правильных вещах говорить, то для работы с базами данных наиболее правильным выходом будет использование готовых решений, коих в интернете масса (например
SQLite). Но это уже потом, когда накопишь опыт. На данный момент реализуемая задача более, чем соответствует своим целям - натренировать начинающего программиста.
Re: Файловый вывод
Добавлено: 08 апр 2016, 12:19
WinMain
Предложенный мной вариант взят из реальной жизни. К примеру база данных формата dBase (расширение .DBF) В нём каждая таблица по сути является текстовым файлом, у которого все записи являются строками фиксированной длины. Там лишь заголовок бинарный. Но к нему так же прилагается индексный файл для поиска записей через отсортированный массив ключевых значений. Ещё прилагаются файлы с массивами данных типа BLOB и МЕМО. Понятно, что руками эти файлы не редактируют (хотя лет 25-30 назад наверно и такой способ тоже имел место), и появилась эта система очень давно, однако ведь она до сих пор существует.
Re: Файловый вывод
Добавлено: 08 апр 2016, 12:37
Romeo
Это уже описан классический индекс-файл. Он используется для ускорения поиска. В файле хранятся не просто смещения строк. Хранимые значения ещё и пересортированы в таком порядке, чтобы соответствующие им строки из исходного файла шли по алфавиту. В таком случае смысл в индексном файле конечно же есть. Более того, собственно, это то, для чего индексные файлы и используются в базах данных.
А вот использовать индексный файл просто для того, чтобы хранить смещения строк в том порядке, в котором они идут в исходном файле - смысла не много.
Re: Файловый вывод
Добавлено: 10 апр 2016, 10:15
Decoder
В общем вывод можно сделать такой: использовать текстовый файл для хранения структурированных данных конечно можно, но как промежуточный формат для экспорта-импорта данных из разных приложений.
Например: если в качестве разделителя столбцов использовать символ ; (точка с запятой), а расширение файла поменять с TXT на CSV, то этот файл можно открыть как таблицу при помощи Microsoft Excel или Libre Office Calc.
Числовые данные в текстовом файле так же представлены в виде текста. Это удобно для их отображения в разных таблицах и отчётах, но для математической обработки данных их необходимо преобразовывать в числа.
Если представлять все записи в виде строк фиксированной длины, то почти половина файла будет заполнена пробелами, что не оптимально с точки зрения размеров файла и выделения памяти.
Что же касается идеи, которую предложил WinMain, то она требует доработки.
Прочитать исходный текстовый файл и сформировать из него массив индексных структур - это правильно, только записывать его нужно не в отдельный файл, а вместе с исходным текстом сохранить в единый файл, где будут представлены и текстовые строки и бинарные индексы.
Ещё в начало этого файла необходимо будет записать специальную заголовочную структуру, содержащую всю техническую информацию для правильного чтения последующих данных.