程序在使用通配符(*)作为第一个输入时给出了分段错误

时间:2015-04-30 06:55:50

标签: c pointers memory char segmentation-fault

/*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个整数时,它运行正常。 当我的输入是两个整数和一个*它运行正常,除非我用*替换第一个整数,不知道我哪里出错!有什么建议吗?

2 个答案:

答案 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()对输入字符串进行标记。这是更好的选择。