trim 函数将内存大小减半以删除空格?
trim function halve the memory size to remove the whitespaces?
我必须创建一个可以执行此任务的函数(trim 函数):获取一个空终止字符串,如果在字符串的第 0 个位置有一个空格,则删除该空格。如果空格位于字符串的末尾(零终止符之前),则同样如此。因此,基本上函数会忽略字符串中间的空格。
这是我到目前为止尝试做的,
(1) 我将“ a b ”字符串传递给 trim 函数。
(2)(空指针检查)。
(3) 我用strlen函数取了字符串的长度。
(4) (this is the delicate part, because debugging line-by-line I found a
strange error inside the for loop).
错误是这样的:当调试器运行for循环的第一行时,它按预期进入了循环;好的,没关系,但是当调试器运行 if 检查时,它应该为真(因为在字符串的开头有一个空格)并且该函数应该进入 if 主体,在第一个 if 语句中,然后重新分配记忆。但事实并非如此,因为 realloc 永远不会被执行。为什么?
(函数必须 return 指向重新分配内存的指针)。
another error is that "s" isn't initialized but I used it anyway, and that's not true because I initialized s with " a b " string.
char* trim(const char* s) {
if (s == NULL) {
return NULL;
}
size_t length = strlen(s);
for (unsigned int i = 0; s[i] != '[=11=]'; i++) {
if (s[i] == " ") {
realloc(s, length - sizeof(char));
}
}
return s;
}
int main(void) {
trim(" a b ");
return 0;
}
在 if 语句中,您试图将 char s[i]
类型的对象与隐含的字符串文字 " "
进行比较;仅转换为指向其第一个元素的指针。
if (s[i] == " ") {
很明显,这样的比较计算结果为逻辑错误。
您需要使用整数字符常量 ' '
而不是字符串文字。
if (s[i] == ' ') {
还有这个内存重新分配
realloc(s, length - sizeof(char));
没有意义,因为至少重新分配的内存地址没有存储。
您不得触摸源字符串 s
。您需要动态分配一个新的字符数组并将修剪后的源字符串复制到那里。
函数可以这样定义,如下面的演示程序所示。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
char * trim( const char *s )
{
const char *first = s;
while ( isblank( ( unsigned char )*first ) ) ++first;
const char *last = first + strlen( first );
while ( last != first && isblank( ( unsigned char )last[-1] ) ) --last;
size_t n = last - first;
char * result = malloc( n + 1 );
if ( result != NULL )
{
memcpy( result, first, n );
result[n] = '[=13=]';
}
return result;
}
int main(void)
{
const char *s = " a b ";
printf( "\"%s\"\n", s );
char *p = trim( s );
printf( "\"%s\"\n", p );
free( p );
return 0;
}
程序输出为
" a b "
"a b"
在函数内而不是这个 while 循环
while ( isblank( ( unsigned char )*first ) ) ++first;
您可以使用函数 strspn
作为
first += strspn( first, " \t" );
我必须创建一个可以执行此任务的函数(trim 函数):获取一个空终止字符串,如果在字符串的第 0 个位置有一个空格,则删除该空格。如果空格位于字符串的末尾(零终止符之前),则同样如此。因此,基本上函数会忽略字符串中间的空格。
这是我到目前为止尝试做的, (1) 我将“ a b ”字符串传递给 trim 函数。 (2)(空指针检查)。 (3) 我用strlen函数取了字符串的长度。
(4) (this is the delicate part, because debugging line-by-line I found a strange error inside the for loop).
错误是这样的:当调试器运行for循环的第一行时,它按预期进入了循环;好的,没关系,但是当调试器运行 if 检查时,它应该为真(因为在字符串的开头有一个空格)并且该函数应该进入 if 主体,在第一个 if 语句中,然后重新分配记忆。但事实并非如此,因为 realloc 永远不会被执行。为什么?
(函数必须 return 指向重新分配内存的指针)。
another error is that "s" isn't initialized but I used it anyway, and that's not true because I initialized s with " a b " string.
char* trim(const char* s) {
if (s == NULL) {
return NULL;
}
size_t length = strlen(s);
for (unsigned int i = 0; s[i] != '[=11=]'; i++) {
if (s[i] == " ") {
realloc(s, length - sizeof(char));
}
}
return s;
}
int main(void) {
trim(" a b ");
return 0;
}
在 if 语句中,您试图将 char s[i]
类型的对象与隐含的字符串文字 " "
进行比较;仅转换为指向其第一个元素的指针。
if (s[i] == " ") {
很明显,这样的比较计算结果为逻辑错误。
您需要使用整数字符常量 ' '
而不是字符串文字。
if (s[i] == ' ') {
还有这个内存重新分配
realloc(s, length - sizeof(char));
没有意义,因为至少重新分配的内存地址没有存储。
您不得触摸源字符串 s
。您需要动态分配一个新的字符数组并将修剪后的源字符串复制到那里。
函数可以这样定义,如下面的演示程序所示。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
char * trim( const char *s )
{
const char *first = s;
while ( isblank( ( unsigned char )*first ) ) ++first;
const char *last = first + strlen( first );
while ( last != first && isblank( ( unsigned char )last[-1] ) ) --last;
size_t n = last - first;
char * result = malloc( n + 1 );
if ( result != NULL )
{
memcpy( result, first, n );
result[n] = '[=13=]';
}
return result;
}
int main(void)
{
const char *s = " a b ";
printf( "\"%s\"\n", s );
char *p = trim( s );
printf( "\"%s\"\n", p );
free( p );
return 0;
}
程序输出为
" a b "
"a b"
在函数内而不是这个 while 循环
while ( isblank( ( unsigned char )*first ) ) ++first;
您可以使用函数 strspn
作为
first += strspn( first, " \t" );