/*Input string argument can be up to 3 integer numbers,
separated by spaces. A wild card value, represented by a *
character can replace any one of the integer numbers.*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
void parse(char *data);
int program = 0, version = 0, process = 0;
unsigned char flags = 0;
#define GOT_PROG 0x01
#define GOT_VERS 0x02
#define GOT_PROC 0x04
int main()
{
char data[] = " * 10 7 ";
parse(data);
system("PAUSE");
return 0;
}
void parse(char *data)
{
char *tmp = NULL;
/* advance past whitespace */
while(isspace((int)*data)) data++;
if(*data != '*')
{
program = strtoul(data,&tmp,0);
flags|=GOT_PROG;
printf("%d 11\n",program );
}
if(*tmp == '\0') return;
data=++tmp;
if(*data != '*')
{
version = strtoul(data,&tmp,0);
flags|=GOT_VERS;
printf("%d 22\n",version);
}
else
{
tmp++;
}
if(*tmp == '\0') return;
data=++tmp;
if(*data != '*')
{
process = strtoul(data,&tmp,0);
flags|=GOT_PROC;
printf("%d 33\n",process);
}
}
当我的输入是3个整数时,它运行正常。
当我的输入是两个整数和一个*
它运行正常,除非我用*
替换第一个整数,不知道我哪里出错!有什么建议吗?
答案 0 :(得分:3)
此块中的逻辑错误:
char *tmp = NULL;
/* advance past whitespace */
while(isspace((int)*data)) data++;
// If *data == '*', you are skipping the code inside the if block.
// tmp continues to be NULL.
if(*data != '*')
{
program = strtoul(data,&tmp,0);
flags|=GOT_PROG;
printf("%d 11\n",program );
}
// Now you are dereferencing a NULL pointer
// and then setting the value of data to 'NULL + 1'.
if(*tmp == '\0') return;
data=++tmp;
我没有遵循您的功能的整个逻辑,但您必须添加处理*data == '*'
案例的代码。
答案 1 :(得分:2)
在parse()
内,你正在做
char *tmp = NULL;
然后,如果*data
等于*
,(请记住,错误的案例输入以*
开头)而不更改tmp
,你正在做
if(*tmp == '\0')
即,取消引用无效指针,而指针又调用undefined behaviour。
如果输入具有前导tmp
,则需要注意*
的访问权限。
FWIW,同样的问题,data=++tmp;
也是无效的。
建议:在看到您的逻辑后,我建议使用strtok()
对输入字符串进行标记。这是更好的选择。