Страница 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, то она требует доработки.
Прочитать исходный текстовый файл и сформировать из него массив индексных структур - это правильно, только записывать его нужно не в отдельный файл, а вместе с исходным текстом сохранить в единый файл, где будут представлены и текстовые строки и бинарные индексы.
Ещё в начало этого файла необходимо будет записать специальную заголовочную структуру, содержащую всю техническую информацию для правильного чтения последующих данных.