Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C strtol帮助为什么返回0_C_Struct_Strtol - Fatal编程技术网

C strtol帮助为什么返回0

C strtol帮助为什么返回0,c,struct,strtol,C,Struct,Strtol,因此,我不明白为什么内置的strtol返回0。从手册中可以看出,如果无法转换,它将返回0。虽然对我来说太多了,但它应该正确地转换。这就是函数 struct coin * addCoins(char *val){ char *ptr =NULL; long int denomination = strtol(val, &ptr,10); long int count = strtol( &ptr,NULL, 10); printf("%d",

因此,我不明白为什么内置的strtol返回0。从手册中可以看出,如果无法转换,它将返回0。虽然对我来说太多了,但它应该正确地转换。这就是函数

struct coin * addCoins(char *val){
    char *ptr =NULL;
    long int denomination = strtol(val, &ptr,10);
    long int count = strtol( &ptr,NULL, 10);
        printf("%d",count);
    struct coin *k;
    k = malloc(sizeof(struct coin));
    k->denom = denomination;
    k->count = count;
    return k;
}
这将返回硬币面额的长整数,以及有多少硬币被存储在硬币类型的结构中。它具有以下
typedef

/* 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;
};
正在读取的文件的格式如下所示。 第一列是面额,第二列是计数

1000,3
500,4
200,20
100,30
50,5
20,3
10,40
5,20

分隔符是逗号。我们明确要求使用strtol,否则我将使用
strtok\u r

我提出的解决方案是在传递给strtol之前对字符串进行标记化,但设想有一种更优雅的方法来执行此操作

char *ptr =NULL;
char *ptrs =NULL;
const char *deli = ",";
char *denominations = strtok_r(val, deli, &ptrs);
char *counts = strtok_r(NULL, deli, &ptrs);

long int denomination = strtol(denominations, &ptr,10);
long int count = strtol( counts,NULL, 10);
你的代码

long int denomination = strtol(val, &ptr,10);
long int count = strtol( &ptr,NULL, 10);
第二行有一些问题

第一个参数
&ptr
应该是
ptr
。这是因为
strtol
需要一个指向char的简单指针作为其第一个参数。因此,尽管在第一次调用
strtol
时,符号AND是正确的,但在第二次调用中它是不正确的

第二个问题是,从strtol返回的
endptr
指向不属于第一个数字的第一个字符。换句话说,它指向逗号。由您决定是否将指针移过逗号

这就引出了另一个问题。在将指针移过逗号之前,必须确保它确实指向逗号。如果没有,那么就出了问题,你必须优雅地失败。由于函数返回指针,因此应返回
NULL
,以指示发生了错误

因此,您的函数应该是

struct coin * addCoins(char *val)
{
    char *ptr;
    long int denomination = strtol( val, &ptr, 10 );
    if ( ptr == val || *ptr != ',' )   // verify that we found the comma
        return NULL;
    ptr++;                             // advance the pointer past the comma

    char *endptr;
    long int count = strtol( ptr, &endptr, 10 );
    if ( endptr == ptr || *endptr != '\0' )   // verify that the second conversion succeeded
        return NULL;

    struct coin *k;
    k = malloc(sizeof(struct coin));
    k->denom = denomination;
    k->count = count;
    return k;
}

strtol
的第一个参数是
const char*
。由于
ptr
char*
&ptr
char**
。这显然是不对的。如果我不&ptr,我得到的错误是:从不兼容的指针类型[enabled by default]传递'strtol'的参数2显然他指的是你的第二个strtol。通过将它应用到第二个strtol,它仍然会产生相同的垃圾。1000,0 500,0 200,0 100,0 50,0 20,0 10,0 5,0@JoshuaTheeuf一次一只虫子。(提示:你认为这两个数字之间的逗号会发生什么变化?)我有点偏见的态度是“那些伸手去拿strtok_r()的人通常拿错了工具”。至少您正在使用
strtok_r()
,而不仅仅是
strtok()
;纯
strtok()
是更糟糕的“错误工具”。只要您从未将字符串文本传递给
addCoins()
函数,您将知道如何工作的代码-尽管您无论如何都不应该这样做,因为字符串文本应该被视为常量。
strtok_r()
的另一个问题是它会破坏输入字符串,如果有多个分隔符字符,则无法分析它找到的分隔符。