C中函数中指针的行为不正确

时间:2016-06-01 19:46:08

标签: c arrays pointers strtok

我遇到以下程序的问题。

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;
}

1 个答案:

答案 0 :(得分: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