在家庭作业中不太有用的错误分割错误(核心转储)。

时间:2022-09-10 22:26:57

When compiling a program containing this particular function,

在编译包含这个函数的程序时,

/*
 * Function read_integer
 *
 * @Parameter CHAR* stringInt
 *
 * Parameter contains a string representing a struct integer.
 * Tokenizes the string by each character, converts each char
 * into an integer, and constructs a backwards linked list out
 * of the digits.
 *
 * @Return STRUCT* Integer
 */
struct integer* read_integer( char* stringInt )
{
    int i, n;
    struct integer *curr, *head;

    int numDigits = strlen( stringInt ); // Find the length of the struct integer
    char *tok;
    head = NULL;

    for( i = 0; i < numDigits; i++ )
    {
        tok = strtok( stringInt, NULL ); // Tokenize the string by each char
        n = atoi( tok[i] ); // Convert char to an integer

        curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
        curr->digit = n; // Digit of current node is assigned to n
        curr->next = head; // Move to the next node in the list.
        head = curr; // Move head up to the front of the list.
    }

    return head; // Return a pointer to the first node in the list.
}

I get the warning:

我得到了警告:

bigintII.c: In function ‘read_integer’:
bigintII.c:167: warning: passing argument 1 of ‘atoi’ makes pointer from integer without a cast
//usr/include/stdlib.h:148: note: expected ‘const char *’ but argument is of type ‘char’

I've tried a couple of different ways (that were mostly shots in the dark) to get rid of the warning, but to no avail. Can anybody point me in the right direction?

我尝试了几种不同的方法(大部分是在黑暗中拍摄)来摆脱警告,但都无济于事。有人能告诉我正确的方向吗?

---///---

- - - / / / - - - - - -

Original, dumb question below here, left because I don't want to be that guy.---

下面这个愚蠢的问题,因为我不想成为那样的人。

I'm trying to debug my assignment for CS1 so I can finish it and move onto something interesting (like working on my CLisp studies), but I've run into an error I can't get past. Now, I know the assignment isn't complete yet (i.e., it isn't going to do what I want it to even if I get it to run) but I don't want help with that (besides, what fun would that be?). If someone could just help me figure out why the following code, when compiled and executed, produces the useless (to me) Segmentation fault (core dumped), well, that'd be awesome.

我试着调试CS1的任务,这样我就可以完成它并转移到一些有趣的事情上(比如我的CLisp研究),但是我遇到了一个无法通过的错误。现在,我知道任务还没有完成。但我不想让它去做我想做的事情,但我不想帮助它(除此之外,那会有什么乐趣?)如果有人能帮我找出为什么下面的代码,在编译和执行时,产生了无用的(对我来说)分割错误(核心转储),那就太棒了。

/*
 * File:   struct integer.c

 * Description: Assignment in using Linked Lists
 * in order to perform struct integer addition and subtraction.
 *
 * Created on September 1, 2010, 11:38 AM
 */

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


// Constant Definitions
#define ADD 1
#define SUB 2

// Output file
char *fName = "out.txt";
FILE *outFile;


/*
 * Create a prototype of a single
 * node in the Linked List.
 * Each node will represent a single
 * integer comprising one part of a struct integer.
 */
struct integer
{
    int digit;

    struct integer *next;
};


// Function Prototypes
struct integer* read_integer( char *stringInt );
struct integer* add( struct integer *p, struct integer *q );
struct integer* subtract( struct integer *p, struct integer *q);

int compare( struct integer *p, struct integer *q );

void print( struct integer *p );


// Main function
int main( )
{
    //Variable initialization

    /*
     * Initialize pointers to the linked lists.
     * One, *head, will always point to the
     * first element, the head, of the list.
     * The other element, *curr, will point to the
     * node currently being accessed, and will be
     * used to traverse the list.
     */
    struct integer* pHead;
    struct integer* qHead;
    struct integer* tHead; // Used to contain the total

    int numOps, oper, i;
    const char *fileName = "struct integer.txt";
    char bigintstr[200];
    FILE *inputFile;

    // Open output file
    outFile = fopen(fName, "a+");


    // Open up the input file for reading
    inputFile = fopen(fileName, "r");

    // Read in the number of operations to be performed
    fscanf(inputFile, "%d", &numOps);

    /*
     * For each operation that must be performed,
     * construct a linked list for each of the
     * struct integers in the file. Then, perform the operation
     * indicated by the digit preceding them.
     */
    for( i = 0; i < numOps; i++ )
    {
        // Read in the number that dictates operation
        fscanf(inputFile, "%d", &oper);

        // Read in the first struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer string to read_integer()
         * in order to construct a linked list out of it.
         */
        pHead = read_integer( bigintstr );

        // Read in second struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer str to read_integer()
         * in order to construct a linked list out of it.
         */
         qHead = read_integer( bigintstr );

         /*
          * Depending on the operation to be performed,
          * call the corresponding function.
          */
         switch( oper )
         {
             case ADD:
                 tHead = add( pHead, qHead );
                 break;
             case SUB:
                 tHead = subtract( pHead, qHead );
                 break;
             default:
                 printf("Invalid operation parameter.\n");
         }

         print( pHead ); // Print out the first struct integer
         fprintf(outFile, " + ");
         print( qHead ); // Print out the second struct integer
         fprintf(outFile, " = ");
         print( tHead ); // Print out the sum/difference struct integer
         fprintf(outFile, "\n"); // Move to next line for next instruction set
    }
    fclose(inputFile);

    //system(PAUSE);
    return 0;
}


// Function Definitions

/*
 * Function read_integer
 *
 * @Parameter CHAR* stringInt
 *
 * Parameter contains a string representing a struct integer.
 * Tokenizes the string by each character, converts each char
 * into an integer, and constructs a backwards linked list out
 * of the digits.
 *
 * @Return STRUCT* Integer
 */
struct integer* read_integer( char* stringInt )
{
    int i, n;
    struct integer *curr, *head;

    int numDigits = strlen( stringInt ); // Find the length of the struct integer
    char *tok;
    head = NULL;

    for( i = 0; i < numDigits; i++ )
    {
        tok = strtok( stringInt, NULL ); // Tokenize the string by each char
        n = atoi( tok[i] ); // Convert char to an integer

        curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
        curr->digit = n; // Digit of current node is assigned to n
        curr->next = head; // Move to the next node in the list.
        head = curr; // Move head up to the front of the list.
    }

    return head; // Return a pointer to the first node in the list.
}

/*
 * Function print
 *
 * @Parameter STRUCT* Integer
 *
 * Given a linked list, will traverse through
 * the nodes and print out, one at a time,
 * the digits comprising the struct integer that the
 * linked list represents.
 *
 * TODO: Print to file
 */
void print( struct integer *p )
{    
    while( p )
    {
        fprintf(outFile, "%d", p->digit);
        p = p->next;
    }
}

/*
 * Function add
 *
 * @Paramater STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing
 * big integers stored in reversed order,
 * and returns a linked list containing
 * the sum of the two integers.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* add( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *sHead, *sCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    sHead = NULL;

    while( p )
    {
        sCurr = ( struct integer* ) malloc (sizeof(struct integer));
        sCurr->digit = p->digit + q->digit + carry;
        sCurr->next = sHead;
        sHead = sCurr;

        carry = 0;

        /*
         * If the current digits sum to greater than 9,
         * create a carry value and replace the current
         * value with value mod 10.
         */
        if( sCurr->digit > 9 )
        {
            carry = 1;
            sCurr->digit = sCurr->digit % 10;
        }

        /*
         * If the most significant digits of the numbers
         * sum to 10 or greater, create an extra node
         * at the end of the sum list and assign it the
         * value of 1.
         */
        if( carry == 1 && sCurr->next == NULL )
        {
            struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer));
            sCarry->digit = 1;
            sCarry->next = NULL;
            sCurr->next = sCarry;
        }

        p = p->next;
        q = q->next;
    }

    return sHead;
}

/*
 * Function subtract
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing struct integers.
 * Traverses through the lists, subtracting each
 * digits from the subsequent nodes to form a new
 * struct integer, and then returns the newly formed
 * linked list.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* subtract( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *dHead, *dCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    dHead = NULL;

    while( p )
    {
        dCurr = (struct integer*) malloc (sizeof(struct integer));
        dCurr->digit = p->digit - q->digit - carry;
        dCurr->next = dHead;
        dHead = dCurr;

        if( dCurr->digit < 0 )
        {
            dCurr->digit += 10;
            carry = 1;
        }

        if( dCurr->next == NULL && carry == 1 )
        {
            struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer));
            dCarry->digit = -1;
            dCarry->next = NULL;
            dCurr->next = dCarry;
        }

        p = p->next;
        q = q->next;
    }

    return dHead;
}

/*
 * Function compare
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes in two linked lists representing struct integers.
 * Traverses the lists one at a time, comparing the
 * digits.
 *
 * Case: p < q
 * @Return -1
 *
 * Case: p == q
 * @Return 0
 *
 * Case: p > q
 * @Return 1
 * 
 * TODO Comment me
 */
int compare( struct integer *p, struct integer *q )
{
    struct integer *pHead, *qHead;
    int comp = 0;

    pHead = p;
    qHead = q;

    while( p )
    {
        if( p->digit > q->digit )
        {
            comp = 1;
        }

        if( p->digit < q->digit )
        {
            comp = -1;
        }

        p = p->next;
        q = q->next;
    }

    return comp;
}

I'm sorry that there's a lot to wade through, I'm just trying to get in the habit of over-documenting my code because I like to go back and read through stuff I've written to review concepts. The actual program itself is fairly straightforward, though (if not broken, haha).

我很抱歉有很多事情要处理,我只是想养成过度记录代码的习惯,因为我喜欢回去阅读我写的东西来复习概念。实际的程序本身是相当简单的,尽管(如果没有中断,哈哈)。

2 个解决方案

#1


4  

compiling it with gcc gives this:

将其编译为gcc提供如下:

test.c: In function ‘read_integer’: test.c:165: warning: passing argument 1 of ‘atoi’ makes pointer from integer without a cast /usr/include/stdlib.h:148: note: expected ‘const char *’ but argument is of type ‘char’

测试。在函数' read_integer ': test。c:165:警告:通过参数1的' atoi '使指针从整数而没有一个cast /usr/include/stdlib。注:预期' const char * '但参数是' char '

this is 164/165

这是164/165

    tok = strtok( stringInt, NULL ); // Tokenize the string by each char
    n = atoi( tok[i] ); // Convert char to an integer

should be

应该是

   n =  stringInt - '0'; // Convert char to an integer

the tok variable is now pointless. it doesn't crash anymore with me, and it does find the correct answer(1 + 1 = 2),

tok变量现在毫无意义。它不再和我一起崩溃了,它确实找到了正确的答案(1 + 1 = 2)

furthermore you forgot to close outputFile at the end of your program. and you apparently open the outfile in append mode(wich isn't bad, it just caught me by surprise)

此外,您在程序结束时忘记关闭outputFile。显然,你在append模式中打开了outfile(它并不坏,它只是让我大吃一惊)

then there's another inconsistency, your add function reverses the order in which your numbers are stored wich means that the input numbers are printed in reverse order whilst the anwer is printed in the correct order.

然后还有另一个不一致的地方,你的添加函数会颠倒你的数字存储的顺序,这意味着输入的数字是按相反的顺序打印的,而anwer是按正确的顺序打印的。

I fixed those now:

我现在固定这些:

/*
 * File:   struct integer.c

 * Description: Assignment in using Linked Lists
 * in order to perform struct integer addition and subtraction.
 *
 * Created on September 1, 2010, 11:38 AM
 */

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


// Constant Definitions
#define ADD 1
#define SUB 2

// Output file
char *fName = "out.txt";
FILE *outFile;


/*
 * Create a prototype of a single
 * node in the Linked List.
 * Each node will represent a single
 * integer comprising one part of a struct integer.
 */
struct integer
{
    int digit;

    struct integer *next;
};


// Function Prototypes
struct integer* read_integer( char *stringInt );
struct integer* add( struct integer *p, struct integer *q );
struct integer* subtract( struct integer *p, struct integer *q);

int compare( struct integer *p, struct integer *q );

void print( struct integer *p );


// Main function
int main( )
{
    //Variable initialization

    /*
     * Initialize pointers to the linked lists.
     * One, *head, will always point to the
     * first element, the head, of the list.
     * The other element, *curr, will point to the
     * node currently being accessed, and will be
     * used to traverse the list.
     */
    struct integer* pHead;
    struct integer* qHead;
    struct integer* tHead; // Used to contain the total

    int numOps, oper, i;
    const char *fileName = "struct_integer.txt";
    char bigintstr[200];
    FILE *inputFile;

    // Open output file
    outFile = fopen(fName, "a+");


    // Open up the input file for reading
    inputFile = fopen(fileName, "r");

    // Read in the number of operations to be performed
    fscanf(inputFile, "%d", &numOps);

    /*
     * For each operation that must be performed,
     * construct a linked list for each of the
     * struct integers in the file. Then, perform the operation
     * indicated by the digit preceding them.
     */
    for( i = 0; i < numOps; i++ )
    {
        // Read in the number that dictates operation
        fscanf(inputFile, "%d", &oper);

        // Read in the first struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer string to read_integer()
         * in order to construct a linked list out of it.
         */
        pHead = read_integer( bigintstr );

        // Read in second struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer str to read_integer()
         * in order to construct a linked list out of it.
         */
         qHead = read_integer( bigintstr );

         /*
          * Depending on the operation to be performed,
          * call the corresponding function.
          */
         switch( oper )
         {
             case ADD:
                 tHead = add( pHead, qHead );
                 break;
             case SUB:
                 tHead = subtract( pHead, qHead );
                 break;
             default:
                 printf("Invalid operation parameter.\n");
         }

         print( pHead ); // Print out the first struct integer
         fprintf(outFile, " + ");
         print( qHead ); // Print out the second struct integer
         fprintf(outFile, " = ");
         print( tHead ); // Print out the sum/difference struct integer
         fprintf(outFile, "\n"); // Move to next line for next instruction set
    }
    fclose(inputFile);
    fclose(outFile);
    //system(PAUSE);
    return 0;
}


// Function Definitions

/*
 * Function read_integer
 *
 * @Parameter CHAR* stringInt
 *
 * Parameter contains a string representing a struct integer.
 * Tokenizes the string by each character, converts each char
 * into an integer, and constructs a backwards linked list out
 * of the digits.
 *
 * @Return STRUCT* Integer
 */
struct integer* read_integer( char* stringInt )
{
    int i, n;
    struct integer *curr, *head;

    int numDigits = strlen( stringInt ); // Find the length of the struct integer
    char *tok;
    head = NULL;

    for( i = 0; i < numDigits; i++ )
    {
        n =  stringInt[i] - '0'; // Convert char to an integer

        curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
        curr->digit = n; // Digit of current node is assigned to n
        curr->next = head; // Move to the next node in the list.
        head = curr; // Move head up to the front of the list.
    }

    return head; // Return a pointer to the first node in the list.
}

void reverse (struct integer **p){
    if((*p)->next==0) return;
    struct integer *i=*p,*j;
    while(i->next){
        j=i;
        i=i->next;
    }//i is now the tail;
    i->next=j;
    j->next=0;
    reverse(p);
    *p=i;
}

/*
 * Function print
 *
 * @Parameter STRUCT* Integer
 *
 * Given a linked list, will traverse through
 * the nodes and print out, one at a time,
 * the digits comprising the struct integer that the
 * linked list represents.
 *
 * TODO: Print to file
 */
void print( struct integer *p )
{
    struct integer *head=p;
    reverse(&p);    
    while( p )
    {
        fprintf(outFile, "%d", p->digit);
        p = p->next;
    }
    reverse(&head);
}


/*
 * Function add
 *
 * @Paramater STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing
 * big integers stored in reversed order,
 * and returns a linked list containing
 * the sum of the two integers.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* add( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *sHead, *sCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    sHead = NULL;

    while( p )
    {
        sCurr = ( struct integer* ) malloc (sizeof(struct integer));
        sCurr->digit = p->digit + q->digit + carry;
        sCurr->next = sHead;
        sHead = sCurr;

        carry = 0;

        /*
         * If the current digits sum to greater than 9,
         * create a carry value and replace the current
         * value with value mod 10.
         */
        if( sCurr->digit > 9 )
        {
            carry = 1;
            sCurr->digit = sCurr->digit % 10;
        }

        /*
         * If the most significant digits of the numbers
         * sum to 10 or greater, create an extra node
         * at the end of the sum list and assign it the
         * value of 1.
         */
        if( carry == 1 && sCurr->next == NULL )
        {
            struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer));
            sCarry->digit = 1;
            sCarry->next = NULL;
            sCurr->next = sCarry;
        }

        p = p->next;
        q = q->next;
    }
    reverse(&sHead);
    return sHead;
}



/*
 * Function subtract
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing struct integers.
 * Traverses through the lists, subtracting each
 * digits from the subsequent nodes to form a new
 * struct integer, and then returns the newly formed
 * linked list.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* subtract( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *dHead, *dCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    dHead = NULL;

    while( p )
    {
        dCurr = (struct integer*) malloc (sizeof(struct integer));
        dCurr->digit = p->digit - q->digit - carry;
        dCurr->next = dHead;
        dHead = dCurr;

        if( dCurr->digit < 0 )
        {
            dCurr->digit += 10;
            carry = 1;
        }

        if( dCurr->next == NULL && carry == 1 )
        {
            struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer));
            dCarry->digit = -1;
            dCarry->next = NULL;
            dCurr->next = dCarry;
        }

        p = p->next;
        q = q->next;
    }

    return dHead;
}

/*
 * Function compare
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes in two linked lists representing struct integers.
 * Traverses the lists one at a time, comparing the
 * digits.
 *
 * Case: p < q
 * @Return -1
 *
 * Case: p == q
 * @Return 0
 *
 * Case: p > q
 * @Return 1
 * 
 * TODO Comment me
 */
int compare( struct integer *p, struct integer *q )
{
    struct integer *pHead, *qHead;
    int comp = 0;

    pHead = p;
    qHead = q;

    while( p )
    {
        if( p->digit > q->digit )
        {
            comp = 1;
        }

        if( p->digit < q->digit )
        {
            comp = -1;
        }

        p = p->next;
        q = q->next;
    }

    return comp;
}

i wrote reverse for you:

我为你写了相反的东西:

void reverse (struct integer **p){
    if((*p)->next==0) return;
    struct integer *i=*p,*j;
    while(i->next){
        j=i;
        i=i->next;
    }//i is now the tail;
    // 1->2->3->4->NIL

    i->next=j;
    // 1 -> 2 -> 3 <-> 4

    j->next=0;
    // 1 -> 3 -> 3 <- 4
    //           |
    //           v
    //          NIL
    reverse(p);// p looks like 1 -> 2 -> 3 now recurse
    *p=i;
}

#2


3  

Your problem is caused by passing the wrong thing to atoi. atoi expects a string, which as you know in C is a char pointer. You're passing a single char, which is not a char pointer. atoi attempts to treat the value of the character as a memory address, which is almost certainly an address you're not allowed to access, so your program goes bang.

你的问题是由于把错误的东西传递给了你。atoi期望一个字符串,正如您在C中所知道的,它是一个char指针。您传递的是单个字符,而不是一个char指针。atoi试图将字符的值作为一个内存地址来处理,这几乎肯定是一个您不允许访问的地址,因此您的程序将会爆炸。

To get the numerical value of a char containing an ASCII digit, subtract '0' from it, ie change

要获得包含ASCII数字的字符的数值,可以从其上减去“0”。

n = atoi( tok[i] );

to

n = tok[i] - '0';

But you don't need strtok:

但你不需要strtok:

for (i = 0; i < numDigits; i++) {
    n = stringInt[i] - '0';
    // etc
}

#1


4  

compiling it with gcc gives this:

将其编译为gcc提供如下:

test.c: In function ‘read_integer’: test.c:165: warning: passing argument 1 of ‘atoi’ makes pointer from integer without a cast /usr/include/stdlib.h:148: note: expected ‘const char *’ but argument is of type ‘char’

测试。在函数' read_integer ': test。c:165:警告:通过参数1的' atoi '使指针从整数而没有一个cast /usr/include/stdlib。注:预期' const char * '但参数是' char '

this is 164/165

这是164/165

    tok = strtok( stringInt, NULL ); // Tokenize the string by each char
    n = atoi( tok[i] ); // Convert char to an integer

should be

应该是

   n =  stringInt - '0'; // Convert char to an integer

the tok variable is now pointless. it doesn't crash anymore with me, and it does find the correct answer(1 + 1 = 2),

tok变量现在毫无意义。它不再和我一起崩溃了,它确实找到了正确的答案(1 + 1 = 2)

furthermore you forgot to close outputFile at the end of your program. and you apparently open the outfile in append mode(wich isn't bad, it just caught me by surprise)

此外,您在程序结束时忘记关闭outputFile。显然,你在append模式中打开了outfile(它并不坏,它只是让我大吃一惊)

then there's another inconsistency, your add function reverses the order in which your numbers are stored wich means that the input numbers are printed in reverse order whilst the anwer is printed in the correct order.

然后还有另一个不一致的地方,你的添加函数会颠倒你的数字存储的顺序,这意味着输入的数字是按相反的顺序打印的,而anwer是按正确的顺序打印的。

I fixed those now:

我现在固定这些:

/*
 * File:   struct integer.c

 * Description: Assignment in using Linked Lists
 * in order to perform struct integer addition and subtraction.
 *
 * Created on September 1, 2010, 11:38 AM
 */

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


// Constant Definitions
#define ADD 1
#define SUB 2

// Output file
char *fName = "out.txt";
FILE *outFile;


/*
 * Create a prototype of a single
 * node in the Linked List.
 * Each node will represent a single
 * integer comprising one part of a struct integer.
 */
struct integer
{
    int digit;

    struct integer *next;
};


// Function Prototypes
struct integer* read_integer( char *stringInt );
struct integer* add( struct integer *p, struct integer *q );
struct integer* subtract( struct integer *p, struct integer *q);

int compare( struct integer *p, struct integer *q );

void print( struct integer *p );


// Main function
int main( )
{
    //Variable initialization

    /*
     * Initialize pointers to the linked lists.
     * One, *head, will always point to the
     * first element, the head, of the list.
     * The other element, *curr, will point to the
     * node currently being accessed, and will be
     * used to traverse the list.
     */
    struct integer* pHead;
    struct integer* qHead;
    struct integer* tHead; // Used to contain the total

    int numOps, oper, i;
    const char *fileName = "struct_integer.txt";
    char bigintstr[200];
    FILE *inputFile;

    // Open output file
    outFile = fopen(fName, "a+");


    // Open up the input file for reading
    inputFile = fopen(fileName, "r");

    // Read in the number of operations to be performed
    fscanf(inputFile, "%d", &numOps);

    /*
     * For each operation that must be performed,
     * construct a linked list for each of the
     * struct integers in the file. Then, perform the operation
     * indicated by the digit preceding them.
     */
    for( i = 0; i < numOps; i++ )
    {
        // Read in the number that dictates operation
        fscanf(inputFile, "%d", &oper);

        // Read in the first struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer string to read_integer()
         * in order to construct a linked list out of it.
         */
        pHead = read_integer( bigintstr );

        // Read in second struct integer into a string
        fscanf(inputFile, "%s", bigintstr);

        /*
         * Pass the struct integer str to read_integer()
         * in order to construct a linked list out of it.
         */
         qHead = read_integer( bigintstr );

         /*
          * Depending on the operation to be performed,
          * call the corresponding function.
          */
         switch( oper )
         {
             case ADD:
                 tHead = add( pHead, qHead );
                 break;
             case SUB:
                 tHead = subtract( pHead, qHead );
                 break;
             default:
                 printf("Invalid operation parameter.\n");
         }

         print( pHead ); // Print out the first struct integer
         fprintf(outFile, " + ");
         print( qHead ); // Print out the second struct integer
         fprintf(outFile, " = ");
         print( tHead ); // Print out the sum/difference struct integer
         fprintf(outFile, "\n"); // Move to next line for next instruction set
    }
    fclose(inputFile);
    fclose(outFile);
    //system(PAUSE);
    return 0;
}


// Function Definitions

/*
 * Function read_integer
 *
 * @Parameter CHAR* stringInt
 *
 * Parameter contains a string representing a struct integer.
 * Tokenizes the string by each character, converts each char
 * into an integer, and constructs a backwards linked list out
 * of the digits.
 *
 * @Return STRUCT* Integer
 */
struct integer* read_integer( char* stringInt )
{
    int i, n;
    struct integer *curr, *head;

    int numDigits = strlen( stringInt ); // Find the length of the struct integer
    char *tok;
    head = NULL;

    for( i = 0; i < numDigits; i++ )
    {
        n =  stringInt[i] - '0'; // Convert char to an integer

        curr = (struct integer *) malloc (sizeof( struct integer )); // Allocate memory for node
        curr->digit = n; // Digit of current node is assigned to n
        curr->next = head; // Move to the next node in the list.
        head = curr; // Move head up to the front of the list.
    }

    return head; // Return a pointer to the first node in the list.
}

void reverse (struct integer **p){
    if((*p)->next==0) return;
    struct integer *i=*p,*j;
    while(i->next){
        j=i;
        i=i->next;
    }//i is now the tail;
    i->next=j;
    j->next=0;
    reverse(p);
    *p=i;
}

/*
 * Function print
 *
 * @Parameter STRUCT* Integer
 *
 * Given a linked list, will traverse through
 * the nodes and print out, one at a time,
 * the digits comprising the struct integer that the
 * linked list represents.
 *
 * TODO: Print to file
 */
void print( struct integer *p )
{
    struct integer *head=p;
    reverse(&p);    
    while( p )
    {
        fprintf(outFile, "%d", p->digit);
        p = p->next;
    }
    reverse(&head);
}


/*
 * Function add
 *
 * @Paramater STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing
 * big integers stored in reversed order,
 * and returns a linked list containing
 * the sum of the two integers.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* add( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *sHead, *sCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    sHead = NULL;

    while( p )
    {
        sCurr = ( struct integer* ) malloc (sizeof(struct integer));
        sCurr->digit = p->digit + q->digit + carry;
        sCurr->next = sHead;
        sHead = sCurr;

        carry = 0;

        /*
         * If the current digits sum to greater than 9,
         * create a carry value and replace the current
         * value with value mod 10.
         */
        if( sCurr->digit > 9 )
        {
            carry = 1;
            sCurr->digit = sCurr->digit % 10;
        }

        /*
         * If the most significant digits of the numbers
         * sum to 10 or greater, create an extra node
         * at the end of the sum list and assign it the
         * value of 1.
         */
        if( carry == 1 && sCurr->next == NULL )
        {
            struct integer *sCarry = ( struct integer* ) malloc (sizeof(struct integer));
            sCarry->digit = 1;
            sCarry->next = NULL;
            sCurr->next = sCarry;
        }

        p = p->next;
        q = q->next;
    }
    reverse(&sHead);
    return sHead;
}



/*
 * Function subtract
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes two linked lists representing struct integers.
 * Traverses through the lists, subtracting each
 * digits from the subsequent nodes to form a new
 * struct integer, and then returns the newly formed
 * linked list.
 *
 * @Return STRUCT* Integer
 * 
 * TODO Comment me
 */
struct integer* subtract( struct integer *p, struct integer *q )
{
    int carry = 0;

    struct integer *dHead, *dCurr;
    struct integer *pHead, *qHead;

    pHead = p;
    qHead = q;

    dHead = NULL;

    while( p )
    {
        dCurr = (struct integer*) malloc (sizeof(struct integer));
        dCurr->digit = p->digit - q->digit - carry;
        dCurr->next = dHead;
        dHead = dCurr;

        if( dCurr->digit < 0 )
        {
            dCurr->digit += 10;
            carry = 1;
        }

        if( dCurr->next == NULL && carry == 1 )
        {
            struct integer *dCarry = (struct integer*) malloc (sizeof(struct integer));
            dCarry->digit = -1;
            dCarry->next = NULL;
            dCurr->next = dCarry;
        }

        p = p->next;
        q = q->next;
    }

    return dHead;
}

/*
 * Function compare
 *
 * @Parameter STRUCT* Integer
 * @Parameter STRUCT* Integer
 *
 * Takes in two linked lists representing struct integers.
 * Traverses the lists one at a time, comparing the
 * digits.
 *
 * Case: p < q
 * @Return -1
 *
 * Case: p == q
 * @Return 0
 *
 * Case: p > q
 * @Return 1
 * 
 * TODO Comment me
 */
int compare( struct integer *p, struct integer *q )
{
    struct integer *pHead, *qHead;
    int comp = 0;

    pHead = p;
    qHead = q;

    while( p )
    {
        if( p->digit > q->digit )
        {
            comp = 1;
        }

        if( p->digit < q->digit )
        {
            comp = -1;
        }

        p = p->next;
        q = q->next;
    }

    return comp;
}

i wrote reverse for you:

我为你写了相反的东西:

void reverse (struct integer **p){
    if((*p)->next==0) return;
    struct integer *i=*p,*j;
    while(i->next){
        j=i;
        i=i->next;
    }//i is now the tail;
    // 1->2->3->4->NIL

    i->next=j;
    // 1 -> 2 -> 3 <-> 4

    j->next=0;
    // 1 -> 3 -> 3 <- 4
    //           |
    //           v
    //          NIL
    reverse(p);// p looks like 1 -> 2 -> 3 now recurse
    *p=i;
}

#2


3  

Your problem is caused by passing the wrong thing to atoi. atoi expects a string, which as you know in C is a char pointer. You're passing a single char, which is not a char pointer. atoi attempts to treat the value of the character as a memory address, which is almost certainly an address you're not allowed to access, so your program goes bang.

你的问题是由于把错误的东西传递给了你。atoi期望一个字符串,正如您在C中所知道的,它是一个char指针。您传递的是单个字符,而不是一个char指针。atoi试图将字符的值作为一个内存地址来处理,这几乎肯定是一个您不允许访问的地址,因此您的程序将会爆炸。

To get the numerical value of a char containing an ASCII digit, subtract '0' from it, ie change

要获得包含ASCII数字的字符的数值,可以从其上减去“0”。

n = atoi( tok[i] );

to

n = tok[i] - '0';

But you don't need strtok:

但你不需要strtok:

for (i = 0; i < numDigits; i++) {
    n = stringInt[i] - '0';
    // etc
}