创建strchr()的简化版本

时间:2017-02-03 07:28:32

标签: c

尝试创建一个简单的函数来查找字符串中的单个字符"就像strchr()那样",我做了以下内容:

char* findchar(char* str, char c)
{
    char* position = NULL;
    int i = 0;
    for(i = 0; str[i]!='\0';i++)
    {
        if(str[i] == c)
        {
            position = &str[i];
            break;
        }
    }
    return position;
}

到目前为止它的确有效。但是,当我看到strchr()的原型时:

char *strchr(const char *str, int c);

第二个参数是int?我很想知道..为什么不是炭?这是否意味着我们可以使用int来存储字符,就像我们使用char一样?

这让我想到了第二个问题,我试图改变我的功能以接受一个int作为第二个参数......但是我不确定这样做是否正确和安全:

char* findchar(char* str, int c)
{
    char* position = NULL;
    int i = 0;
    for(i = 0; str[i]!='\0';i++)
    {
        if(str[i] == c) //Specifically, is this line correct? Can we test an int against a char? 
        {
            position = &str[i];
            break;
        }
    }
    return position;
}

2 个答案:

答案 0 :(得分:6)

在ANSI C89之前,声明的函数没有原型。当时strchr的声明看起来像这样:

char *strchr();

那就是它。根本没有声明参数。相反,有这些简单的规则:

  • 所有指针都作为参数传递给 - 是
  • 范围小于int的所有整数值都将转换为int
  • 所有浮点值都转换为double

所以当你打电话给strchr时,真正发生的是:

strchr(str, (int)chr);

引入ANSI C89时,必须保持向后兼容性。因此,它将strchr的原型定义为:

char *strchr(const char *str, int chr);

这会保留上述示例调用的确切行为,包括转换为int。这很重要,因为实现可能会定义传递char参数的工作方式与传递int参数不同,这在8位平台上是有意义的。

答案 1 :(得分:5)

考虑fgetc()的返回值,unsigned charEOF范围内的值,某些负值。这是传递给strchr()的值。

@Roland Illig对导致int chstrchr()一起使用的历史记录进行了非常好的解释。

OP的代码失败/有以下问题。

1)char* str被视为unsigned char *str符合§7.23.1.13

  

对于本子条款中的所有函数,每个字符都应被解释为具有unsigned char类型

2)i应为size_t,以处理字符数组的整个范围。

3)出于strchr()的目的,空字符被视为搜索的一部分。

  

终止空字符被认为是字符串的一部分。

4)最好使用conststr不会更改。

char* findchar(const char* str, int c)     {
    const char* position = NULL;
    size_t i = 0;
    for(i = 0; ;i++) {
        if((unsigned char) str[i] == c) {
            position = &str[i];
            break;
        }
        if (str[i]=='\0') break;
    }
    return (char *) position;
}

更多细节

  

strchr函数在c指向的字符串中定位char(转换为s)的第一个匹配项。 C11dr§7.23.5.22

所以int c被视为char。这可能意味着

        if((unsigned char) str[i] == (char) c) {

但我认为这意味着:

        if((unsigned char) str[i] == (unsigned char)(char) c) {

或只是

        if((unsigned char) str[i] == (unsigned char)c) {