我正试图使用一个使用strtok函数的函数打印命令行参数的标记。关键是return语句无法识别返回的指针。
#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>
#include<string>
using namespace std;
char **makeargv(char *s);
int main()
{
int i;
char **myargv;
char mytest[] = "This is a test";
if((myargv = makeargv(mytest)) == NULL)
fprintf(stderr,"Failed to construct an argument arrayn");
else
for (i=0;myargv[i]!=NULL;i++)
printf("%d:%sn",i,myargv[i]);
system("pause");
return 0;
}
char **makeargv(char *mytest)
{
char *pch;
printf("Splitting string %s into tokens:n",mytest);
pch = strtok(mytest," ");
while(pch != NULL)
{
printf("%sn",pch);
pch = strtok(NULL," ");
}
pch = strtok(mytest," ");
char *s = pch;
return &s;
}
这将始终使pch在循环后指向NULL因为那是你的结局。
while(pch != NULL)
{
printf("%sn",pch);
pch = strtok(NULL," ");
}
char *s = pch; // pch is NULL
如果你想返回最后一个令牌,你可以手动搜索最后一个空间
正如Rakibul已经提到的,您不应该两次取消引用字符串,您需要返回的是字符串的地址,即pch本身。
如果你的系统上有strrev,你可以写一些类似的东西
strrev( mytest ); // reverse string
char* pch = strtok( mytest, " " ); // extract token
if ( pch != NULL )
{
puts( strrev(pch) ); // back to original
}
编辑
你写了
我对函数做了一个小的更改,但我得到了错误的指针异常错误
char **makeargv(char *mytest)
{
char *pch;
printf("Splitting string %s into tokens:n",mytest);
pch = strtok(mytest," ");
while(pch != NULL)
{
printf("%sn",pch);
pch = strtok(NULL," ");
}
pch = strtok(mytest," ");
char *s = pch;
return &s;
}
您仍然试图返回指针的地址——您似乎不知道strtok会修改其参数,当您将原始字符串传递给strtok函数时,它会被修改。
相反,尝试类似的东西
char **makeargv(char *mytest)
{
// setup an array of pointers to strings, 20 is an arbitrary value
const int maxtokens = 20;
char**tokens = malloc( sizeof(char*) * maxtokens );
for ( int i = 0; i < maxtokens; ++i )
{
tokens[i] = NULL;
}
printf("Splitting string %s into tokens:n",mytest);
char *pch = strtok(mytest," ");
int found = 0;
// the maxtokens - 1 will ensure that at least one pointer is null
// in the array
while(pch != NULL && found < maxtokens - 1)
{
printf("%sn",pch);
tokens[found++] = strdup(pch); // allocate and copy token
pch = strtok(NULL," ");
}
return tokens;
}
现在你得到了一个带有标记的数组
char arg[] = "this is a test";
char** tokens = makeargv(arg);
int i = 0;
for (i = 0; tokens[i] != NULL; ++i)
puts( tokens[i] );
don't forget to free the memory later
for (i = 0; tokens[i] != NULL; ++i)
free( tokens[i] );
free( tokens );
定义char *myargv[MAXARGV]
,并将其传递到makeargv
函数中,并将pch
存储在其中。返回找到的参数数。
char *s = pch;
s
是一个指向字符的指针,但在return **s;
语句中,您取消了两次引用,这是错误的。您的预期用途是
return &s;
这将返回一个指向字符(char**
(的指针。
但是您的整个程序在指针使用方面定义不清。例如,您正在返回指向堆栈上某个局部变量的指针,该变量将在方法返回后被销毁,并且在调用程序中访问它是UB。
在返回pch
之前,将是NULL
,s
也是,所以基本上您正在获取并返回NULL指针的地址。