我无法利用else
中的main()
条件。在字符串中找不到字符时,该代码不起作用。我应该如何修改return
中的else
语句或main
条件?
#include <stdio.h>
char *xstrchr(char *string, char ch);
void main() {
char str[20], ch;
printf("Enter a string :");
gets(str);
printf("Enter character to search in string :");
scanf("%c", &ch);
char *r = xstrchr(str, ch);
printf("%c is stored at %d\n", *r, r);
if (r != NULL)
printf("Character '%c' found at %d index.\n", ch, (r - str + 1));
else
printf ("Character not found.");
}
char *xstrchr(char *s, char ch) {
int flag = 0, i = 0;
while (*(s + i) != '\0') {
if (*(s + i) == ch) {
flag = 1;
return (s + i);
}
i++;
}
if (flag == 0) {
return NULL;
}
}
答案 0 :(得分:3)
当找不到字符时,您的函数执行返回NULL
,但是当您取消引用main()
时,您在r
中具有未定义的行为测试printf
结果之前的NULL
语句,导致程序崩溃。
还有其他问题:
main
的原型应为int main(void)
或int main(int argc, char *argv[])
或可能为int main()
。
您不得使用gets()
。由于无法安全使用该功能,因此已从C语言中删除该功能。如果用户在提示符下键入超过19个字符,则您的程序将具有未定义的行为,因为gets()
会在数组末尾写入内容。
指针不应该用%d
打印,您应该输入:
printf("%c is stored at %p\n", *r, (void *)r);
两个指针的差为ptrdiff_t
类型,其大小应大于int
,并且不应使用%d
打印。对此的标准格式为%td
,但是许多C库都不支持此格式,因此最好将差异转换为int
:
printf("Character '%c' found at %d index.\n", ch, (int)(r - str + 1));
索引值从C语言中的0
开始。将数组的第一个元素称为索引1令人困惑。
您应该测试fgets()
和scanf()
的返回值,以检测文件过早结束或其他输入失败。
索引值可能超出类型int
的范围。您应该为size_t
中的i
使用类型xstrchr()
。
flag
未在xstrchr
函数中使用:更新代码和测试是多余的,可以删除。
*(s + i)
可以写为s[i]
,这更具可读性。除非需要显式使用指针算术语法,否则应使用方括号括起来。
这是更正的版本:
#include <stdio.h>
char *xstrchr(char *string, char ch);
int main() {
char str[200], ch;
printf("Enter a string: ");
if (!fgets(str, sizeof str, stdin))
return 1;
printf("Enter character to search in string: ");
if (scanf("%c", &ch) != 1)
return 1;
char *r = xstrchr(str, ch);
if (r != NULL) {
printf("Character '%c' found at %d index.\n", ch, (int)(r - str));
else
printf("Character not found.\n");
return 0;
}
char *xstrchr(char *s, char ch) {
size_t i = 0;
while (s[i] != '\0') {
if (s[i] == ch) {
return s + i;
}
i++;
}
return NULL;
}
最后,xstrchr()
函数与标准strchr()
函数的规范不完全匹配:
ch
的参数类型为int
,但出于比较目的将其值转换为char
。
s
的参数类型为const char *
,因为此函数未修改字符串,但是返回类型为char *
,因此返回值必须转换为(char *)
,这是不幸但必要的步骤。
如果ch
具有空值,则将匹配字符串末尾的空终止符。
增加s
而不使用索引变量是许多C程序员更喜欢的选择。
这是修改后的版本:
char *xstrchr(const char *s, int ch) {
for (;; s++) {
if (*s == (char)ch)
return (char *)s;
if (*s == '\0')
return NULL;
}
}