为了创建一个简单的函数来查找字符串中的单个字符“类似strchr() like”,我执行了以下操作:
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来存储字符,就像使用字符一样?
这就引出了第二个问题,我试图改变我的函数,接受一个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;
}发布于 2017-02-03 08:13:14
考虑fgetc()的返回值,在unsigned char和EOF范围内的值,一些负值。这是传递给strchr()的值类型。
@Roland Illig很好地解释了导致在strchr()中保留使用int ch的历史。
OP的代码失败/有以下问题。
1) char* str被视为每§7.23.1.1 3中的unsigned char *str
对于本款中的所有函数,每个字符应被解释为其类型为无符号字符。
2) i应该是size_t类型,以处理字符数组的整个范围。
3)为了strchr()的目的,将空字符视为搜索的一部分。
终止空字符被认为是字符串的一部分。
4)最好使用const,因为str没有改变。
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函数在s指向的字符串中定位c(转换为char)的first事件。C11dr§7.23.5.2 2
所以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) {发布于 2017-02-03 08:14:05
在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位平台上是有意义的。
https://stackoverflow.com/questions/42018949
复制相似问题