2016-06-01 2 views
-5

다음 프로그램에 문제가 있습니다.C의 함수에서 포인터의 잘못된 동작

main 함수는 returnArrayOfWords(arrS1, &ptrArray1) 함수를 두 번 호출합니다. 첫 번째 호출에서 배열은 완벽하게 파싱 된 후 포인터는 항상 첫 번째 단어를 가리 킵니다. 반면에 두 번째 호출 후에는 첫 번째 배열의 포인터가 두 번째 단어, 세 번째 단어 또는 때로는 첫 번째 단어를 가리 키지 만 항상 첫 번째 단어를 가리켜 야합니다.

두 번째로 호출 할 때 왜 함수가 오동작합니까?

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

void returnArrayOfWords (char *str4Parsing, char *arrayParsed[]) 
{ 
    char seps[] = " ,\t\n"; // separators 
    char *token1 = NULL; 
    char *next_token1 = NULL; 
    int i = 0; 

    // Establish string and get the first token: 
    token1 = strtok_s(str4Parsing, seps, &next_token1); 

    // While there are tokens in "str4Parsing" 
    while (token1 != NULL) 
    { 
     // Get next token: 
     if (token1 != NULL) 
     { 
      arrayParsed[i] = token1; 
      printf(" %s\n", token1); 
      token1 = strtok_s(NULL, seps, &next_token1); 
      i++; 
     } 
    } 
} 


//int main1() 
int main() 
{ 
    int i, j, n = 80; /*max number of words in string*/ 
    char arrS1[80], arrS2[80]; 
    const char *w1, *w2; /*pointers*/ 
    char *ptrArray1, *ptrArray2; 
    int currLength1 = 0, currLength2 = 0 ; 
    int sizeArr1 = 0, sizeArr2 = 0; 
    int maxLength = 0; 
    char wordMaxLength ; 

    printf("Type your first string: "); 
    fgets(arrS1, 80, stdin); 
    returnArrayOfWords(arrS1, &ptrArray1); 
    sizeArr1 = sizeof(ptrArray1)/sizeof(ptrArray1[0]); 

    printf("Type your second string: "); 
    fgets(arrS2, 80, stdin); 
    returnArrayOfWords(arrS2, &ptrArray2); 
    sizeArr2 = sizeof(ptrArray2)/sizeof(ptrArray2[0]); 

    for (i = 0; i < sizeArr1; i++) 
    { 
     // to find the largest word in the array 
     w1 = &ptrArray1[i]; 
     currLength1 = strlen(w1); 
     for (j = 0; j < sizeArr2; j++) 
     { 
      w2 = &ptrArray2[j]; 
      currLength2 = strlen(w2); 

      if (strcoll(w1, w2) == 0) 
      // compares the strings 
      { 
       if (currLength2 >= maxLength) 
       // in the 0th element -> the length of the longest word 
       { 
        maxLength = currLength2; 
        wordMaxLength = ptrArray2[j]; 
       } 
      } 
     } 
    } 

    printf("The largest word is: %s", wordMaxLength); 
    return 0; 
} 

편집 : 여기

코드의 최신 버전의 모든 것이 여기에 잘 작동, 그것을 자신을 해결할 수 있었다. 나는 누군가가 해결책으로 그것을 필요로하는 경우를 대비해서 게시하고있다 :

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

     #define n 80 /*max number of words in string*/ 

     /* Arrays and pointers */ 

     int returnArrayOfWords (char *str4Parsing, char *arrayParsed[]) 
    { 
// returns the length of array 
int elArr = 0, na = 0; 
char *delim = " .,;-\t\n";  /* word delimiters */ 
char *next_token1 = NULL; 
char *ap = str4Parsing;   /* pointer to str4Parsing */ 
for (ap = strtok_s (str4Parsing, delim, &next_token1); ap; ap = strtok_s(NULL, delim, &next_token1)) 
{ 
    arrayParsed[na++] = ap; 
    elArr++; 
} 

return elArr; 
} 


void printArr(char *arr[]) 
{ 
int i; 
for (i = 0; i < n; i++) 
{ 
    printf("Element %d is %s \n", i, arr[i]); 
} 
} 


void findLargestWord(char *ptrArray1[], int sizeArr1, char *ptrArray2[], int  sizeArr2) 
{ 
size_t maxLength = 0; 
char *wordMaxLength = NULL ; 
int i = 0, j = 0; 
char *w1 = NULL, *w2 = NULL; /*pointers*/ 
size_t currLength1 = 0, currLength2 = 0 ; 

for (i = 0; i < sizeArr1; i++) 
    { 
    // to find the largest word in the array 
    w1 = (ptrArray1[i]); // value of address (ptrArray1 + i) 
    currLength1 = strlen(w1); 
    //printf("The word from the first string is: %s and its length is : %d  \n", w1, currLength1); // check point 

    for (j = 0; j < sizeArr2; j++) 
     { 
     w2 = (ptrArray2[j]); // value of address (ptrArray2 + j) 
     currLength2 = strlen(w2); 
     //printf("The word from the second string is : %s and its length is : %d \n", w2, currLength2); // check point 

     if (strcoll(w1, w2) == 0 && currLength1 == currLength2) 
      // compares the strings 
      { 
      if (currLength2 >= maxLength) 
       // in the variable maxLength -> the length of the longest word 
       { 
        maxLength = currLength2; 
        wordMaxLength = w2; 
        //printf("The largest word for now is : %s and its length is : %d \n", wordMaxLength, maxLength); // check point 
       } 
      } 
     } 
    } 
printf("The largest word is: %s \n", wordMaxLength); 
printf("Its length is: %d \n", maxLength); 
} 


    void typeArray (char *arrS1) 
{ 
    int err = 0; 
if (!fgets (arrS1, n, stdin)) { /* validate 'arrS1' */ 
    fprintf (stderr, "Error: invalid input for string.\n"); 
    err = 1; 
} 

while (err == 1) 
{ 
    if (!fgets (arrS1, n, stdin)) { /* validate 'arrS1' */ 
     fprintf (stderr, "Error: invalid input for string.\n"); 
     err = 1; 
    } 
} 
} 


    int main(void) 
{ 
    char arrS1[n], arrS2[n]; 
char *ptrArray1[n] = {NULL}, *ptrArray2[n] = {NULL}; 
int sizeArr1 = 0, sizeArr2 = 0; 

printf("Type your first string: "); 
typeArray (arrS1); 
sizeArr1 = returnArrayOfWords (arrS1, ptrArray1); // sizeArr1 = number of elements in array 1 

printf("Type your second string: "); 
typeArray (arrS2); 
sizeArr2 = returnArrayOfWords (arrS2, ptrArray2); // sizeArr2 = number of elements in array 2 

findLargestWord(ptrArray1, sizeArr1, ptrArray2, sizeArr2); 

return 0; 
} 
+0

가 도움을 사전에 모두 감사합니다! –

+6

샷건으로 들여 쓰기를 했습니까? 또한 NULL이 아닌 ** token1'을 ** 꼭해야 할 필요가있는 까다로운 경우에 while ((token1! = NULL)) { if (token1! = NULL)'을 좋아합니다. – EOF

+2

"역 서식 스타일"을 발명 했습니까? –

답변

0

경고없이 컴파일되었지만 수많은 오류가있다. 주로 배열에 대한 포인터 유형과 할당 된 메모리. 두 번째로 함수는 얼마나 많은 단어가 허용되는지 알지 못하며 읽은 횟수를 반환하지 않습니다 - 메서드가 전혀 작동하지 않았습니다 (주석 에서처럼). 셋째, 문자열 비교 : 목표를 명확하게 명시하지 않았지만 의견에서 "가장 큰 문자열"을 원합니다. strcoll은 그렇게하지 않습니다. 어휘 비교이므로 입력 한 두 문장 중 가장 긴 문자열을 찾기 위해 해당 섹션을 변경했습니다. 의견보기, 나는 많은 변화를 만들었다.

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

int returnArrayOfWords (char *str4Parsing, char *arrayParsed[], int maxtokens) // added max 
{ 
    char seps[] = " ,\t\n"; // separators 
    char *token1 = NULL; 
    char *next_token1 = NULL; 
    int i = 0; 

    // Establish string and get the first token: 
    token1 = strtok_s(str4Parsing, seps, &next_token1); 

    // While there are tokens in "str4Parsing" 
    while (token1 != NULL) 
    { 
     if(i >= maxtokens) 
      return i;         // ignore the rest 
     arrayParsed[i] = token1; 
     printf(" %s\n", token1); 
     token1 = strtok_s(NULL, seps, &next_token1); 
     i++; 
    } 
    return i; 
} 

int main (void)           // correct signature 
{ 
    int i, j, n = 80; /*max number of words in string*/ 
    char arrS1[80], arrS2[80]; 
    //const char *w1, *w2; /*pointers*/     // deleted 
    char **ptrArray1, **ptrArray2;      // changed type 
    int currLength1 = 0, currLength2 = 0 ; 
    int sizeArr1 = 0, sizeArr2 = 0; 
    int maxLength = 0; 
    char *wordMaxLength;        // changed to pointer 

    ptrArray1 = malloc(n * sizeof (char*));    // allocate mem for pointer array 
    if (ptrArray1 == NULL) 
     return 1; 
    ptrArray2 = malloc(n * sizeof (char*));    // allocate mem for pointer array 
    if (ptrArray2 == NULL) 
     return 1; 

    printf("Type your first string: "); 
    fgets(arrS1, 80, stdin); 
    sizeArr1 = returnArrayOfWords(arrS1, ptrArray1, n); // indirection error, added max words, get actual num 

    printf("Type your second string: "); 
    fgets(arrS2, 80, stdin); 
    sizeArr2 = returnArrayOfWords(arrS2, ptrArray2, n); // indirection error, added max words, get actual num 

    for (i = 0; i < sizeArr1; i++)      // this section rewritten 
    { 
     // to find the largest word in the array 
     currLength1 = strlen(ptrArray1[i]); 
     if(currLength1 > maxLength) 
     { 
      maxLength = currLength1; 
      wordMaxLength = ptrArray1[i];    // changed definition to pointer 
     } 
    } 

    for (j = 0; j < sizeArr2; j++) 
    { 
     // to find the largest word in the array 
     currLength2 = strlen(ptrArray2[j]); 
     if(currLength2 > maxLength) 
     { 
      maxLength = currLength2; 
      wordMaxLength = ptrArray2[j];    // changed definition to pointer 
     } 
    } 

    printf("The largest word is: %s", wordMaxLength); 

    free(ptrArray1);         // added 
    free(ptrArray2); 
    return 0; 
} 

프로그램 세션 :

Type your first string: one two three four 
one 
two 
three 
four 
Type your second string: apple banana pear 
apple 
banana 
pear 
The largest word is: banana 
+0

감사합니다. 코드는 잘 작동하지만 원래 두 문자열에서 가장 긴 공통 단어를 검색했습니다. 예 : 문자열 1 = 배 바나나 사과; 줄 2 = 바나나 포도 오이; 가장 일반적인 단어 = 바나나. 이걸로 나를 도울 수 있니? –

+0

사과드립니다. 나는 "나는이 대답을 받아 들인다"는 말을 결코하지 않았으며, 나는이 사이트를 처음 접했고 그것에 대해 많이 알지 못했다. 나는 그것을 지금 고쳤다. 답변을 주셔서 다시 한 번 감사 드리며 좋은 하루 되세요! :) –