2017-11-02 7 views
0

파일에서 배열로 일련의 단일 단어 줄을로드해야하므로이 작업을 수행했습니다. 이 함수는 문자열 배열에 대한 포인터 인 매개 변수로 char*** arr을 사용합니다. 나는 메모리를 할당 한 다음이 루프를 사용하여 단어를 배열에로드합니다.C : 모든 배열 항목을 다시 쓰는 char * 배열의 마지막 요소

i=0; 
FILE *fp = fopen(filename, "r"); 
while(fgets(tok, WORD_BUFFER, fp) != NULL){ 
    (*arr)[i] = tok; 
    printf("Word %d:%s", i, (*dict)[i]); 
    i++; 
} 
//arr is a char***, tok is a char[WORD_BUFFER], and WORD_BUFFER is 50 

내 문제는 이것이 내가 [I] 항목에 입력하기 위해 노력하고있어 무엇과 배열의 모든 항목을 덮어 것으로 보인다는 것이다.

A 
B 
C 
D 

올바르게 인쇄 할 것 같다, 그러나 나는 주요 기능의 배열을 인쇄 할 때 (또는 단지 나중에 그 기능의) : 나는 때문에 이런 식으로 뭔가를 보이는 파일에 대한 위의 루프의 출력이 말

D 
D 
D 
D 

나는 내 fgets의 사용 또는 (*arr)[i] = tok의 할당 함께 할 수있는 뭔가가하지만 난 잘 모르겠어요 같은데요 : 그것은처럼 인쇄됩니다. 감사합니다.

+2

다음 문장 (* arr) [i] = tok; 배열의 모든 요소는 변수 토큰과 동일한 값을 갖습니다. –

+0

왜 그런가요? 왜 그저 토큰의 가치가 arr [i]를 만들지 않을까요? – Jeb

+1

당신은 단지'= '연산자로 포인터를 할당하고 있습니다. 'tok'는 반복문을 통해 반복되는 모든 파일을 덮어 씁니다. 그래서 모든 것이'tok'를 가리키며 파일에서 마지막으로 읽은 행입니다. 당신이해야합니다 ['strcpy'] (https://linux.die.net/man/3/strcpy) 다른 대상에 tok''의 데이터를 저장하려는 경우 루프를 통해 때마다. – yano

답변

0

의견에 비추어 볼 때 간단한 char* 배열을 사용하여 무엇을하는지 설명하려고합니다. 의는 다음과 같은 당신이 있다고 가정 해 봅시다 :

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

int main(void) 
{ 
    int i; 
    char tok[50] = "applesauce"; // tok can contain up to 49 chars plus the NUL terminator 

    char* myCharPtr[20]; // this is an array 20 long where each element is of type char* 

    // All the loop does is store the _address_ of tok at each position in the 
    // myCharPtr array. The _data_ "applesauce" only exists _once_ in memory, 
    // and whatever that address is now fills the contents of myCharPtr. 
    // (technically, "applesauce" exists twice in memory, the string literal 
    // and the char array.. but neither of those places are in myCharPtr) 
    for (i=0; i<20; i++) 
    { 
    myCharPtr[i] = tok; 
    } 

    for (i=0; i<20; i++) 
    { 
    printf("myCharPtr[%d] = %s\n", i, myCharPtr[i]); 
    // prints out "applesauce" for each entry because each entry points to tok. 
    } 

    // Now let's do 

    strcpy(tok, "apples"); // "apples" is smaller than 49, so we aren't overwriting the bounds of the array 

    for (i=0; i<20; i++) 
    { 
    printf("myCharPtr[%d] = %s\n", i, myCharPtr[i]); 
    // prints out "apples" for each entry because the _pointer_ to tok 
    // hasn't changed, but the _data_ in tok has changed. 
    } 

    // To further re-enforce this, you can do 
    printf("address of tok = %p\n", (void*)tok); 
    for (i=0; i<20; i++) 
    { 
    printf("address of myCharPtr[%d] = %p\n", i, (void*)(&myCharPtr[i])); 
    } 
    // the address for tok will match all the addresses in myCharPtr 

    // if you want to actually save/copy the data in tok, then you need to do 
    // something like this 

    char wordList[20][50]; // this can store up to 20 words that are each up 
          // to 49 chars each (must leave 1 byte for NUL termination 
    for (i=0; i<20; i++) 
    { 
    // assume this function populates tok with new data each call, much like fgets 
    // this function would have to ensure it's not writing strings bigger than 49 to tok 
    GetNewContentForTok(tok); 
    strcpy(wordList[i], tok); 
    // now, we are saving the contents of tok each time, not simply copying 
    // its pointer. 
    } 

    for (i=0; i<20; i++) 
    { 
    printf("wordList[%d] = %s\n", i, wordList[i]); 
    // this will print all the strings that were once stored in tok from the previous loop 
    } 

    return 0; 
} 

내가 일반적으로 그 정도 간접 나에게 혼란을 얻을 수있는, char*** 유형을 다루는 피하려고. 위의 예제에서 배열을 사용했지만 동적으로 할당 된 메모리를 가리키는 포인터에도 동일한 원칙이 적용됩니다.