[英]C-string alternatives to strtok_r() and strsep() that don't modify the original string pointer?
我正在查看 2 個 C 字符串函數 strtok_r() 和 strsep(),並注意到這兩個函數都修改了傳入的原始字符串的位置。
是否還有其他不修改傳入的原始字符串的 C 字符串函數?
在我的應用程序中,原始字符串是動態分配的,所以我希望在解析完成后釋放原始字符串。
strtok_r() 的示例
int main(){
char * str = strdup("Tutorial and example");
char* token;
char* rest = str;
printf("%s\n", rest);
while ((token = strtok_r(rest, " ", &rest)))
printf("%s\n", token);
printf("\n%s\n",str);
return(0);
}
Output
Tutorial and example
Tutorial
and
example
Tutorial
在最后一行,我希望 str 指向未修改的 cstring“教程和示例”。
strsep() 也會發生類似的 output 。
int main(){
char * str = strdup("Tutorial and example");
char* token;
char* rest = str;
printf("%s\n", rest);
while ((token = strsep(&rest, " ")))
printf("%s\n", token);
if (rest != NULL)
printf("%s\n", rest);
printf("%s\n", str);
return(0);
}
謝謝你。
我認為您誤解strtok_r
。 它不會改變原始字符串的位置,而且它不能——function 不能改變傳遞給它的指針的值,並使這個改變對調用代碼可見。
它可以並且將會做的是通過用nul
終止符替換標記來修改字符串本身的內容。 所以回答你原來的問題:
在我的應用程序中,原始字符串是動態分配的,所以我希望在解析完成后釋放原始字符串。
你不必做任何特別的事情。 完成后,您可以並且應該釋放原始字符串。
您看到一個單詞Tutorial
打印只是因為下一個字符被替換為nul
-終止符並且printf
停在那里。 如果您要逐個字符地檢查字符串,您會發現它在其他方面保持不變。
盡管提到的字符串函數改變了原始字符串,但指針str
指向動態分配的 memory,您可以使用它來釋放分配的 memory。
如果您不想更改原始字符串,可以使用標准 C 字符串函數strspn
和strcspn
。
例如
#include <stdio.h>
#include <string.h>
int main(void)
{
const char *s = "Tutorial and example";
const char *separator = " \t";
puts( s );
for ( const char *p = s; *p; )
{
p += strspn( p, separator );
const char *prev = p;
p += strcspn( p, separator );
int width = p - prev;
if ( width ) printf( "%.*s\n", width, prev );
}
return 0;
}
程序 output 是
Tutorial and example
Tutorial
and
example
使用這種方法,您可以為每個提取的 substring 動態分配 memory。
例如
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
const char *s = "Tutorial and example";
const char *separator = " \t";
puts( s );
size_t n = 0;
char **a = NULL;
int success = 1;
for ( const char *p = s; success && *p; )
{
p += strspn( p, separator );
const char *prev = p;
p += strcspn( p, separator );
if ( p - prev != 0 )
{
char *t = malloc( p - prev + 1 );
if ( ( success = t != NULL ) )
{
t[p - prev] = '\0';
memcpy( t, prev, p - prev );
char **tmp = realloc( a, ( n + 1 ) * sizeof( char * ) );
if ( ( success = tmp != NULL ) )
{
a = tmp;
a[n++] = t;
}
else
{
free( t );
}
}
}
}
for ( size_t i = 0; i < n; i++)
{
puts( a[i] );
}
for ( size_t i = 0; i < n; i++)
{
free( a[i] );
}
free( a );
return 0;
}
程序 output 與上圖相同。
Tutorial and example
Tutorial
and
example
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.