| wangshim_ 回复于:2003-12-25 10:30:42
|
数组调用
顺序来,先从前往后,记住非空的位置
再从后往前,记住非空的位置。
两位置之间的字符就是你要的。
|
| cacaty 回复于:2003-12-25 10:31:27
|
我给你改改,函数这样声明好了char *trim(char *ptr)
其实很好写
|
| wangshim_ 回复于:2003-12-25 10:32:36
|
pb 中的trim 也很好用,呵呵
|
| lylzp 回复于:2003-12-25 10:35:52
|
[quote:1d563acbb8="bjf"]要求:代码尽量简洁,内存访问安全,符合接口规范。例如,把" 123 aa d "变成"123 aa d",空符号指空格符和制表符。
函数原型:void kill_space( char *ptr );[/quote:1d563acbb8]
[code:1:1d563acbb8]
void TrimAllStr(char *ibuf)
{
int nlen,i;
/*判断字符指针是否为空及字符长度是否为0*/
if (ibuf == NULL)
return;
nlen = strlen(ibuf);
if (nlen == 0)
return;
/*去前空格*/
i = 0;
while (1)
{
if (ibuf[i]!=' ')
break;
i ++;
}
if (i == nlen)
{
ibuf[0] = 0;
return;
}
if (i != 0)
{
nlen = nlen - i + 1;
memcpy(ibuf,&ibuf[i],nlen);
}
/*去后空格*/
nlen = strlen(ibuf) - 1;
while (nlen>=0)
{
if (ibuf[nlen] != ' ')
{
ibuf[nlen + 1] = 0;
break;
}
nlen --;
}
}
[/code:1:1d563acbb8]
|
| flw 回复于:2003-12-25 10:38:01
|
[quote:77befd92ac="lylzp"][/quote:77befd92ac]
呵呵,还不行。
|
| 只爱一点点 回复于:2003-12-25 10:47:21
|
看了 wangshim_ 和 cacaty 的帖子应该效率更高。
我好多年没用了,全忘了。就当从头学起,望指正。
可能会有逻辑和语法错误,看看我到什么水平了,虚啊~~
[code:1:3fedc0eb38]
void kill_space( char *ptr )
{
char *search ;
if( *ptr!='\0' )
{
search=ptr ;
while( *search!='\32' || *search!='\t' )
{
seach++ ;
}
while( *search!='\0' )
{
*ptr=*search ;
ptr++ ;
search++ ;
}
search-- ;
while( *search=='\32' || *search=='\t' )
{
search-- ;
}
search++ ;
*search='\0' ;
}
}
[/code:1:3fedc0eb38]
不行了,一帮人虎视着我要我去给打印机加纸,去起动个电脑,去印个材料~~~
刚才大叫了一顿~~
|
| lylzp 回复于:2003-12-25 10:49:55
|
哈!不好意思,我没看到还有制表符:
把if (ibuf[i]!=' ')改为 if ((ibuf[i]!=0x20)&&(ibuf[i]!='\t'))
把if (ibuf[nlen] != ' ')改为 if ((ibuf[nlen]!=0x20)&&(ibuf[nlen]!='\t'))
|
| flw 回复于:2003-12-25 10:51:52
|
[quote:38a0450cfd="只爱一点点"][/quote:38a0450cfd]
你这个也不行的。
|
| 只爱一点点 回复于:2003-12-25 10:52:51
|
[quote:6250e4e4fd="flw"]
你这个也不行的。[/quote:6250e4e4fd]
快告诉我哪错了!
|
| wangshim_ 回复于:2003-12-25 10:53:29
|
楼上兄弟,第2个while 应该这样写:
while( *seach!='\0' || *seach!='\32' || *seach!='\t')
这样才能把后面的空给屏蔽掉。
|
| flw 回复于:2003-12-25 10:54:44
|
[quote:16f39e735a="wangshim_"]楼上兄弟,第2个while 应该这样写:
while( *seach!='\0' || *seach!='\32' || *seach!='\t')
这样才能把后面的空给屏蔽掉。[/quote:16f39e735a]
这样还是不行的。
呵呵。
|
| 只爱一点点 回复于:2003-12-25 10:58:24
|
[quote:07088a035d="wangshim_"]楼上兄弟,第2个while 应该这样写:
while( *seach!='\0' || *seach!='\32' || *seach!='\t')
这样才能把后面的空给屏蔽掉。[/quote:07088a035d]
我是尾巴没处理好。
但这样中间有空格就会截断了。
|
| wangshim_ 回复于:2003-12-25 10:59:15
|
有意见可以提嘛,我们可以讨论,
不过不需要硬邦邦的定论。:)
|
| lylzp 回复于:2003-12-25 11:01:45
|
[quote:ad284c278c="flw"]
这样还是不行的。
呵呵。[/quote:ad284c278c]
你真逗,不过我的那段代码确实不怎么简洁
我也没去调试,我想功能应该是做到了。
|
| 只爱一点点 回复于:2003-12-25 11:10:21
|
不行了,忘了给会计打表了,找来的。
flw,把我的改了或者删了吧,拜托
删了吧,这样做没什么效率了。
原型就不满意,呵呵
|
| BingbingNorth 回复于:2003-12-25 11:15:29
|
void kill_space(char * ptr)
{
int start,end,i;
for(start=0; ((ptr[start]==' ')||(ptr[start]=='\t'))&&(ptr[start]!='\0'); start++);
for(end=strlen(ptr)-1; (ptr[end]==' ')||(ptr[end]=='\t'); end--);
for(i=start; i<=end; i++)
ptr[i-start]=ptr[i];
ptr[end-start+1]='\0';
}
我的这段代码效率并不是最高的(最高的应该不用strlen),但是比较简单。
|
| flw 回复于:2003-12-25 11:15:46
|
[code:1:bffef3d6a9]void AllTrim( char *str )
{
char *head, *tail;
if ( str == NULL )
return;
for( head = str; *head == ' ' || *head == '\t'; head ++ );
for( tail = str + strlen(str) - 1; (*tail == ' ' || *tail == '\t' ) && tail >= head; tail -- );
while( head <= tail )
*str ++ = *head ++;
*str = 0;
}
[/code:1:bffef3d6a9]
|
| 只爱一点点 回复于:2003-12-25 12:25:51
|
到底地对不对呀?
[code:1:a7e1b22f99]
void kill_space( char *ptr )
{
char *search ;
if( *ptr!='\0' )
{
for( search=ptr; *search==' ' || *search=='\t'; search++ ) ;
for( ; *search!='\0'; *ptr++=*search++ ) ;
/* 多了一些无用的内存移动 */
for( search-- ; *search==' ' || *search=='\t' ; search-- ) ;
search++ ;
*search='\0' ;
}
}
[/code:1:a7e1b22f99]
楼下的老大,我改了,看看行不行
|
| flw 回复于:2003-12-25 12:28:22
|
[quote:0ab997ffeb="只爱一点点"][/quote:0ab997ffeb]
优点:没有用 strlen。
缺点:不能在 C 中编译,而且,有语法错误! :? :oops: :oops: :oops: :oops:
|
| 蓝色键盘 回复于:2003-12-25 14:08:00
|
trim的问题写了这么多代码,好啊!
老夫也写个
去左边
[code:1:41ff858844]
char *lefttrim( char *str )
{
char *pstart, *ptr;
if ( str == NULL )
return NULL;
pstart = ptr = str;
while ( *( ( unsigned char * )ptr ) == 0x20 || *ptr == '\t' || \
*ptr == '\r' || *ptr == '\n' )
ptr ++;
while ( *ptr != 0x0 )
*str ++ = *ptr ++;
*str = 0x0;
return pstart;
}
[/code:1:41ff858844]
去右别
[code:1:41ff858844]
char *righttrim( char *str )
{
char *ptr;
if ( str == NULL )
return NULL;
ptr = str + strlen( str ) - 1;
while ( ptr >= str && ( *( ( unsigned char * )ptr ) == 0x20 || \
*ptr ==&nbs''''' || *ptr ==&nbs''''' || *ptr ==&nbs''''' ))
*ptr -- = 0x0;
return str;
}
[/code:1:41ff858844]
如法炮制,去左右以及去所有空格、制表符等,谁来写写?
|
| 只爱一点点 回复于:2003-12-25 14:17:12
|
测试了一下,我的用&nbs''''' 判断制表符好像不行???
|
| BingbingNorth 回复于:2003-12-25 14:47:45
|
不可能吧,一直都行的!
|
| 只爱一点点 回复于:2003-12-25 15:06:40
|
[quote:ac8fe57ac8="BingbingNorth"]不可能吧,一直都行的![/quote:ac8fe57ac8]
我说的是在 flw 写的代码下的面的那个代码?它可以吗?
|
| youngf 回复于:2003-12-25 16:09:00
|
修改了一下。source量应该是比较小了。
性能应该还可以吧。
[code:1:5d76327fc7]void kill_space(char *ptr){
char *pHead=ptr, *pFoot=ptr+strlen(ptr)-1;
if (ptr==NULL) return;
while(*pFoot==32 || *pFoot''''') *pFoot--;
while(*pHead==32 || *pHead''''') *pHead++;
*(++pFoot)=0;
if (pHead==ptr) return;
while(pHead<=pFoot) *ptr++=*pHead++;
*ptr=0;
return;
}
[/code:1:5d76327fc7]
|
| eboymcy 回复于:2003-12-25 16:09:59
|
1
|
| eboymcy 回复于:2003-12-25 16:10:26
|
[code:1:251627421a]
char *KillSpeace(char *pStr)//去掉pStr前后空格和制表符
{
char *pHead,*pTail;
char *pAddr;
if(pStr == NULL)
return NULL;
pAddr = pStr;
for(pHead = pStr;((*pHead ==&nbs'''&nbs''') || (*pHead ==&nbs''''')&&(*pHead !=&nbs'''''));pHead ++);
for(pTail = pStr + strlen(pStr) -1;((*pTail ==&nbs'''&nbs''')||(*pTail ==&nbs''''')&&(pTail <= pHead));pTail --);
while(pHead <= pTail)
*pStr++ = *pHead ++;
*pStr =&nbs''''';
return pAddr;
}
[/code:1:251627421a]
|
| youngf 回复于:2003-12-25 16:19:09
|
注意,他的要求是:返回值是 void, 不是char*。
|
| BingbingNorth 回复于:2003-12-25 16:32:14
|
[quote="只爱一点点"]
我说的是在 flw 写的代码下的面的那个代码?它可以吗?[/quote]
能运行啊,而且跟最佳状态已经不远了(只要解决多余的内存移动,但是如果要解决多余的内存移动,代码就变长了)。
|
| 只爱一点点 回复于:2003-12-25 16:44:10
|
[quote:022844b84b="BingbingNorth"]
能运行啊,而且跟最佳状态已经不远了(只要解决多余的内存移动,但是如果要解决多余的内存移动,代码就变长了)。[/quote:022844b84b]
???你是怎么测试的,把主程序贴出来看看可以吗?
我都忘了,想从控制台读一行字符串都想不起来了。
|
| tangsuilx 回复于:2003-12-25 17:03:15
|
UNIX C 下:
void sch_ltrim( char* str )
{
int len;
int i;
len = strlen( str );
for ( i = 0; i < len, str[i] ==&nbs'''&nbs'''; i++ )
if( i )
strcpy( str, &str[++i] );
}
void sch_rtrim( char* str )
{
int i;
int len;
char *ptr;
if( len = strlen( str ) ){
ptr = malloc( strlen( str ) + 1 );
memcpy( ptr, str, len );
i = len;
for( ; i > 0, ptr[i-1] ==&nbs'''&nbs'''; i-- );
ptr[i] =&nbs''''';
memcpy( str, ptr, len );
free( ptr );
}
return;
}
|
| lylzp 回复于:2003-12-25 17:17:12
|
哈!我就再献一次丑:
[code:1:162ff366ba]
void TrimAllStr(char *str)
{
char *phead,*pmove;
if (str == NULL)
return;
phead = pmove = str;
while ((*pmove == 0x20)||(*pmove ==&nbs'''''))
pmove ++;
do
{
*str ++ = *pmove ++;
}
while (*pmove != 0);
*str = 0;
if ((str - phead) == 1) return;
pmove = str - 1;
while (1)
{
if ((*pmove != 0x20)&&(*pmove !=&nbs'''''))
{
pmove ++;
*pmove =&nbs''''';
break;
}
pmove --;
}
}
[/code:1:162ff366ba]
|
| BingbingNorth 回复于:2003-12-25 20:46:09
|
回答只爱一点点:
没有读标准输入,而是这样:
#include <stdio.h>
void kill_space( char *ptr )
{
char *search ;
if( *ptr''''' )
{
for( search=ptr; *search'''&nbs''' || *search'''''; search++ ) ;
for( ; *search'''''; *ptr++=*search++ ) ;
/* &àÁËÒ&Ð&ÎÞÓÃ&ÄÄÚ&&ÒÆ&& */
for( search-- ; *search'''&nbs''' || *search''''' ; search-- ) ;
search++ ;
*searc''''' ;
}
}
int main()
{
char a[]=" \t bc efg\t";
kill_space(a);
printf("[%s]\n",a);
}
|
| 老K 回复于:2003-12-25 22:10:46
|
flw的我收了。比我的写的好。
|
| youngf 回复于:2003-12-26 12:29:10
|
能不能借这个机会,讲讲C是怎么实现strlen函数的?
|
| win_hate 回复于:2003-12-26 12:36:49
|
[quote:6cbbbf3a47="youngf"]能不能借这个机会,讲讲C是怎么实现strlen函数的?[/quote:6cbbbf3a47]
不同的c库实现方式肯定不一样,在x86上,一个很好的选择是用汇编中的串扫描指令。
|
| bjf 回复于:2003-12-26 20:33:28
|
我自己也来一个:
void
trim( ptr )
char *ptr;
{
char *p1, *p2;
p1 = p2 = ptr;
while( *p2'''&nbs''' || *p2''''' || *p2''''' ) p2++;
for( ; *p1=*p2; p1++,p2++ );
while( p1>ptr && (*(p1-1)'''&nbs''' || *(p1-1)''''' || *(p1-1)''''') ) p1--;
*p1 =&nbs''''';
}
|
| 蓝色键盘 回复于:2003-12-27 09:56:57
|
楼上各位兄弟讲得非常好
去空格的函数,我倒是没有仔细追究性能。看了标题,偶便把left/right贴上来,凑热闹。呵呵
|
| 只爱一点点 回复于:2003-12-27 12:02:00
|
[quote:21a77270f6="forest077"]返回值是char *和void有很大的区别,后者需要把新的字符串的每个字符覆盖掉旧字符串的每个字符,所以一些内存移动必不可少....[/quote:21a77270f6]
这种情况下内存移动是不可必免的。我主要指在字符串末尾有空格时程序也会对它进行移动。要避免就要先找到末尾,所以没有那样做。
另外做成这样纯属偶然,因为写到一半忘了处理末尾的空格了,经大家提醒才临时打了个补丁,呵呵 。其实它的效率取决于字符串的长度和末尾空格数的多少了。
不过效率在这意思好像不是很大,主要能让我们理解一些更深的东西,如:strlen的效率如何等等。
|
| bjf 回复于:2003-12-27 14:38:37
|
一个小小的问题引出那么多的见解,真没想到啊!希望能有谁总结一下,对于这个常用的小函数,从安全、高效的角度来考虑,哪一种方法最好,以后就不用再去写了。
|
| converse 回复于:2004-02-15 20:06:53
|
我的算法,应该是比较简洁的吧,大家给点意见
void kill_space( char *str)
{
int i, j;
assert( str != NULL);
/*find the first non-space ch'''s position */
for (i = 0; (str[i] ==&nbs'''&nbs''' || str[i] ==&nbs''''') && str[i] !=&nbs'''''; i++)
;
/*find the last non-space ch'''s position */
for (j = strlen(str) - 1; (str[j] ==&nbs'''&nbs''' || str[j] ==&nbs''''') && j; j--)
;
memmove(str, str + i, j - i);
str[j + 1] =&nbs''''';
}
|
| BingbingNorth 回复于:2004-02-15 20:52:16
|
这个帖子又被顶上来了,我发表一下关于“效率最高”的拙见,不足之处请大家补充。
1。如果前面没有空白符,那么str[i]=str[i]这样的操作不应该被执行,否则,对于一个很大的字符串,你的算法的时间复杂性比最佳的就低很多。大家可以看看前面的帖子,这一点有谁考虑到了。
2。用了strlen()的算法一定不是最佳的,因为这个程序的算法可以降到strlen(str)+1,而strlen()本身的时间复杂性就是strlen(str)+1。
3。只爱一点点兄发表于: 2003-12-25 12:12 的算法,bjf兄 发表于: 2003-12-26 20:12 的时间复杂性是最小的,(只比strlen(str)+1大了一点点)但还没有达到最佳,在到达字符串结尾后又折回来了。
另外我还要感谢converse兄,教给了我memmove()的用法。
|
| converse 回复于:2004-02-15 22:33:05
|
在写上面的代码前,没有看过前面的留言,原来可以不用strlen呀,所以我又进行了一个改进,大家再看一看吧
[code:1:1d563acbb8]
void kill_space(char *str)
{
char *p, *q;
assert(str != NULL);
for (p = str; (*p ==&nbs'''&nbs''' || *p ==&nbs''''') && *p !=&nbs'''''; p++)
;
for (q = p; *q !=&nbs'''&nbs''' && *q !=&nbs''''' && *q !=&nbs'''''; q++)
;
*q =&nbs''''';
memmove(str, p, q - p);
}[/code:1:1d563acbb8]
BingbingNorth:
我现在写程序的时候,首先考虑的是标准库里有没有相应功能的函数,这样可以保证移植性,我也是最近开始仔细研究C库的,过一段时间(大概一个月吧),我会把自己实现的部分C库(主要是string.h,input/output,stdlib.h)的代码放在这里和大家讨论。
另外,谁能告诉我哪里能找到C库的实现,我听说好像LINUX里有,不知道是不是呢
|
| converse 回复于:2004-02-15 22:44:41
|
在写上面的代码前,没有看过前面的留言,原来可以不用strlen呀,所以我又进行了一个改进,大家再看一看吧
[code:1:8f2359ca7a]
void kill_space(char *str)
{
char *p, *q;
assert(str != NULL);
for (p = str; (*p ==&nbs'''&nbs''' || *p ==&nbs''''') && *p !=&nbs'''''; p++)
;
for (q = p; *q !=&nbs'''&nbs''' && *q !=&nbs''''' && *q !=&nbs'''''; q++)
;
*q =&nbs''''';
memmove(str, p, q - p);
}[/code:1:8f2359ca7a]
BingbingNorth:
我现在写程序的时候,首先考虑的是标准库里有没有相应功能的函数,这样可以保证移植性,我也是最近开始仔细研究C库的,过一段时间(大概一个月吧),我会把自己实现的部分C库(主要是string.h,input/output,stdlib.h)的代码放在这里和大家讨论。
另外,谁能告诉我哪里能找到C库的实现,我听说好像LINUX里有,不知道是不是呢
|
| BingbingNorth 回复于:2004-02-16 15:00:16
|
converse兄:
你的算法不太符合原来的要求,字符串中间的空白符是不能删的。
|
| foryijian 回复于:2004-02-16 15:41:49
|
个人认为,由于中间空格的存在,strlen 一下是无法避免的
|
| converse 回复于:2004-02-16 17:49:17<7
|
BingbingNorth:
我昨晚回去睡觉的时候也反应过来了,不过今天上班,不太有时间想,我暂时也想不到一个比较好的小于(或接近)strlen(s)-1的方法找到后面空格的位置,待我想一想。
|
| gm_jwl 回复于:2004-02-17 01:11:57
|
char *
kill_space(char *ptr)
{
int i=0,j;
char *str;
j=strlen(ptr)-1;
while(ptr[i]'''''||ptr[i]'''&nbs'''||ptr[i]''''') i++;
while(ptr[j]'''''||ptr[j]'''&nbs'''||ptr[j]''''') j--;
if((str=(char *)malloc(j-i+2))==NULL)
{
perror("kill_space:malloc");
exit(1);
}
strncpy(str,ptr+i,j-i+1);
str[j-i+1''''';
return str;
}
楼主应当把函数接口改掉,如双指针,否则不可能成功。
|
| BingbingNorth 回复于:2004-02-17 10:53:18
|
关注这个帖子的同仁,也可以看一看wangrujun兄发的一个有关算法的帖子,主题为“[原创] 从字符串中,删除指定字符串中的任意字符”,有一定的相似之处。
|
| bulluta 回复于:2004-02-21 13:22:12
|
不考虑memmove的复杂度后复杂度为strlen(s),大家看看算法有没有问题
void KillSpace(char*ptr)
{
int begin=-1, end=0, curpos=0;
while(0 != ptr[curpos])
{
if'''&nbs''' == ptr[curpos]) || ''''' == ptr[curpos]))
{
//do nothing
}
else
{
//find out the first byte not space
&nb; if(-1 == begin)
begin = curpos;
//current the last byte not space
end = curpos;
}
curpos++;
}
ptr[end+1] = 0;
if(-1 == begin)
//only space and tab in ptr
ptr[0] = 0;
else if(0 != begin)
memmove(ptr, &ptr[begin], end-begin+1);
}
这是借鉴了楼上各位兄台的思路后得出的算法,尤其是BingbingNorth的“如果前面没有空白符”的提醒。
不过我还有个疑问,这样去空格会不会造成内存泄漏?去掉的空格的内存空间并没有真正的释放掉,但直接用free似乎不妥。
|
| improgrammer 回复于:2004-02-24 22:14:57
|
void kill_space(char *ptr)
{
char *p,*q;
if(ptr==NULL)
return;
for(p=ptr;*p'''&nbs''' || *p''''';++p);
if(*p''''')
{
*pt''''';
return;
}
for(q=ptr;*p;++p,++q)
{
*q=*p;
}
for(p=q-1;*p'''&nbs'''||*p''''';--p);
*(++p''''';
}
这样简单,而且即使用memmove()代替逐字符拷贝提高一点效率,也少不了逐字符计算长度,效率的提高毕竟有限。至于没有前置空字符时可以省却第一、二循环,则要看使用时那种情况出现的概率大小。如果大多数情况下有前置空字符,则加一个if判断反而降低理论上的效率。总之,多一事不如少一事,就这样,采用最简单的代码。
有一点,就是如果传入NULL指针,则算是调用者违规,用个assert(ptr);强调一下协议是规范的做法,而不用这里的if(ptr==NULL)判断。 :em11:
|
| mindit 回复于:2004-02-25 09:32:43
|
我也来凑凑热闹
// 用处:1、删除前导空白符
// 2、将中间连续的空白符替换为一个空格
// p; 3、删除后面的空白符
void kill_space(char *s)
{
char *p=s, *q=s;
for(; isspace(*s); s++); /* 掠过前导空白符 */
for(; *s; )
{ /* 顺序访问字符串s中的每个字符 */
*q++ = isspace(*s) ?&nbs'''&nbs''' : *s ;
if(!isspace(*s))
{
s++;
}
else /* 掠过中间连续的多余空白符 */
{
while(isspace(*s))
{
s++;
}
}
}
if(q>p && *(q-1) ==&nbs'''&nbs''') /* 如q>p,则已经复制过非空白字符 */
{
*(q-1) =&nbs'''''; /* 如果后复制的是空白字符,将其改为字符串结束符 */
}
else
{
*q =&nbs'''''; /* 否则添加字符串结束符 */
}
}
// 判断是否空字符
int isspace(char chr)
{
if(chr'''&nbs''' || chr''''' || chr''''' || chr==0x0a)
{
return(1);
}
return(0);
}
|
| zxhred 回复于:2004-02-25 11:02:59
|
聆听教诲,不敢多走一步,只不过代码又多了一个变量.
[code:1:d44b116498]void trim ( char* ptr)
{
char *p,*q,*pos;
if ( ptr == NULL)
return ;
p = q = pos = ptr;
for ( ;*p'''&nbs'''||*p''''';p++);
q = pos = p;
for ( ; *p !=&nbs'''''; p++)
{
if ( *p'''&nbs'''&&*p''''')
&np; q = p;
}
*(++q) =&nbs''''';
memmove ( ptr,pos,q-pos+1);
return ;
}[/code:1:d44b116498]
|
| flw 回复于:2004-03-02 15:55:49
|
http://bbs.chinaunix.net/forum/viewtopic.php?p=1813892
这个是我刚写的,比这个帖子所有的代码都好用。
|
| 鸿弧凌风 回复于:2004-03-02 16:48:10
|
#include "stdio.h"
#include "string.h"
void kill_space(char * str)
{
char * head,* end,* temp;
if(str==NULL )
printf("The String is NULL.\n");
head=str;
end=str+strlen(str);
while((*head''''')||(*head''''')||(*head''''')||(*head==32))
head++;
while((*end''''')||(*end''''')||(*end''''')||(*end==32))
end--;
temp=head;
temp[end-head''''';
*str=*temp;
printf("%s\n",str);
}
|
| 我不懂C++ 回复于:2004-06-29 12:01:46
|
[code:1:53b0fd94a2]char* trim(char* s)
{
ASSERT ( s != NULL );
char* begin = s;
char* end = s + strlen( s );
if( begin != end )
{
--end;
while( isspace( *end ) && begin != end )
--end;
*end = 0;
}
if( isspace( *begin ) )
{
++begin;
while( isspace( *begin ) )// will stop at trailing zero
++begin;
memmove(s, begin, end - begin + 1 );
}
return s;
}
[/code:1:53b0fd94a2]
|
| xstart 回复于:2004-09-10 02:33:26
|
#include <stdio.h>
#include <string.h>
#include <ctype.h>
char * trim(char * ptr)
{
int start,end,i;
for(start=0; isspace(ptr[start]); start++);
for(end=strlen(ptr)-1;isspace(ptr[end]);end--);
for (i=start;i<=end;i++)
ptr[i-start]=ptr[i];
ptr[end-start+1''''';
return (ptr);
}
正好需要这样一个函数所以找到这里,试用了很多人的成果,发现大家的注意力主要在程序的效率上,结果往往不是很精确。我使用isspace函数改了一下,经测试能保证结果的正确性。
|
| zxf_tdm 回复于:2004-10-10 13:55:47
|
该写法应该是比较简洁的
int trim(char *str)
{
char *src, *dst;
int i;
i=strlen(str)-1;
dst=src=str;
while(*(src+i) && *(src+i)==0x20)
{
*(dst+i''''';
i--;
}
dst=src=str;
while(*src && *src==0x20) src++;
do
{
*dst++=*src;
}while (*src++);
}
|
| yuxh 回复于:2004-10-11 12:18:33
|
这样子是不是有点烦?但效率应该还可以。
[code:1:11518c9fc8]#include "stdio.h"
void kill_space(char * str)
{
char *pSource, *pDest;
int nLen, nNum, iFlag;
pSource = pDest = str;
&n while(*pSource ==&nbs'''&nbs'''||*pSource ==&nbs''''' || *pSource ==&nbs''''' || *pSource ==&nbs''''') pSource++;
if(pSource == pDest) {
nLen = 0;
iFlag = 1;
while(*pSource != 0) {
if(*pSource ==&nbs'''&nbs'''||*pSource ==&nbs''''' || *pSource ==&nbs''''' || *pSource ==&nbs''''') {
if( iFlag == 0)
nNum++;
else {
iFlag = 0;
nNum = 1;
}
}
else {
if( iFlag == 0 ) {
iFlag = 1;
&nbs nLen += nNum;
}
nLen++;
}
pSource++;
}
str[nLen] = 0;
}
else {
nLen = 0;
iFlag = 1;
while(*pSource != 0) {
if(*pSource ==&nbs'''&nbs'''||*pSource ==&nbs''''' || *pSource ==&nbs''''' || *pSource ==&nbs''''') {
if( iFlag == 0)
nNum++;
else {
iFlag = 0;
nNum = 1;
}
}
else {
if( iFlag == 0 ) {
iFlag = 1;
nLen += nNum;
}
nLen++;
}
*pDest++ = *pSource++;
}
str[nLen] = 0;
}
}
[/code:1:11518c9fc8]
|
| mengwg 回复于:2004-10-11 17:05:55
|
好热闹,偶一个类里的实现,摘了一部分代码。
[code:1:cd4ed32717]
#ifndef str_h
#define str_h
class TStr
{
private:
char * mBuf;
int mSize;
int mInfo_Size;
public:
TStr();
TStr(char *str);
~TStr();
int Size();
char * Str();
char * Ret();
char * operator~();
char * operator=(char * str);
char * operator+(char * str);
char * operator+(char str);
char * operator()(char * str,int size);
char * AR();
char * AL();
};
#endif
char * TStr::AR()
{
char * pblank=NULL,*pos;
if(mBuf==NULL) return NULL;
pos=mBuf;
while(*pos!=0)
{
if(*pos'''&nbs'''||*pos==0x09)
pblank=pos;
else pblank=NULL;
pos++;
};
if(pblank!=NULL)
*pblank=0;
mInfo_Size=strlen(mBuf);
return mBuf;
};
char * TStr::AL()
{
char * src,*tag;
if(mBuf==NULL) return NULL;
tag=src=mBuf;
while(*src'''&nbs'''||*src==0x09) src++;
while(*src!=0) *tag++=*src++;
*tag=0;
mInfo_Size=strlen(mBuf);
return mBuf;
};
[/code:1:cd4ed32717]
|
| Ares42 回复于:2004-10-11 18:51:24
|
[quote:95e686d76d="bjf"]要求:代码尽量简洁,内存访问安全,符合接口规范。例如,把" 123 aa d "变成"123 aa d",空符号指空格符和制表符。
函数原型:void kill_space( char *ptr );[/quote:95e686d76d]
我也凑一贴,请高手指正.
#include <stdio.h>
#include <string.h>
void Trim(char *Old)
{
int i=0;
char *New;
if(!strlen(Old) || !(New=strdup(Old))) return;
while(strchr(" \t",*(New+i)) && ++i);
while(strchr(" \t",New[strlen(New)-1]) && !(New[strlen(New)-1'''''));
sprintf(Old,New+i);
return;
}
|
| xjfirst 回复于:2004-10-12 15:05:48
|
[code:1:623db5675f]
void trim(char *scr)
{
int i, startpos, endpos;
startpos = 0;
if(scr == NULL) return NULL;
for(i = 0; *(scr + i) ==&nbs'''&nbs''' || *(scr + i) ==&nbs'''''; i++);
startpos = i;
endpos = i;
for(; *(scr + i) !=&nbs''''';)
{
for(; *(scr + i) !=&nbs'''&nbs''' && *(scr + i) !=&nbs''''' && *(scr + i) !=&nbs'''''; i++);
endpos = i - 1;
for(; *(scr + i) ==&nbs'''&nbs''' || *(scr + i) ==&nbs'''''; i++);
}
if(startpos == endpos) { /* 说明字符串是由空格与制表符组成的 */
return NULL;
}
memmove(scr, scr + startpos, endpos - startpos + 1);
memset(scr + endpos - startpos + 1, 0, i - endpos + startpos);
}[/code:1:623db5675f]
|
| zerglot 回复于:2004-10-15 15:40:48
|
upup
|
| shiyiming 回复于:2004-10-15 19:05:05
|
我给你改改,函数这样声明好了char *trim(char *ptr)
其实很好写
|
| zzgwz 回复于:2004-11-21 21:05:25
|
void kill_space( char *ptr )
{
int i, j, k;
for( i = j = 0, k = -1; *(ptr + i ) !=&nbs''''' ; ++ i )
if( *( ptr + i ) !=&nbs'''&nbs''' && *( ptr + i ) !=&nbs''''' )
{
k = i;
*( ptr + j ) = *( ptr + i )
++j;
}
*( ptr + k + 1 ) =&nbs''''';
return ;
}
|
| christine6280 回复于:2004-11-29 09:54:16
|
void TrimStr( char *s )
{
int len = 0;
char *p;
p = s;
len = strlen( p );
if( p == NULL )
return;
if( strlen( p ) == 0 )
return;
while( 1 )
{
if(( p[ len - 1 ] != 0x20 ) &&
( p[ len - 1 ] !=&nbs''''' ))
{
p[ len ] = 0x00;
break;
}
len--;
}
while( 1 )
{
if(( *p != 0x20 ) && ( *p !=&nbs''''' ))
break;
p++;
len--;
}
sprintf( s, p );
}
已经在sco上调试通过
|
| wangxg2 回复于:2004-12-28 17:16:15
|
[code:1:ea8a39d367]
void erase_char(char *str, char a)
{
if (*str ==&nbs''''') return;
for (char *p = str; *p !=&nbs'''''; )
{
if (*p == a)
{
char *pos1 = p;
char *pos2 = p;
while(*pos1++ = *(++pos2)){}
}
else
p++;
}
}[/code:1:ea8a39d367]
这样呢?可以删除任何字符
|
| javacool 回复于:2005-07-25 14:53:11
|
void trim(char *str)
{
int bpos;
assert(str != NULL);
/* trim blank character in front of str */
for(int i = 0; str[i]''''' && (str[i]'''&nbs''' || str[i]'''''); i++)
NULL;
/* test where str is full of blank characters*/
if(str[i] ==&nbs'''''){
str[0] =&nbs''''';
return;
}
/* trim blank character at the end of str */
bpos = 0;
for(int j = i; str[j]'''''; j++)
/* record pos start of last blank characters */
if(str[j] ==&nbs'''&nbs''' || str[j] ==&nbs'''''){
bpos = j;
for(; str[j]'''&nbs''' || str[j] ==&nbs'''''; j++)
NULL;
/* make j point to end pos of last blank characters*/
j--;
}
/* test whether last blank characters at the end of str */
if(str[j-1] '''&nbs''' || str[j-1] ''''')
j = bpos;
memmove(str, str+i, j-i);
str[j-i] =&nbs''''';
}
通过bpos记录最后一个空字符串的起始位置,移动字符串时比较bpo'''''的位置来决定后面空字符串的trim 程序只需遍历字符串一次且不需使用strlen
|