所以我很好奇为什么以下代码段保持segfaulting。它对我来说是正确的。
int * addCoins(char *val){
const char *deli = ",";
char *ptr =NULL;
char *denomination = strtok_r(val, deli, &ptr);
char *count = strtok_r(NULL, deli, &ptr);
int deno = atoi(denomination);
int cnt = atoi(count);
int *k;
k = malloc(sizeof(*k)*2);
k[0] = deno;
k[1] =cnt;
return k;
}
在main中调用函数addCoins。我不认为错误在于此,但老实说我对这个问题有点失落。
char* fileNameCoin = argv[2];
FILE *fileCoin;
fileCoin = fopen(fileNameCoin, "r+");
char bufCoin[256];
int i = 0;
//vmNode->next = NULL;
int *j;
while (fgets(bufCoin, sizeof bufCoin, fileCoin) != NULL) {
j = addCoins(bufCoin);
int deno = j[0];
switch(deno){
case 5:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 10:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 20:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 50:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 100:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 200:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 500:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
case 1000:
Coins[i].denom = j[0];
Coins[i].count = j[1];
break;
default:
break;
}
i++;
}
以下是文件的定义方式
1000,3
500,4
200,20
100,30
50,5
20,3
10,40
5,20
其中第一个数字是以美分为单位的面额,第二列是所述面额的数量。
这些是typedef:
/* The different denominations of coins available */
enum denomination
{
FIVE_CENTS, TEN_CENTS, TWENTY_CENTS, FIFTY_CENTS, ONE_DOLLAR,
TWO_DOLLARS, FIVE_DOLLARS, TEN_DOLLARS
};
/* Each coin in the coins array will have a denomination (20 cents,
* 50 cents, etc) and a count - how many of that coin do we have on hand
*/
struct coin
{
enum denomination denom;
unsigned count;
};
答案 0 :(得分:1)
老实说,您应该通过structs
更好地使用typedef
。示例(使用exename in.txt
调用):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* The different denominations of coins available */
enum denomination {
FIVE_CENTS, TEN_CENTS, TWENTY_CENTS, FIFTY_CENTS, ONE_DOLLAR,
TWO_DOLLARS, FIVE_DOLLARS, TEN_DOLLARS
};
typedef struct {
enum denomination denom;
unsigned int count;
} coin;
coin * addCoins(char *val) {
coin *k = malloc(sizeof(coin));
if( sscanf( val, "%d,%d", &(k->denom), &(k->count)) != 2 ) {
fprintf(stderr,"Two int values not found on line '%s' in input.\n", val);
free(k);
k=NULL;
}
return k;
}
int main(int argc, char *argv[])
{
coin Coins[100]={0};
char* fileNameCoin = argv[1];
FILE *fileCoin = fopen(fileNameCoin, "r+");
char bufCoin[256];
int i = 0;
coin *j;
if( fileCoin ) {
while(fgets(bufCoin, sizeof bufCoin, fileCoin) != NULL) {
j = addCoins(bufCoin);
if( j ) { // only add if 2 int values found on input line
Coins[i] = *j;
free(j);
printf("c: %d, %d\n", Coins[i].denom, Coins[i].count);
i++;
}
}
fclose(fileCoin);
}
else {
fprintf(stderr,"Unable to open file %s for input.\n",fileNameCoin);
}
}
答案 1 :(得分:0)
您已经对代码进行了更彻底的重新实现,这实际上非常好。这是一套应用于原始代码的清理工作;它表明程序中出现的任何问题都不在显示的代码中。
#define _XOPEN_SOURCE 700
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum denomination
{
FIVE_CENTS, TEN_CENTS, TWENTY_CENTS, FIFTY_CENTS, ONE_DOLLAR,
TWO_DOLLARS, FIVE_DOLLARS, TEN_DOLLARS
};
struct coin
{
enum denomination denom;
unsigned count;
};
static struct coin Coins[10];
static
int *addCoins(char *val)
{
const char *deli = ",";
char *ptr = NULL;
char *denomination = strtok_r(val, deli, &ptr);
char *count = strtok_r(NULL, deli, &ptr);
printf("D = %s, C = %s", denomination, count);
int deno = atoi(denomination);
int cnt = atoi(count);
printf("D = %d, C = %d\n", deno, cnt);
int *k = malloc(sizeof(*k) * 2);
if (k == 0)
{
fprintf(stderr, "Failed to allocate memory\n");
exit(1);
}
k[0] = deno;
k[1] = cnt;
return k;
}
int main(int argc, char **argv)
{
if (argc != 2)
{
fprintf(stderr, "Usage: %s file\n", argv[0]);
return 0;
}
char *fileNameCoin = argv[1];
FILE *fileCoin = fopen(fileNameCoin, "r+");
if (fileCoin == 0)
{
fprintf(stderr, "%s: failed to open file %s\n", argv[0], argv[1]);
return 0;
}
char bufCoin[256];
int i = 0;
while (fgets(bufCoin, sizeof bufCoin, fileCoin) != NULL)
{
int *j = addCoins(bufCoin);
int deno = j[0];
switch (deno)
{
case 5:
case 10:
case 20:
case 50:
case 100:
case 200:
case 500:
case 1000:
Coins[i].denom = j[0];
Coins[i].count = j[1];
printf("(%d,%d)\n", Coins[i].denom, Coins[i].count);
i++;
break;
default:
fprintf(stderr, "Unrecognized coin denomination (%d,%d)\n", j[0], j[1]);
break;
}
free(j);
}
return 0;
}
汇编:
gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Wold-style-declaration -Werror coins.c -o coins
#define _XOPEN_SOURCE 700
是宣传strtok_r()
所必需的。
示例运行:
D = 1000, C = 3
D = 1000, C = 3
(1000,3)
D = 500, C = 4
D = 500, C = 4
(500,4)
D = 200, C = 20
D = 200, C = 20
(200,20)
D = 100, C = 30
D = 100, C = 30
(100,30)
D = 50, C = 5
D = 50, C = 5
(50,5)
D = 20, C = 3
D = 20, C = 3
(20,3)
D = 10, C = 40
D = 10, C = 40
(10,40)
D = 5, C = 20
D = 5, C = 20
(5,20)