Не в состоянии понять поведение fgets
В моем коде я читаю process.txt файл. Я знаю, что processed.txt имеет 1 миллион строк. Каждая строка представляет собой некоторую перестановку всех чисел от 1 до 31. Теперь, когда я пытаюсь прочитать файл в функции readfile, он дает количество строк 1 миллион, что правильно.
void readfile() { FILE * processed_fp; int no_line = 0; char line[256]; processed_fp = fopen("processed.txt","r"); while(fgets(line,256,processed_fp)) { fprintf(stdout,"%s",line); no_line ++; } printf("No of lines read:%d\n",no_line); fclose(processed_fp); }
Я пытаюсь прочитать этот файл и вычислить количество инверсий по сравнению с query.txt.
int * getMinInversion(int * query) { int curr_inv; int * result= malloc(sizeof(int)*10); memset(result,-1,sizeof(int)*10); int idx = 0; char copy_line[256]; FILE * processed_fp; int no_line = 0; char line[256]; processed_fp = fopen("processed.txt","r"); int * candidate = malloc(sizeof(int)*ARR_SIZE); int * subs = malloc(sizeof(int)*ARR_SIZE); if (candidate == NULL) { printf("Could not allocate candidate memory\n"); exit(EXIT_FAILURE); } if (subs == NULL) { printf("Could not allocate substitution memory\n"); exit(EXIT_FAILURE); } if (processed_fp == NULL) { printf("Could not open the processed file\n"); exit(EXIT_FAILURE); } while(fgets(line,256,processed_fp)) { strcpy(copy_line,line); printf("%s\n",line); printf("%s\n",copy_line); loadintarray(candidate,copy_line); substitution(candidate,query,subs); curr_inv=brute_inversion(subs); if (curr_inv<min_inv) {="" min_inv="curr_inv;" result[idx]="no_line;" idx++;="" }="" else="" if="" (curr_inv="=" min_inv)="" no_line++;="" printf("processed="" %d\n",no_line);="" fclose(processed_fp);="" return="" result;="" <="" pre="">
Что я уже пробовал:
Теперь, когда я вызываю функцию getMinInversion, обработанное число увеличивается до 1000381. Я не в состоянии понять, как может обработанный идти выше 1 миллиона. Кроме того, когда исполнение доходит до последней строки processed.txt файл есть ошибка сегментации. Я не в состоянии понять свою ошибку.
Kornfeld Eliyahu Peter
Может быть, у вас есть строки длиннее 256 символов?
Daniel Pfeffer
Другие вещи, которые нужно проверить:
1. каково определение ARR_SIZE? (по вашему описанию, это должно быть не менее 31)
2. результат-массив из 10 элементов. Вы уверены, что " idx " не может превысить 9?
3. убедитесь,что массив "запрос" имеет тот размер, который вы ожидаете.
...
Если все остальное не удается, попробуйте пройти через код с помощью отладчика. Посмотрите, являются ли результаты тем, что вы ожидаете на каждом этапе.
Up_CrossYourHeart
Да, результат массива выходил за пределы индекса 9, что и вызывало ошибку.Рядом с loadintarray была функция strsep, которая работала с переменной line, которая также путала количество строк, которые считывались.
Peter_in_2780
Конец вашего кода кажется искаженным, поэтому я не могу прочитать, что происходит. У меня возникло бы искушение перестроить его вот так:
...
while(fgets(line, 256, processed_fp))
{
do_whatever_you_want_with(строка);
no_line ++;
}
...
Другими словами, отделите обработку строки от цикла get-and-count-a-line. Это значительно облегчит понимание того, что происходит.
Up_CrossYourHeart
Да, я понял, что именно поэтому я реструктурировал код. Прямо сейчас я смог решить эту проблему. Индекс в результате выходил за пределы 9, что и вызывало проблему. Кроме того, в функции loadintarray функция strsep работала с переменной line, которая путалась с количеством строк, считываемых из файла.
Rick York
Один комментарий: у вас есть массив символов из 256. В вызове fgets вы передаете номер 256. Что происходит, когда вы решаете, что у вас может быть строка, скажем, 400 байт? Ответ заключается в том, что вам придется изменить 256 на 400 или 500 в двух местах. По этой причине лучше всего рассматривать такие магические значения как константу и объявлять их как одно: const size_t LineSize=256; или что-то в этом роде. Мое личное предпочтение это:
const size_t LineSize=255;
char lineBuffer[LineSize+1];
...
while (fgets( lineBuffer, LineSize, fp ) )
{
... / / технологическая линия здесь
}
Плюс один в объявлении буфера предназначен для завершающего нулевого байта. Я предпочитаю ставить плюс один там вместо того, чтобы иметь минус один везде, где используется этот конкретный размер.