getint函数的分段错误错误

时间:2015-11-09 07:26:47

标签: c loops

/*
 * GETINTDRIVER -- program to call an integer reading function
 *
 * Compiling: put the getint function in getint.c, then say:
 *  gcc -ansi -pedantic -Wall -o getint getintdriver.c getint.c
 *
 * Usage: getint
 *
 * Inputs (from standard input)
 *      -- a line of text
 *      -- EOF to exit
 *      -- special handling of 2246, 2247, 2248, 2249
 * Outputs (to standard output)
 *  -- a prompt when it expects input
 *  -- outputs indicating the success or failure of the getint call
 *  -- if input is integer 2246, also indicate whether getint() handles
 *      a NULL first argument correctly
 *  -- if input is integer 2247, also indicate whether getint() handles
 *      a NULL second argument correctly
 *  -- if input is integer 2248, also indicate whether getint() handles
 *      a NULL third argument correctly
 *  -- if input is integer 2249, also indicate whether getint() handles
 *      a NULL dereferencing of the third argument correctly
 * Errors (to standard error)
 *  -- nothing printed
 *
 * Exit Code: 0

 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
/*
 * macros
 *
 * how to test for bogus arguments
 */
#define BADARG1 2246        /* if read, test handling of NULL first arg */
#define BADARG2 2247        /* if read, test handling of NULL second arg */
#define BADARG3 2248        /* if read, test handling of NULL third arg */
#define BADARG4 2249        /* if read, test handling of NULL dereference for third arg */

/*
 *  prototypes
 */
int getint(char *inputline, int *value, char **nextchar)    
/* function to read an integer */
{ 
    int c; 
    int sign;
    while(isspace(c = getchar()))
        ;
    if(!isdigit(c) && c != EOF && c != '+' && c != '-') {
       **nextchar =  ungetchar(c);
        return 0;
    }

    sign = (c == '-') ? -1 : 1;
    if(c == '+' || c == '-')
        c = getchar();

    for(*value = 0; isdigit(c); (c = getchar()))
        *value  = 10 * *value + (c - '0');
    *value *= sign;
    if(c != EOF)
        ungetchar(c);
    return c;
}
ungetchar(int n)
{
    while(getchar() != '\n');
    {
        return 1;
    }
}



/* {
    int n;
    int i;
    char inpline[INT_MAX];

    while(fgets(inpline, sizeof[inpline], *inputline))
    {
        n = antoi(inpline);
        if(atoi(inpline) == 1);
        {
            *value = atoi(inpline);
        }
        else if (!atoi(inpline) && (getchar() != '\n' || inpline == '.'))
        {
            return 0;
        }
        else
        {
            **nextchar = inpline[n];
        }
    if(inpline[n] >= inpline[INT_MAX])
    {
        return 0;
    }
    else if (inpline[n] <= inpline[INT_MIN])
    {
        return 0;
    }
    return 0;
}
*/
/*
 * this function calls getint with various illegal parameters
 *
 * Parameter:   int number to trigger test (or not)
 *          numbers that do not trigger tests are ignored
 *          BADARG1     test NULL argument 1
 *          BADARG2     test NULL argument 2
 *          BADARG3     test NULL argument 3
 *          BADARG4     test argument 3 pointing to NULL
 * Returns: nothing
 * Exceptions:  none
 * Side Effects:    prints a 1-line message identifying the test run and
 *          giving the success or failure of the test */



void checkargs(int testno)
{
    char line[10];      /* array used for input line */
    int inpnum = 0;     /* space for the read number */
    char *nextch = line;    /* where the getint function leaves off */
    int rv;         /* return value from getint() */

    /*
     * just copy some characters into line
     */
    (void) strcpy(line, "987654321");

    /*
     * process any magic numbers (see above)
     */
    switch(testno){
    case BADARG1:       /* NULL first argument */
        if ((rv = getint(NULL, &inpnum, &nextch)) == -1)
            printf("Passed NULL first argument test\n");
        else
            printf("Failed NULL first argument test; returned %d\n", rv);
        break;
    case BADARG2:       /* NULL second argument */
        if ((rv = getint(line, NULL, &nextch)) == -1)
            printf("Passed NULL second argument test\n");
        else
            printf("Failed NULL second argument test; returned %d\n", rv);
        break;
    case BADARG3:       /* NULL third argument */
        if ((rv = getint(line, &inpnum, NULL)) == -1)
            printf("Passed NULL third argument test\n");
        else
            printf("Failed NULL third argument test; returned %d\n", rv);
        break;
    case BADARG4:       /* NULL dereference of third  argument */
        nextch = NULL;
        if ((rv = getint(line, &inpnum, &nextch)) == -1)
            printf("Passed NULL third argument dereference test\n");
        else
            printf("Failed NULL third argument dereference test; returned %d\n", rv);
        break;
    default:        /* ignore any other number */
        break;
    }
}

/*
 * it all starts at the main routine
 */
int main(void)
{
    char buf[1024];         /* input buffer */
    int numread;            /* number read from input */
    char *nextch;           /* where we left off */
    int rv;             /* return value of getint() */

    /*
     * loop until end of file
     * prompting the user for an input line
     */
    while(printf("> "), fgets(buf, 1024, stdin) != NULL){
        /* clobber any trailing newline */
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = '\0';
        /*
         * now process the line -- read the leading integer
         * and report if it is not an integer or if
         * it is too big or too small to represent
         */
        switch(rv = getint(buf, &numread, &nextch)){
        case -1:        /* illegal parameter */
            printf("Illegal call -- internal inconsistency\n");
            break;
        case 0:         /* no leading integer */
            printf("No number -- string is \"%s\"\n", nextch);
            if (buf != nextch)
                printf("Note -- third argument should point to first, but it doesn't\n");
            break;
        case 1:         /* read number, all's well */
            printf("Read integer %d; rest of string is \"%s\"\n", numread, nextch);
            break;
        case 2:         /* read number but it's too big */
            printf("Integer overflow (+ve) -- string is \"%s\"\n", nextch);
            break;
        case 3:         /* read number but it's too negative */
            printf("Integer underflow (-ve) -- string is \"%s\"\n", nextch);
            break;
        default:        /* huh? should never happen */
            printf("Unknown return value %d\n", rv);
            break;
        }
        /*
         * now check for illegal arguments
         */
        if (rv == 1)
            checkargs(numread);
    }

    /*
     * sweet dreams ...
     */
    return(0);
}

我一直收到分段错误错误,但我想要做的就是获取整数并删除非字母数字。对于这个程序,+ 123和-123是整数,而123xyz不是。 123.4不是整数,而是1234.是。但我不断收到分段错误。

更新:现在我运行它,我一直得到&#34;未知的返回值#&#34;。过去,如果我输入一个字母,如123xys或只是字母,我得到分段错误。

1 个答案:

答案 0 :(得分:3)

你什么时候为nextch分配内存?

char *nextch;           /* where we left off */
int rv;  

来自main,您正在调用方法switch(rv = getint(buf, &numread, &nextch)){

请考虑以下程序以便您理解。

#include<stdio.h>
#include<string.h>

void f(char **c){

 **c = 'h';
return;
}

int main(){
    char *n;
    n = malloc( sizeof (char));
    f(&n);
    return 0;
}

如果您对该行n = malloc( sizeof (char));发表评论,则会出现细分错误。

更改您的代码,如:

    char buf[1024];         /* input buffer */
    int numread;            /* number read from input */
    char *nextch;           /* where we left off */
    int rv;             /* return value of getint() */
    nextch = malloc ( sizeof( char) * 1024);

让我知道我是否正确理解了您的问题。