c中没有alloc内存的字符串操作

时间:2010-05-06 16:43:06

标签: c string

我想知道是否有另一种获取子字符串而不分配内存的方法。更具体地说,我有一个字符串:

const char *str = "9|0\" 940 Hello";

目前我正在收到940,这是我想要的子字符串,

char *a = strstr(str,"9|0\" ");
char *b = substr(a+5, 0, 3); // gives me the 940

substr是我的子字符串过程。问题是我不想通过调用子字符串过程来为此分配内存。

有没有更简单的方法?可能是通过做一些字符串操作而不是分配mem。

我会感激任何反馈。

5 个答案:

答案 0 :(得分:2)

不,它无法完成。至少,不是没有修改原始字符串,也不是没有偏离字符串通常的C概念。

在C中,字符串是由NUL(\0字符)终止的字符序列。为了从"9|0\" 940 Hello"获得子串"940",必须有一系列字符940\0记忆中的某个地方。由于原始字符串中的任何字符都不存在该字符序列,因此您必须修改原始字符串。

另一种选择只是在你想要的子字符串开始的地方使用指向原始字符串的指针,然后还记住你的子字符串应该用多长时间来代替终止\0字符。但是,所有对字符串起作用的C标准库函数(以及几乎所有使用字符串的第三方C库)都希望字符串以NUL方式终止,因此不接受这种指针和计数格式。

答案 1 :(得分:1)

试试这个:

char *mysubstr(char *dst, const char *src, const char *substr, size_t maxdst) {
    ... do substr logic, but stick result in dst respecting maxdst ...
}

基本上,punt让调用者通过以下方式在堆栈上分配空间:

char s[100];

或其他什么。

答案 2 :(得分:0)

C字符串只是内存中的字符数组。如果您想在不分配字符副本的情况下访问子字符串,可以直接访问它:

char *b = a[5];

这种方法的问题是b不会以空值终止到适当的长度。它本质上是指向字符串的指针:“940 hello”。

如果与使用b的代码无关,那么你就可以了。但请记住,这可能会让产品生命周期中的其他程序员感到惊讶(包括您自己)!

答案 3 :(得分:0)

正如xyld所建议的,您可以让调用者分配内存并将substr函数传递给缓冲区来填充;但严格来说,这仍然涉及“分配记忆”。

根本没有分配任何内存,你能够做到这一点的唯一方法是通过将子字符串后面的字符更改为'\0'来修改原始字符串,但当然那么你的函数就不能用了不再需要const char *,而你正在修改原始字符串,这可能是不可取的。

答案 4 :(得分:0)

如果你不需要\ 0终止字符串,你可以创建一个子字符串查找功能,它只是告诉你在你的部分字符串(针)的完整字符串(haystack)中的位置。这将被视为热拷贝或别名,因为可以通过更改完整字符串(haystack)来更改数据。

我正在写一篇关于如何使用alloca分配内存并实现一个宏(因为它不能作为一个函数)可以做你想做的事情,但恰好碰到{ {1}}类似于strndupa,除了在堆栈上而不是从堆中分配内存。这是一个GNU扩展,所以它可能不适合你。

编写自己的宏看起来像一个函数,因为它需要返回一个值,但也可以处理内存,但这是可能的。