C 函数中指针的不正确行为
Incorrect behavior of a pointer in function in C
我的以下程序有问题。
主函数调用函数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;
}
虽然编译时没有任何警告,但程序中有很多错误。主要是数组的指针类型和分配的内存。其次,该函数不知道允许使用多少个单词,也不知道 return 读取了多少个 - 您的方法根本不起作用(如评论中所示)。第三个字符串比较:你没有明确说明目标,但在评论中你想要 "biggest string"。 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
我的以下程序有问题。
主函数调用函数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;
}
虽然编译时没有任何警告,但程序中有很多错误。主要是数组的指针类型和分配的内存。其次,该函数不知道允许使用多少个单词,也不知道 return 读取了多少个 - 您的方法根本不起作用(如评论中所示)。第三个字符串比较:你没有明确说明目标,但在评论中你想要 "biggest string"。 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