2015-10-20 3 views
-1

Мне нужно прочитать файл до его конца, но он прерывается до конца. Вот мой файл;fgets() не продолжается до конца файла во время цикла

8378749330196451143 7761927347639996843 
3597172149842452783 2722311582032048570 
6413963814675220040 151985128848019557 
2797849130305409931 7006855242872793130 
2312483514986641752 4723009976223322840 
6299327914512777856 8560986736619134288 
7840374864908954188 6413325942318176938 
7120263339634576853 5721019237600873947 
4064508404151769878 8332513917413808407 
1131946326472490896 8768732125304950625 
2593825059274639432 4898919688177170005 
1152428805919273221 4955899780218674181 
4762291655892416501 1286985264509566046 
1098025338340897985 4952984927278789363 
2524421559647997815 8843945302342585201 

Я использую эту часть кода для получения линий;

file = fopen (buffer, "r"); 
    if (file != NULL){ 
      while (fgets (line, sizeof line, file) != NULL) { 
       // Token will point to the part before the =. 
       pairs[i].key = strdup(strtok(line, search)); 
       // Token will point to the part after the =. 
       pairs[i].value = strdup(strtok(NULL, search)); 

       i++; 
       } 
    } 

Это работает, но не до конца. После прочтения части ниже, когда контур цикла завершен. Что может быть причиной этого? Каждая строка заканчивается символом \ n.

8378749330196451143 7761927347639996843 
3597172149842452783 2722311582032048570 
6413963814675220040 151985128848019557 
2797849130305409931 7006855242872793130 
2312483514986641752 4723009976223322840 
6299327914512777856 8560986736619134288 
7840374864908954188 6413325942318176938 
7120263339634576853 572101923 

Примечания: Я получил скриншот редактора, который показывает знаки

enter image description here

+1

Dunno. Вероятно, вы должны отладить его. –

+0

Когда я сделал минимальный пример из опубликованной вами информации, сделав разумные предположения о том, что код не показан, он работает. Таким образом, ваша проблема кроется в другом месте, или в строке слишком короткой, или 'strdup' или' strtok' возвращает 'NULL', или' search', не включая всех возможных ограничителей. Как всегда, вы ** должны ** размещать MCVE, который позволяет комментаторам реплицировать проблему. –

+0

Примечание OP продолжается из ранее заданного вопроса http://stackoverflow.com/questions/33201531/values-stays-the-same-after-updating-a-struct-array-value –

ответ

4

EDIT 2

Вашего previous question по этой теме означает, что вы обрабатываете данные из файла 1000 строк, в то время, для каждого из этих 1000 строк вы называете strdup дважды (один раз для каждого поля данных в текстовой строке). Вы также сказали: «У меня есть файл, который содержит 2^32 пары ключ/значение».

Для каждого из них вы вызываете strdup дважды, один раз для каждого поля данных. Теперь strdup выделяет память для хранения строки, которую вы хотите дублировать. С вашим огромным количеством данных это огромный объем памяти, и программа измельчается из-за ее отсутствия.

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

for (i=0; i<1000; i++) { 
    free(pairs[i].key); 
    free(pairs[i].value); 
} 

Практически целесообразно проверить возвращаемое значение любой функции библиотеки, которая возвращает значение ошибки. В случае strdup, который скажет вам, что у вас закончилась нехватка памяти. В случае strtok вы узнаете, что строка с изгоями находилась в файле, который вы не можете интерпретировать, - возможно, пустая строка в конце файла, заканчивающаяся newline.

Во-вторых, комментарии в этом предыдущий вопрос показывают, что char line [c]

определяется как 41 полукокса, потому что каждая моя линия может быть максимум 41.

Теперь, есть 20 десятичных цифр максимум в 64-бит unsigned int. Два из них плюс space составляют 41. Как насчет терминатора строк? А как насчет newline, который обычно будет на конце ввода, полученном fgets?Я предлагаю вам изменить ваше определение c (вы никогда не показывать) на что-то вроде

#define c 50 

, поскольку нет никаких оснований быть натянуты с одной длиной строки. Когда вы вызываете strdup, это будет выделять достаточно памяти для длины строки + терминатора, так что это не большая потеря памяти.

+1

'c' должно быть в _least_ 43. +1 для' '\ 0''. См. [Комментарий] (http://stackoverflow.com/questions/33243170/fgets-doesnt-continue-until-to-the-end-of-the-file-in-the-while-loop?noredirect1_comment54294494_33243170) – chux

+0

@ спасибо спасибо, я думал, что когда предыдущий вопрос был задан, но забыл. Теперь пересмотрен весь ответ. –

1

Это программа, которая корректно считывает данные из файла -

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 

struct data{ 
    char *key; 
    char *value; 
}pairs[20]; 

int main(void) { 
    FILE *fp; 
    int i=0; 
    char line[255],search[2]=" "; 
    char *token; 
    fp=fopen("Results.txt","r"); 
    if(fp!=NULL){ 
     while(fgets(line,sizeof line,fp)!=NULL){   // read from file 
     pairs[i].key=NULL;    // setting to NULL 
     pairs[i].value=NULL;    // setting to NULL 
     token=strtok(line, search); 
     if(token!=NULL){    // check its return 
       pairs[i].key = strdup(token); 
      } 
     token=strtok(NULL, search); 
     if(token!=NULL){   // check its return    
      pairs[i].value = strdup(token); 
     }    
     if(pairs[i].key!=NULL && pairs[i].value!=NULL)  //check return from strdup 
       printf("%s %s\n",pairs[i].key,pairs[i].value); //print values 
      i++; 
     } 
    } 
    for(int j=0;j<i;j++) { 
     free(pairs[i].key); 
     free(pairs[i].value); 
    } 
    fclose(fp); 
} 

Я Жду» Знать свои заявления, соответственно.

+0

@WeatherVane Добавлено :-) – ameyCU

+0

Думаю, вам нужно предпринять прерывистое действие на 'NULL', а не пропустить. Массив 'pairs' может не содержать' NULL', поскольку с предыдущего вопроса OP (см. Выше комментарий) он, вероятно, перерабатывает массив. –

+0

@WeatherVane Но я проверяю 'return'' strdup', который возвратит 'NULL' при ошибке, независимо от предыдущих данных. Так что это не должно быть проблемой. Исправьте меня, если я ошибаюсь :-) – ameyCU