所以我很好奇为什么以下代码段保持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)
strtok()
/ strtok_r()
的第二个参数描述了 set 的分隔符,期望0
终止的char
数组,这是一个C-“字符串”。
来自strtok()
/strtok_r()
's man-page:
delim参数指定一组字节,用于分隔已解析字符串中的标记。
所以它的用法应该是:
const char deli[2] = {',', '\0'};
...
char * denomination = strtok_r(val, deli, &ptr);
甚至更直接:
const char deli[] = ",";
...
char * denomination = strtok_r(val, deli, &ptr);
或者只删除deli
的定义并执行:
char * denomination = strtok_r(val, ";", &ptr);
此外,代码应该在将结果传递给strtok_t()
之前检查对NULL
的调用是否返回atoi()
,因为后者在被NULL
投放时会失败。