从字符串中获取第二个单词
Get second word from string
我正在尝试使用 strtok
:
从 C 中的字符串中获取第二个单词
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char* GetFirstToken(char str[])
{
const char delim[] = " ";
char inputCopy [255];
strcpy(inputCopy, str);
return strtok(inputCopy, delim);
}
char* GetSecondToken(char str[])
{
const char delim[] = " ";
char inputCopy [255];
strcpy(inputCopy, str);
char * ptr = strtok(inputCopy, delim);
return strtok(NULL, delim);
}
int main(void){
char my_str[100] ="hello world";
char *first = GetFirstToken(my_str);
char *second = GetSecondToken(my_str);
printf("first:%s\n", first);
printf("second:%s\n", second);
return 0;
}
输出为:
first: hello
second: wo
为什么 "world" 不是 second
的值?
函数 return 无效指针,因为它们指向局部数组,这些数组在退出函数后将不存在。因此使用指针可以调用未定义的行为。
您可以只定义一个函数,再定义一个参数来指定要提取的子字符串。
这是一个演示程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * GetToken( const char str[], size_t pos )
{
const char delim[] = " \t";
char *inputCopy = malloc( ( strlen( str ) + 1 ) );
char *p = NULL;
if ( inputCopy != NULL )
{
strcpy( inputCopy, str );
p = strtok( inputCopy, delim );
while ( p != NULL && pos -- != 0 )
{
p = strtok( NULL, delim );
}
if ( p != NULL )
{
size_t n = strlen( p );
memmove( inputCopy, p, n + 1 );
p = realloc( inputCopy, n + 1 );
}
if ( p == NULL )
{
free( inputCopy );
}
}
return p;
}
int main(void)
{
char my_str[100] ="hello world";
char *first = GetToken(my_str, 0);
char *second = GetToken( my_str, 1 );
if ( first ) printf("first:%s\n", first);
if ( second ) printf("second:%s\n", second);
free( first );
free( second );
return 0;
}
您在每个函数内部声明 char inputCopy[255]
,然后 return 指向它的指针。但是,该数组仅存在于函数范围内,导致 未定义的行为。
您可以通过在 main 中创建数组并将其作为参数传递给函数来避免这种情况。此外,使用 malloc
为数组动态分配内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char* GetFirstToken(char str[], char inputCopy[], const char delim[])
{
strcpy(inputCopy, str);
return strtok(inputCopy, delim);
}
char* GetSecondToken(char str[], char inputCopy[], const char delim[])
{
strcpy(inputCopy, str);
char * ptr = strtok(inputCopy, delim);
return strtok(NULL, delim);
}
int main(void){
char my_str[100] ="hello world";
char *inputCopy = malloc(255 * sizeof(char));
const char delim[] = " ";
char *first = GetFirstToken(my_str, inputCopy, delim);
char *second = GetSecondToken(my_str, inputCopy, delim);
printf("first:%s\n", first);
printf("second:%s\n", second);
free(inputCopy);
return 0;
}
输出:
first:hello
second:world
您可以在 C here, and about malloc here.
中阅读有关 scopes 的更多信息
另外,请注意 GetFirstToken
和 GetSecondToken
具有相似的功能。因此,最好有一个函数 returns 给定字符串中的第 n 个单词。这是基本思想:
#include <stdio.h>
#include <string.h>
int main()
{
char my_str[] ="hello world i am a string";
char* word;
/* get the first word from the message, seperated by
* space character */
word = strtok(my_str, " ");
printf("1st word: %s\n", word);
/* the following loop gets the rest of the words until the
* end of the message */
int i=2;
while ((word = strtok(NULL, " ")) != NULL)
{
printf("%d word: %s\n", i, word);
i++;
}
return 0;
}
您可以阅读有关此类解决方案的更多信息here and also in 。
我正在尝试使用 strtok
:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char* GetFirstToken(char str[])
{
const char delim[] = " ";
char inputCopy [255];
strcpy(inputCopy, str);
return strtok(inputCopy, delim);
}
char* GetSecondToken(char str[])
{
const char delim[] = " ";
char inputCopy [255];
strcpy(inputCopy, str);
char * ptr = strtok(inputCopy, delim);
return strtok(NULL, delim);
}
int main(void){
char my_str[100] ="hello world";
char *first = GetFirstToken(my_str);
char *second = GetSecondToken(my_str);
printf("first:%s\n", first);
printf("second:%s\n", second);
return 0;
}
输出为:
first: hello
second: wo
为什么 "world" 不是 second
的值?
函数 return 无效指针,因为它们指向局部数组,这些数组在退出函数后将不存在。因此使用指针可以调用未定义的行为。
您可以只定义一个函数,再定义一个参数来指定要提取的子字符串。
这是一个演示程序。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char * GetToken( const char str[], size_t pos )
{
const char delim[] = " \t";
char *inputCopy = malloc( ( strlen( str ) + 1 ) );
char *p = NULL;
if ( inputCopy != NULL )
{
strcpy( inputCopy, str );
p = strtok( inputCopy, delim );
while ( p != NULL && pos -- != 0 )
{
p = strtok( NULL, delim );
}
if ( p != NULL )
{
size_t n = strlen( p );
memmove( inputCopy, p, n + 1 );
p = realloc( inputCopy, n + 1 );
}
if ( p == NULL )
{
free( inputCopy );
}
}
return p;
}
int main(void)
{
char my_str[100] ="hello world";
char *first = GetToken(my_str, 0);
char *second = GetToken( my_str, 1 );
if ( first ) printf("first:%s\n", first);
if ( second ) printf("second:%s\n", second);
free( first );
free( second );
return 0;
}
您在每个函数内部声明 char inputCopy[255]
,然后 return 指向它的指针。但是,该数组仅存在于函数范围内,导致 未定义的行为。
您可以通过在 main 中创建数组并将其作为参数传递给函数来避免这种情况。此外,使用 malloc
为数组动态分配内存。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
char* GetFirstToken(char str[], char inputCopy[], const char delim[])
{
strcpy(inputCopy, str);
return strtok(inputCopy, delim);
}
char* GetSecondToken(char str[], char inputCopy[], const char delim[])
{
strcpy(inputCopy, str);
char * ptr = strtok(inputCopy, delim);
return strtok(NULL, delim);
}
int main(void){
char my_str[100] ="hello world";
char *inputCopy = malloc(255 * sizeof(char));
const char delim[] = " ";
char *first = GetFirstToken(my_str, inputCopy, delim);
char *second = GetSecondToken(my_str, inputCopy, delim);
printf("first:%s\n", first);
printf("second:%s\n", second);
free(inputCopy);
return 0;
}
输出:
first:hello
second:world
您可以在 C here, and about malloc here.
中阅读有关 scopes 的更多信息另外,请注意 GetFirstToken
和 GetSecondToken
具有相似的功能。因此,最好有一个函数 returns 给定字符串中的第 n 个单词。这是基本思想:
#include <stdio.h>
#include <string.h>
int main()
{
char my_str[] ="hello world i am a string";
char* word;
/* get the first word from the message, seperated by
* space character */
word = strtok(my_str, " ");
printf("1st word: %s\n", word);
/* the following loop gets the rest of the words until the
* end of the message */
int i=2;
while ((word = strtok(NULL, " ")) != NULL)
{
printf("%d word: %s\n", i, word);
i++;
}
return 0;
}
您可以阅读有关此类解决方案的更多信息here and also in