Работа с большими текстовыми файлами в Си

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Ответить
AlexN
Сообщения: 4
Зарегистрирован: 27 окт 2017, 21:58

27 окт 2017, 22:27

Всем привет!

Совсем недавно начал изучать программирование и Си как первый язык.

Появилась вот такая задача:
Есть два текстовых файла, больших, на по 100 000 строк в каждом. Нужно сделать так, чтобы программа брала строку из первого файла, проверяла её на вхождение в строки второго файла и, при наличии совпадения, записывала бы строку из первого файла в третий файл.

Программу, которая делает такое с маленькими фалами (по 10 строчек) я написал. А вот если "скормить" ей те самые большие файлы, то она зависает.

В связи с этим два вопроса:

1. Имеет ли смысл подобную задачу решать на Си? И если нет, то при помощи чего лучше?
2. Есть какая-то особенность при работе с большим колличеством строк? Какая-то защита от переполнения памяти или что-то такое?

Покачто я придумал толко один способ - разбивать эти большие файлы на малнькие и работать с ними, но мне кажется это тупо.

Буду рад любой информации! Спасибо!
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

27 окт 2017, 22:44

AlexN писал(а): 1. Имеет ли смысл подобную задачу решать на Си? И если нет, то при помощи чего лучше?
На всем чем угодно можно. Вы, видимо, выбрали неудачный алгоритм.
AlexN писал(а): 2. Есть какая-то особенность при работе с большим колличеством строк? Какая-то защита от переполнения памяти или что-то такое?
Без разницы. Если в файле 100.000 строк, и каждая строка - 100 символов (допустим), то файлы по 10 Мб. Это смешной объём. Сейчас по несколько Гб на машину ставят.
2B OR NOT(2B) = FF
AlexN
Сообщения: 4
Зарегистрирован: 27 окт 2017, 21:58

27 окт 2017, 22:57

Программа выглядит вот так:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define SIZE 100

void FindString(char String[SIZE])
{
char String1[SIZE], j = 0;
FILE *fFile1, *fResult;
fFile1 = fopen("file1.txt", "r");
while (fscanf (fFile1, "%s", &String1[j]) != EOF)
{
if (strstr (String, &String1[j]) != 0)
{
fResult = fopen("Rresult.txt", "a");
fprintf(fResult, "%s\n", String);
fclose(fResult);
}
j++;
}
fclose(fFile1);
}

int main(int argc, char const *argv[])
{
char String2[SIZE], String1[SIZE], i = 0, FileDoname[SIZE];
FILE *fFile2, *fResult;
fFile2 = fopen(FileDoname, "r");
if (fFile2 == NULL)
{
printf("Error - file not found. Restart the programm and try again\n");
}
else
{
while (fscanf (fFile2, "%s", &String2) != EOF)
{
FindString(&String2);
i++;
}
}
fResult = fopen("Result.txt", "r");
if (fResult == NULL)
{
printf("No matches found\n");
}
else
{
fclose(fResult);
system("Result.txt");
}
return 0;
}



Имеет смысл развивать идею или лучше сразу заново? =)
Готовых решений не нужно, очень интересно самому разобраться. Просто как-то в тупик зашёл и не знаю что дальше делать.
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

27 окт 2017, 23:15

AlexN писал(а):Программа выглядит вот так:



Имеет смысл развивать идею или лучше сразу заново? =)
Готовых решений не нужно, очень интересно самому разобраться. Просто как-то в тупик зашёл и не знаю что дальше делать.

Идеи тут нет. Зачем читать один и тот же файл и тот же файл 100.000 раз? Обычно чтобы проверить входит ли какая-то строка в множество делают хеш. В вашем случае нужно построить хеш по второму файлу, потом идти по первому файлу строчка за строчкой и искать вхождения в хеш.
2B OR NOT(2B) = FF
AlexN
Сообщения: 4
Зарегистрирован: 27 окт 2017, 21:58

27 окт 2017, 23:36

Absurd писал(а): В вашем случае нужно построить хеш по второму файлу, потом идти по первому файлу строчка за строчкой и искать вхождения в хеш.
Благодарю! Отличный совет, вы мне очень помогли!
Absurd
Сообщения: 1213
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

27 окт 2017, 23:47

AlexN писал(а):Благодарю! Отличный совет, вы мне очень помогли!

Если вам нужен был готовый код, то, подозреваю, то, скорее всего, нет.
2B OR NOT(2B) = FF
AlexN
Сообщения: 4
Зарегистрирован: 27 окт 2017, 21:58

27 окт 2017, 23:57

Absurd писал(а):Если вам нужен был готовый код, то, подозреваю, то, скорее всего, нет.
И всётаки да, помогли. Готовый код мне не нужен, мне нужно было направлени куда "копать". Я учусь и мне правда очень интересно написать это самостоятельно.
Аватара пользователя
Duncon
Сообщения: 1974
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

28 окт 2017, 00:04

У тебя внутри цикла ещё каждый раз открытие и закрытие файла на дозапись происходит, велика вероятность что это и вызывает зависание..
[syntax=Delphi] [/syntax]
Ответить