2016-11-20 9 views
2

파일을 읽을 때 매우 긴 줄에 동적으로 메모리를 할당하는 방법을 배우려고합니다. 나는 여기와 웹에서 검색하고 몇 가지 코드를 시도했다. 내가 파일을 읽을 때동적으로 텍스트 파일에서 한 줄 읽음

char line[256]; 
file = fopen(inputFileName, "r"); 
// Here, of course I checked file is opened or not. 
while (fgets(line, sizeof(line), file)) { 
    // do some operations 
} 
// Closing operations 

이 나를 위해 작동합니다

첫째, 여기 내 첫 번째 비 동적 코드입니다. 그러나 여기에 선은 255 자 이하 여야합니다. 그래서 예를 들어 300 자 길이의 파일을 파일에서 읽으 려합니다.

나는 다음 코드를 시도 :

size_t maxl = 256; 
//char line[256]; 
char *line = malloc(maxl * sizeof(char)); 
if(!line){ 
    printf("Memory not allocated!!\n"); 
    return -2; 
} 
file = fopen(inputFileName, "r"); 

while (fgets(line, sizeof(line), file)) { 

    while(line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r'){ 
     char *tmp = realloc (line, 2 * maxl); 
     //fgets(line, sizeof(line), file); 
     if (tmp) { 
      line = tmp; 
      maxl *= 2; 
     } 
     else{ 
      printf("Not enough memory for this line!!\n"); 
      return -3; 
     } 
    } 
    // do some operations 
} 

난 사실이 질문에 대한 답 구현하기 위해 노력 : Reading a line from file in C, dynamically

를하지만 항상 코드의 "메모리가 부족합니다"부분을 입력합니다. 그래서 내가 뭘 잘못하고 있니?

답장을 보내 주시면 감사하겠습니다.


편집 : 코드는 첫 번째 의견에 따라 달라집니다.


편집 2 : 코드는 항상 파일에서 3 자로 읽습니다.

파일 같은 것을 상상해

abcdabcdabcd... 

line 변수도 재 할당 작업 후 "ABC"항상.

+1

'while' 루프는 그 안에있는 파일에서 새 텍스트를 읽는 경우에만 종료되지만 사용자는 그렇지 않습니다. – Ryan

+0

가능한 [sizeof '(배열을 가리키는 포인터)를 찾는 방법?] (http://stackoverflow.com/questions/492384/how-to-find-the-sizeofa-pointer-pointing-to -an-array) –

+0

'sizeof (char *)'틀렸어. 'char *'의 배열을 할당하고 있습니까? 아니요. –

답변

1

여기에 당신이해야 할 몇 가지 수정 사항은 다음과 같습니다 (! 그냥 제안)

  • 변경 char *tmp = realloc (line, 2 * maxl);char *tmp = realloc (line, 2 * maxl * sizeof(char);합니다.
  • 메모리를 재 할당 한 후 전체 문자열을 읽으려면 파일을 다시 검색해야합니다. 예를 들어, fseek(file,0,SEEK_SET);은 파일 inputFileName의 시작 부분을 찾습니다.
  • sizeof(line)은 문자열 길이가 아닌 문자 포인터의 크기를 계산할 때 항상 상수입니다. 따라서 while (fgets(line, sizeof(line), file)) {while (fgets(line, maxl, file)) {으로 변경하십시오.
  • 재 할당 후 파일에서 문자열을 다시 읽으므로 블록 번호가 블록 안에있는 주석 행을 이동하십시오.
  • line[strlen(line) - 1] != '\n' || line[strlen(line) - 1] != '\r'은 논리적으로 올바르지 않습니다. line의 마지막 문자가 '\n'이나 '\r'이 아닌 경우에만 루프를 입력 할 수 있습니다. 따라서 || 대신 &&을 사용해야합니다.코드에서

    size_t maxl = 256; 
    //char line[256]; 
    char *line = malloc(maxl * sizeof(char)); 
    if(!line){ 
        printf("Memory not allocated!!\n"); 
        return -2; 
    } 
    file = fopen(inputFileName, "r"); 
    
    while (fgets(line, maxl, file)) { 
    
        while(line[strlen(line) - 1] != '\n' && line[strlen(line) - 1] != '\r'){ 
         char *tmp = realloc (line, 2 * maxl * sizeof(char)); 
    
         fseek(file,0,SEEK_SET);   //or wherever you want to seek to 
         if (tmp) { 
          line = tmp; 
          maxl *= 2; 
          fgets(line, maxl, file); 
         } 
         else{ 
          printf("Not enough memory for this line!!\n"); 
          return -3; 
         } 
        } 
        printf("%s\n",line);  //just to check 
    } 
    

    문제점이 있었다 : 여기

수정 된 코드는 문자 sizeof(line) 수를 읽고 있었기 때문에 당신은 파일에서 몇 문자를 읽어했다

  • 문자 수는 maxl이 아닙니다.
  • 전체 문자열을 다시 읽으려면 일부 바이트를 다시 검색하는 것이 좋지만, 이는 사용자의 몫입니다.
  • 재 할당이 성공한 경우에만 파일에서 문자열을 다시 읽습니다 (if(tmp)).

이제 Not enough memory..이 인쇄 작업을 마쳤습니까?

는 루프가 여러 번 재 할당 된 메모리 크기 (maxl 값), 1024, 512, 256과 같이 2048 증가 하였다 실행 되었기 때문에 그것이 ...은 65536, ...

이 크기가되면 컴파일러가 재 할당을 거부하기에 충분히 큰 경우 해당 오류 문자열이 인쇄됩니다. 원하는 경우 코드 버전을 디버깅하거나 루프의 각 반복에서 maxl의 값을 인쇄 해보십시오.

+1

안녕하세요, skrtbhtngr. 귀하의 설명 주셔서 감사합니다, 그것은 매우 명확하고 유익한 것입니다. 그러나이 라인을 수정 한 후에, 다시 "메모리 부족"메시지가 나타납니다. – pilkington

+1

수정 된 코드를 사용해 보았습니다. 정상적으로 작동합니다. 각 반복에서 'maxl'값을 확인할 수 있습니까? – skrtbhtngr

+0

256에서 시작하여 512,1024와 같이 증가합니다. 답변에 언급 된 메모리가 없을 때까지 – pilkington