不太有用的错误 – 家庭作业中的分段错误(核心转储)
编译包含此特定函数的程序时,
/* * 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 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. }
我收到警告:
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'
我尝试了几种不同的方式(主要是在黑暗中拍摄)以摆脱警告,但无济于事。 任何人都能指出我正确的方向吗?
— /// —
下面的原始,愚蠢的问题,因为我不想成为那个人而离开了.—
我正在尝试调试我对CS1的任务,所以我可以完成它并进入一些有趣的事情(比如我的CLisp研究),但是我遇到了一个我无法理解的错误。 现在,我知道任务尚未完成(即,即使我让它运行也不会做我想要的事情)但是我不想要那个帮助(此外,那将是多么有趣是?)。 如果有人可以帮我弄清楚为什么下面的代码在编译和执行时会产生无用的(对我来说) Segmentation fault (core dumped)
,那就太棒了。
/* * 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 #include #include // 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 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 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 * * 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 digit ) { comp = -1; } p = p->next; q = q->next; } return comp; }
我很抱歉有很多东西可以解决,我只是想养成过度记录我的代码的习惯,因为我喜欢回过头来阅读我写的东西以回顾概念。 实际的程序本身是相当简单的(如果没有打破,哈哈)。
用gcc编译它给出了这个:
test.c:在函数’read_integer’中:test.c:165:警告:传递’atoi’的参数1使得整数指针没有强制转换/usr/include/stdlib.h:148:注意:期望’const char * ‘但参数是’char’类型
这是164/165
tok = strtok( stringInt, NULL ); // Tokenize the string by each char n = atoi( tok[i] ); // Convert char to an integer
应该
n = stringInt - '0'; // Convert char to an integer
tok变量现在毫无意义。 它不会再崩溃了,它确实找到了正确的答案(1 + 1 = 2),
此外,您忘记在程序结束时关闭outputFile。 你显然在追加模式下打开outfile(这不错,它让我感到惊讶)
然后还有另一个不一致的地方,你的添加function会反转你的号码存储的顺序,这意味着输入的数字会以相反的顺序打印,同时按正确的顺序打印anwer。
我现在修好了:
/* * 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 #include #include // 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; }
我为你写了反向:
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; }
你的问题是由错误的东西传递给atoi
引起的。 atoi
需要一个字符串,如你所知,在C中是一个字符指针。 你传递的是一个char,它不是char指针。 atoi
试图将字符的值视为内存地址,这几乎肯定是一个你不允许访问的地址,所以你的程序会爆炸。
要获取包含ASCII数字的char
的数值,请从中减去'0'
,即更改
n = atoi( tok[i] );
至
n = tok[i] - '0';
但你不需要strtok
:
for (i = 0; i < numDigits; i++) { n = stringInt[i] - '0'; // etc }