我创建了一个程序,要求读取包含银行帐户和交易历史记录的CSV文件。要访问某些信息,我有一个函数getfield
,该函数逐个令牌读取每个行令牌:
const char* getfield(char* line, int num)
{
const char *tok;
for (tok = strtok(line, ",");
tok && *tok;
tok = strtok(NULL, ",\n"))
{
if (!--num)
return tok;
}
return NULL;
}
我稍后将在我的代码中使用它来访问帐号(在位置2)和交易金额(在位置4):
...
while (fgets(line, 1024, fp))
{
char* tmp = strdup(line);
//check if account number already exists
char *acc = (char*) getfield(tmp, 2);
char *txAmount = (char*)getfield(tmp, 4);
printf("%s\n", txAmount);
//int n =1;
if (acc!=NULL && atoi(acc)== accNum && txAmount !=NULL){
if(n<fileSize)
{
total[n]= (total[n-1]+atof(txAmount));
printf("%f", total[n]);
n++;
}
}
free(tmp1); free(tmp2);
}
...
char *acc = (char*) getfield(tmp, 2)
似乎没有问题,但是当我将getfield
用作char *txAmount = (char*)getfield(tmp, 4)
时,下面的打印语句表明我一直有NULL
。对于上下文,文件当前读取为(第一行为空):
AC,1024,John Doe
TX,1024,2020-02-12,334.519989
TX,1024,2020-02-12,334.519989
TX,1024,2020-02-12,334.519989
我以前曾问过是否需要在我的代码的另一部分(free(acc)
)中使用Free() pointer error while casting from const char*,并且答案似乎是否定的,但是我希望这个问题能提供更好的上下文。这不是释放txAmount
的问题吗?任何帮助是极大的赞赏 !
(此外,如果有人对标题有更好的建议,请让我知道我该如何措辞更好,我是堆栈溢出的新手)
您的getfield
功能修改其输入。因此,当再次在getfield
上调用tmp
时,您并没有在正确的字符串上调用它。
[为了方便起见,您可能想制作一个getfield
函数,但不修改其输入。这将是低效的,但我认为性能或效率对您的代码并不特别重要。 getfield
函数将在其输入上调用strdup
,提取要返回的字符串,在其上调用strdup
,free
原始输入的重复项,然后将指针返回到找到的字段的重复项。调用者必须free
返回的指针。
问题是strtok用'\0'
替换找到的定界符。您需要获取该行的新副本。或者使用getfield (NULL, 2)
从上次中断的地方继续。