【问题标题】:Size of Needle in strstr functionstrstr 函数中针的大小
【发布时间】:2015-11-20 02:08:36
【问题描述】:

这是一个简单的问题,但是,当我使用 strstr 函数时,为什么针的大小必须至少比针中的实际文本大一个字符?这是因为空字符的原因吗?

当我把针作为针[1] 时,它不起作用。为什么可以将确切的字符数放入大海捞针?

#include <stdio.h>
#include <string.h>


int main(void)
{
   const char haystack[21] = "IDontUnderstand?Help!";
   const char needle[2] = "?";
   char *buffer;

   buffer = strstr(haystack, needle);

   printf("The substring is: %s\n", buffer);

   return(0);
}

【问题讨论】:

  • C 风格的字符串需要以'\0' 结尾,否则没有任何标识结束。
  • 只要不修改内容,使用const char* needle = "?";。问题解决了。
  • 你可以写成const char haystack[] = "IDontUnderstand?Help!";,而不是const char haystack[21] = "IDontUnderstand?Help!";。在后一种情况下,数组所需的大小由编译器计算。
  • 旁注:如果您的针是单个字符,您可以使用strchr()

标签: c strstr string.h


【解决方案1】:

理论上,两个字符串的末尾都应该有空终止字符 ('\0),否则函数不知道何时停止读取字符串:

使用strlen 函数。它读取字符串的长度直到空字符,可以这样实现:

size_t strlen(const char* str)
{
    size_t len = 0;
    for(; *str; ++str, ++len);
    return (len);
}

注意条件是*str,也可以表示*str != 0,表示for循环递增字符串和长度,直到找到一个空字符。

但是,如果没有给出空终止符(例如,您为 "Hello" 分配了 char[5],而实际上它应该是 char[6] - "Hello\0"),如果您使用的函数在“你好”的结尾。

为方便起见,如果您正在编写字符数组,则可以不将数字包含在大括号中,并允许编译器为您推断它以确保有一个空终止字符:

const char haystack[] = "IDontUnderstand?Help!";
const char needle[] = "?";

请注意,您不能将const char haystack[strlen("IDontUnderstand?Help!") + 1] = "IDontUnderstand?Help!"; 放入,因为strlen("IDontUnderstand?Help!") + 1 不是一个常量值。

但是,如果你想动态分配内存,你可以使用strlen来帮助:

char* get_str_buffer(const char* value)
{
    char* buf = malloc(strlen(value) + 1);
    strcpy(buf, value);
    return (buf);
}

int main(void)
{
    const char *haystack = get_str_buffer("IDontUnderstand?Help!");
    const char *needle = get_str_buffer("?");
    char *buffer;

    buffer = strstr(haystack, needle);
    printf("The substring is: %s\n", buffer);


    free(haystack);
    free(needle);
    return(0);
}

【讨论】:

  • 感谢您的帮助!
【解决方案2】:

为什么针的大小必须至少比针中的实际文本大一个字符?这是因为空字符的原因吗?

是的,正是因为null character。如果你看到strstr()的格式就是这个-

char *strstr(const char *haystack, const char *needle)

需要的参数是 -

haystack -This is the main C string to be scanned.

needle -This is the small string to be searched with-in haystack string.

由于needle 是小字符串,因此需要'\0' 来终止它。

【讨论】:

    【解决方案3】:

    干草堆也不好。您确实需要为结尾的 NULL 字节留出空间,以便函数知道字符串在哪里结束。否则他们将继续读取内存,直到遇到恰好存在的 NUL。

    如果您从 haystack 中删除多余的字符,则寻找针 "f" 实际上可能会返回结果,这一切都取决于内存恰好包含的内容。

    这就是为什么使用const char* 来保存字符串文字更好的部分原因。仅在代码中构造值时使用数组。

    【讨论】:

    • 读取数组末尾是未定义的行为。它可能如你所描述的那样表现出来,但说发生是错误的。
    • 是的。根据适当的内存保护,它也可能立即出现段错误。或者它可能会以多种创造性方式出现故障。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-05-30
    • 2013-08-29
    • 2020-05-09
    • 1970-01-01
    • 2021-10-21
    • 2012-08-13
    • 1970-01-01
    相关资源
    最近更新 更多