2014-09-19 2 views
0

텍스트 문서의 내용을 단어 단위로 읽은 다음 문자열 배열로 복사하려고합니다. 먼저 'x'단어를 읽는 동안 fscanf를 사용하여 파일을 엽니 다. 이 x는 최대 워드 길이를 50으로 가정 할 때 배열에 할당됩니다. 내부에는 x와 배열 값이 모두 인쇄됩니다. 둘 다 올바른 값을 인쇄합니다. 하지만 나중에 모든 일이 잘못되면서 배열의 내용을 인쇄하면됩니다. 모든 배열 단어는 같은 값을가집니다. 파일에서 마지막으로 읽은 값입니다. 먼저 연결된 목록으로 시도했지만 동일한 결과가 나타납니다. 그러나 이것도 같은 결과를줍니다. 논리 블록 외부에서는 모든 배열 값 또는 노드 값에 마지막으로 읽은 단어가 있습니다. ...이 함께Word가 C에서 문자열 배열로 문서에서 읽음

int i=0,wCnt=0,j; 
     int N=600; 
     char **word_array = (char **) calloc(N,sizeof(char*)); 
     if(f = fopen("input.txt","r")) 
     { 
      /* assumes no word exceeds length of 150 */ 
      while (fscanf(f, " %149s", x) == 1) 
      { 
       if(wCnt==N){ 
        N = N+400; 
        realloc(word_array,N); 
       } 
       //printf("x=%s\t",x); 
       word_array[i] = (char *) calloc(50,sizeof(char)); 
       word_array[i] = x; 
       printf("x=%s arr=%s\t",x,word_array[i]); // Gives correct output      
       wCnt++; 
       i++; 
      } 

      // Here the code goes goes wrong. The last word gets print 137 times(wCnt) 
      for(j=0;j<wCnt;j++) 
      { 
       printf("%d->%s\n",j,word_array[j]); 
      } 
     } 

를 도와주세요 내가 무엇입니까 출력은 다음과 같습니다

0->growing 
1->growing 
2->growing 
3->growing 
.. 

'성장'문서의 마지막 단어입니다. 그러나 루프 내에서 'X'의 값을 출력 할 때 정확한 출력 결과를 얻었습니다.

x = 최근 x = 연도 x = 거기 x = x = x = ax = 성장했습니다

+3

['realloc (word_array, N)'] (http://en.cppreference.com/w/c/memory/realloc) 음. 이 호출은 당신이 관심을 가질만한 것을 반환합니다. – WhozCraig

+2

'word_array [i] = x;'는 ** 포인터 **를 복사합니다. 내용을 복사해야 할 수도 있습니다 (아마도 공간을 할당하고'strcpy()'를 사용해야 할 것입니다). – pmg

+0

@pmg 나는 'realloc'이라는 블라인드 호출에서 여전히 릴링을하고 있었는데, 나는 계속되는 메모리 누수와 부적절한 할당을 알지 못했다. – WhozCraig

답변

2

이 코드를 포함한 여러 문제가 있습니다

  • 가 고정 된 50 문자를 가정 realloc()
  • 의 반환 값을 무시하고를 버퍼는 150 문자 폭 (터미네이터 포함) 일 수있는 문자열을 보유 할 수 있습니다.
  • 각 단어에 대한 메모리 할당 (누설)을 무시하고 현재 단어의 포인터로 x의 주소 만 저장하면됩니다.
  • 파일을 닫지 않았습니다.

I '가

이러한 세 번째는 (a) 누설 메모리가 자체를 나타내는 것이고, (b)은 워드 테이블의 모든 엔트리 (로컬 X 버퍼)를 동일한 주소있을 것 위의 각 항목을 처리하는 이와 같은 것을 찾고 있는지 확인하십시오.

FILE *f = NULL; 
int i=0,j; 
int N=600, M=400; 
char x[150]; 

// allocate initial table of pointers, all set to null. 
char **word_array = calloc(N,sizeof(*word_array)); 
if (word_array == NULL) 
{ 
    perror("Failed to allocate pointer array"); 
    exit(EXIT_FAILURE); 
} 

if((f = fopen("input.txt","r"))) 
{ 
    /* assumes no word exceeds length of 150 */ 
    while (fscanf(f, " %149s", x) == 1) 
    { 
     if(i == N) 
     { 
      // attempt resize of table, result stored in a temporary 
      // a NULL return means resizing couldn't happen and we're 
      // not left with much we can do about it. 
      void *tmp = realloc(word_array, (N+M) * sizeof(*word_array)); 
      if (tmp == NULL) 
      { 
       perror("Failed to expand pointer array"); 
       exit(EXIT_FAILURE); 
      } 

      // resize worked. make sure the expansion area contains 
      // NULL pointers, as we haven't set them yet. then update 
      // the new size limit. 
      word_array = tmp; 
      memset(word_array+N, 0, M*sizeof(*word_array)); 
      N += M; 
     } 

     // compute length *once* 
     size_t wlen = strlen(x); 

     // use computed length to allocate a dynamic buffer large 
     // enough to hold the incoming data. again, check for 
     // failure before proceeding. 
     word_array[i] = malloc((wlen+1) * sizeof(char)); 
     if (word_array[i] == NULL) 
     { 
      perror("Failed to duplicate string"); 
      exit(EXIT_FAILURE); 
     } 

     // allocation succeeded. We don't need strcpy 
     // since we already know how much data to copy 
     // over (wlen+1, the +1 for the terminating null char) 
     memcpy(word_array[i], x, wlen+1); 

     // output string from pointer array to prove that worked 
     printf("%d ==> %s\n", i, word_array[i]); 

     // adjust to next slot to populate in the pointer array 
     ++i; 
    } 

    // finished with file. 
    fclose(f); 
} 
+0

감사. 나는 이것을 시도하고 대답 할 것이다. –

+0

고마워요! 그것은 완벽하게 작동하지만 ... 그 코드의 문제를 이해하지 못했습니다. 설명해 주시겠습니까 ...? –

+1

@aswathip이 답변의 맨 위에있는 글 머리 기호 목록은 * 정확하게 설명하도록 고안되었습니다.소스 코드에 주석을 달았습니다. 이유는이 코드가 왜 작동하는지, 그리고 연관성에 의해 실패한 곳을 더 잘 설명하는 데 도움이 될 것입니다. – WhozCraig

2

'x'선언은 보이지 않지만 char *라고 가정합니다. 라인

word_array[i] = x; 

에서 당신은 테이블에 문자열을 복사하지만 X를 가리 최초의 char * 설정되지 않습니다. 이 솔루션은 아마 다음과 같이 strcpy와 또는 유사한을 사용하는 것입니다 :

strcpy(word_array[i], x); 
+0

'x'는 char *입니다. strcpy()도 같은 출력을 낸다. –