Up_CrossYourHeart Ответов: 2

Не в состоянии понять поведение 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 ) )
{
... / / технологическая линия здесь
}

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

2 Ответов

Рейтинг:
1

Arthur V. Ratz

Наверное, вам стоит попробовать вот это:

while(fgets(line,256,processed_fp))
{
  strcpy(copy_line,line);
  printf("%s\n",line);
  printf("%s\n",copy_line);
  // Remove processing and try to run this code
}


Рейтинг:
0

Patrice T

Язык C не установлен, это означает, что при доступе к массивам он не проверяет, находитесь ли вы в массиве. Иначе говоря, пока вы находитесь в своем пространстве памяти, вы можете делать все, что угодно.

char line[128];
processed_fp = fopen("processed.txt","r");
while(fgets(line,256,processed_fp))

Это совершенно законно в C но очень опасно так как любая строка длиннее 127 будет мусорить память после выделенного ей места line. Это начало материи-это пространство после того, как line используется, потому что переменные после line внезапно меняют значение без причины.
Ваше сообщение об ошибке появляется, когда ОС обнаруживает, что вы собираетесь писать в пространство памяти, которое не является вашим.

Вы должны научиться использовать отладчик как можно скорее. Вместо того чтобы гадать, что делает ваш код, пришло время увидеть, как он выполняется, и убедиться, что он делает то, что вы ожидаете.

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.
В отладчике нет никакой магии, он не находит ошибок, он просто помогает вам. Когда код не делает того, что ожидается, вы близки к ошибке.