我正在努力完全理解指针,所以我正在研究Kenneth的A. Reek书,“Pointers On C.” 我在处理第6章问题1时遇到了一个问题: “编写一个函数,搜索字符串中任何一个给定的字符集。你的函数应该匹配这个原型
char *find_char(char const *source, char const *chars);
这是我的问题:在这个while循环中,
while(*found_char_location != '\0'){
if(*found_char_location == *source_pt_cpy)
{
return found_char_location;
//return *source_pt_cpy;
}//end if
如果我尝试返回指针 * source_pt_cpy ,程序会给我一个分段错误错误,但如果我返回指针 * found_char_location 这会很麻烦,因为他们没有相同的价值?为什么一个会崩溃而另一个不会崩溃? 这是我的完整源代码。感谢您的帮助。
char *find_char(char const *source, char const *chars)
{
if(is_null(source, chars))
{
return NULL;
}//end if
char *found_char_location;
char *source_pt_cpy;
found_char_location = chars;
source_pt_cpy = source;
while(*found_char_location != '\0'){
if(*found_char_location == *source_pt_cpy)
{
return found_char_location;
//return *source_pt_cpy;
}//end if
source_pt_cpy++;
if(*source_pt_cpy == '\0')
{
chars++;
source++;
found_char_location = chars;
source_pt_cpy = source;
}//end if
}//end while
return NULL;
}//end function
答案 0 :(得分:0)
他们指向的东西是相同的值,但它们不在同一个位置(或者你不需要检查它们的值是否相同)。
另外,小心使用*; * source_pt_cpy不是指针,它指向的是什么,如果那是你要返回的,那么使用该值作为指针很可能会导致seg错误。
答案 1 :(得分:0)
分段错误可能是由find_char
引起的,但在函数的调用者中发生。请注意,在一种情况下(有效的情况),您返回一个指针,调用者可能需要一个指针,因为这是正确的:
return found_char_location;
如果失败,你不会返回指针,但实际上只是指针所指向的字符:
return *source_pt_cpy;
因此,如果调用者将其视为指针,则可能会导致分段错误。
答案 2 :(得分:0)
通常 * chars 字符串会短于 * source 字符串。
您应该通过字符循环来源
中的固定位置如果找不到匹配项,请使用 source ++
进入源代码中的下一个位置但是
返回字符
的开头使用类似的东西:
chars = beginChars ;
你没有做的事。
如果您不确定发生了什么,请添加:
printf(" %c %c\n",*source,*chars);
在循环中间,在所有增量和减量之后。
答案 3 :(得分:0)
在C中,指针是变量的地址,没有别的。如果您想比较字符串(在C中翻译为空终止字符串),最好使用strcmp()
或strncmp()
函数。
像这样的陈述
char *found_char_location;
char *source_pt_cpy;
found_char_location = chars;
source_pt_cpy = source;
...
...
if(*found_char_location == *source_pt_cpy)
会比较存储在found_char_location
和source_pt_cpy
指针指向的位置的单个值,在这种情况下是一个字符,我认为这不是你想要的!
以下是来自a home-brewed string library I maintain的代码段(如果您想通过指针获得乐趣,请查看它!)
/*******************************************************************
* Return values
* - NULL in case any of the arguments is NULL
* - Modified string is returned
*
* Example Usage
* char str[] = "'free' as in 'free speech', not as in 'free beer'";
* printf("%s\n",zstring_replace_str(str,"free","KLMN"));
*
* Example Output
* 'KLMN' as in 'KLMN speech', not as in 'KLMN beer'";
******************************************************************/
char *zstring_replace_str(char *str, const char *x, const char *y){
/* to preserve the address of original pointers, tmp_ are used
* dummy_ptr enables us to preserve the address of tmp_str when
* a matching string pattern is found
* */
char *tmp_str = str, *tmp_x = x, *dummy_ptr = tmp_x, *tmp_y = y;
int len_str=0, len_y=0, len_x=0;
/* NULL pointer check */
if ((*str && *x && *y)==0)
return 0;
/* calculating length of strings */
for(; *tmp_y; ++len_y, ++tmp_y)
;
for(; *tmp_str; ++len_str, ++tmp_str)
;
for(; *tmp_x; ++len_x, ++tmp_x)
;
/* Bounds check */
if (len_y >= len_str)
return str;
/* reset tmp pointers */
tmp_y = y;
tmp_x = x;
for (tmp_str = str ; *tmp_str; ++tmp_str)
if(*tmp_str == *tmp_x) {
/* save tmp_str */
for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
if (*(tmp_x+1) == '\0' && ((dummy_ptr-str+len_y) < len_str)){
/* Reached at the end of x, we got something to replace
* then!
* Copy y only if there is enough room for it
*/
for(tmp_y=y; *tmp_y; ++tmp_y, ++tmp_str)
*tmp_str = *tmp_y;
}
/* reset tmp_x */
tmp_x = x;
}
return str;
}
它并不完全符合您的要求,但会让您了解如何完成任务。
在上面的代码中,for
循环
for (dummy_ptr=tmp_str; *dummy_ptr == *tmp_x; ++tmp_x, ++dummy_ptr)
做你想要的。它从源字符串的开头(for
循环的初始化)开始,然后在其逻辑检查部分中比较指针 tmp_x和dummy_ptr 指向的当前字符。最后,循环递增两个指针以遍历整个字符串。
这是搜索字符串而不是字符串中的字符串的另一个示例。此代码也来自zString library。
/* First if check can be omitted to improve the performance */
int zstring_search_chr(char *token,char s){
if (!token || s=='\0')
return 0;
for (;*token; token++)
if (*token == s)
return 1;
return 0;
}