程序在使用通配符 (*) 作为第一个输入时出现分段错误
Program gives segmantation fault while using wildcard (*) as first input
/*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 == '[=10=]') return;
data=++tmp;
if(*data != '*')
{
version = strtoul(data,&tmp,0);
flags|=GOT_VERS;
printf("%d 22\n",version);
}
else
{
tmp++;
}
if(*tmp == '[=10=]') return;
data=++tmp;
if(*data != '*')
{
process = strtoul(data,&tmp,0);
flags|=GOT_PROC;
printf("%d 33\n",process);
}
}
当我输入 3 个整数时,它运行良好。
当我的输入是两个整数和一个 *
时,它运行正常,除非我用 *
替换第一个整数,不知道我哪里出错了!!有什么建议吗?
在你的parse()
里面,你正在做
char *tmp = NULL;
那么,如果 *data
等于 *
,(记住,错误的大小写输入以 *
开头)而不改变 tmp
,你正在做
if(*tmp == '[=11=]')
即取消引用无效指针,这又会调用 undefined behaviour。
如果输入有前导 *
,您需要注意对 tmp
的访问。
FWIW,同样的,data=++tmp;
也是无效的。
建议: 看到你的逻辑后,我建议使用 strtok()
对输入字符串进行分词。这是更好的选择。
此块中的逻辑错误:
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 == '[=10=]') return;
data=++tmp;
我没有遵循你函数的全部逻辑,但你必须添加处理 *data == '*'
.
情况的代码
/*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 == '[=10=]') return;
data=++tmp;
if(*data != '*')
{
version = strtoul(data,&tmp,0);
flags|=GOT_VERS;
printf("%d 22\n",version);
}
else
{
tmp++;
}
if(*tmp == '[=10=]') return;
data=++tmp;
if(*data != '*')
{
process = strtoul(data,&tmp,0);
flags|=GOT_PROC;
printf("%d 33\n",process);
}
}
当我输入 3 个整数时,它运行良好。
当我的输入是两个整数和一个 *
时,它运行正常,除非我用 *
替换第一个整数,不知道我哪里出错了!!有什么建议吗?
在你的parse()
里面,你正在做
char *tmp = NULL;
那么,如果 *data
等于 *
,(记住,错误的大小写输入以 *
开头)而不改变 tmp
,你正在做
if(*tmp == '[=11=]')
即取消引用无效指针,这又会调用 undefined behaviour。
如果输入有前导 *
,您需要注意对 tmp
的访问。
FWIW,同样的,data=++tmp;
也是无效的。
建议: 看到你的逻辑后,我建议使用 strtok()
对输入字符串进行分词。这是更好的选择。
此块中的逻辑错误:
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 == '[=10=]') return;
data=++tmp;
我没有遵循你函数的全部逻辑,但你必须添加处理 *data == '*'
.