Не указывайте пример входного файла. Укажите свой ввод формат файла - по крайней мере, на бумаге или в комментариях - например, в нотации EBNF (поскольку ваш пример текстовый ... это не a двоичный файл ). Решите, должны ли цифры быть в разных строках (или вы можете принять файл с одной огромной строкой, состоящей из миллиона байтов; прочитайте о формате с разделителями-запятыми ). Затем введите код parser для этого формата. В вашем случае вполне вероятно, что достаточно простого анализа рекурсивного спуска (и ваш конкретный парсер даже не будет использовать recursion ).
Узнайте больше о <stdio.h>
и его подпрограммах . Потратьте время, чтобы внимательно прочитать эту документацию. Поскольку ваш ввод текстовый , а не двоичный , вам не нужно fread . Обратите внимание, что входные подпрограммы могут быть неудачными, и вы должны обработать случай сбоя.
Конечно, fopen
может потерпеть неудачу (например, потому что ваш рабочий каталог - это не то, что вы считаете). Вам лучше использовать perror или errno , чтобы узнать больше о причине сбоя. Так по крайней мере код:
infile = fopen("input.dat", "r");
if (infile == NULL) {
perror("fopen input.dat");
exit(EXIT_FAILURE);
}
Обратите внимание, что точки с запятой (или их отсутствие) очень важны в C (без точки с запятой после условия if
). Прочитайте еще раз основной синтаксис C языка . Читайте о Как отлаживать небольшие программы . Включите все предупреждения и отладочную информацию при компиляции (с GCC , компилируйте с gcc -Wall -g
как минимум). Предупреждения компилятора очень полезны!
Помните, что fscanf не обрабатывает конец строки (новую строку) иначе, чем символ пробела. Поэтому, если у входа должны быть разные строки , вам нужно читать каждую строку отдельно.
Вы, вероятно, будете читать каждую строку , используя fgets (или getline ), и анализировать каждую строку в отдельности. Вы можете выполнить этот анализ с помощью sscanf (возможно, %n
может быть полезным) - и вы хотите использовать счетчик возврата sscanf
. Вы также можете использовать strtok и / или strtod для такого анализа.
Убедитесь, что ваш синтаксический анализ и вся ваша программа правильны . На современных компьютерах (они очень быстрые, и большую часть времени ваш входной файл находится в кеше ), весьма вероятно, что он будет достаточно быстрым. Миллион строк может быть прочитан довольно быстро (если в Linux вы можете сравнить время анализа с временем, используемым wc для подсчета строк в вашем файле). На моем компьютере (мощный рабочий стол Linux с процессором AMD2970WX - у него много ядер, но ваша программа использует только один, 64 ГБ ОЗУ и SSD-диск), можно прочитать миллион строк (wc
) менее чем за 30 миллисекунды, поэтому я предполагаю, что вся ваша программа должна выполняться менее чем за полсекунды, если дано миллион строк ввода и если дальнейшая обработка проста (в линейном времени).
Вы, вероятно, заполните большой массив struct O_DATA
, и этот массив, вероятно, должен быть динамически выделен и перераспределен при необходимости. Подробнее о C динамическом выделении памяти . Внимательно прочитайте о C процедурах управления памятью . Они могут потерпеть неудачу, и вы должны справиться с этой ошибкой (даже если это очень маловероятно). Вы, конечно, не хотите перераспределять этот массив в каждом цикле. Вы, вероятно, могли бы выделить его в некоторой геометрической прогрессии (например, если размер этого массива size
, вы будете вызывать realloc
или новый malloc
для некоторых int newsize = 4*size/3 + 10;
только тогда, когда старый size
слишком мало). Конечно, ваш массив, как правило, будет немного больше того, что действительно нужно, но память довольно дешевая, и вам разрешено «потерять» ее.
Но StackOverflow - это , а не сайт "сделай мою домашнюю работу". Я дал несколько советов выше, но вы должны сделать свою домашнюю работу.