代码之家  ›  专栏  ›  技术社区  ›  Kauder Hexenban

C中函数中指针的错误行为

  •  -5
  • Kauder Hexenban  · 技术社区  · 9 年前

    我对以下程序有问题。

    主函数调用函数 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;
    }
    
    1 回复  |  直到 9 年前
        1
  •  0
  •   Weather Vane    9 年前

    尽管程序编译时没有任何警告,但程序中有许多错误。主要是数组的指针类型和分配的内存。其次,该函数不知道允许使用多少单词,也不返回读取了多少单词——您的方法根本不起作用(如注释)。第三个字符串比较:你没有明确说明目标,但在评论中你想要“最大的字符串”。 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