请教一个简单的问题:sprintf的用法

dhdhdh 2006-05-14 06:12:39
读代码发现:
sprintf(prs_buf,"%s%s",prs_buf,prs_word);
的用法,注意是prs_buf给sprintf到prs_buf,自己输出给自己
但是结果和
printf(prs_buf,"%s%s",prs_buf,prs_word);
不一致,为什么?

注:此段代码是在unix下使用





...全文
917 32 打赏 收藏 转发到动态 举报
写回复
用AI写文章
32 条回复
切换为时间正序
请发表友善的回复…
发表回复
dhdhdh 2006-05-16
  • 打赏
  • 举报
回复
不好意思,今天才来结贴!
谢谢大家的帮助!
code_tin 2006-05-15
  • 打赏
  • 举报
回复
char * __cdecl strcat (
char * dst,
const char * src
)
{
char * cp = dst;

while( *cp )
cp++; /* find end of dst */

while( *cp++ = *src++ ) ; /* Copy src to end of dst */

return( dst ); /* return dst */

}

帖一下VC6的strcat实现
是没什么临时变量的。所以用这代替sprintf确实好许多
code_tin 2006-05-15
  • 打赏
  • 举报
回复
原来stidio_zhougang(回头是岸)说过了。没仔细看帖。该打。村长来扣我专家分吧。。。
code_tin 2006-05-15
  • 打赏
  • 举报
回复
哦。知道了。没事了。结帖。
铖邑 2006-05-15
  • 打赏
  • 举报
回复
好好想想吧,不多说了。楼上的想弄明白,干脆开个帖子吧
code_tin 2006-05-15
  • 打赏
  • 举报
回复
这时buf是1oy,先输入第一个字符,这样buf[1]='1'

如果这样那么%s,buf
应该变成bbb了。。。
铖邑 2006-05-15
  • 打赏
  • 举报
回复
很简单啊,格式1%s的第一个字符是1,那么buf[0]='1',这个是很显然的。接下来,是%s,这时buf是1oy,先输入第一个字符,这样buf[1]='1',于是buf是11y。接下来还是一样,111,然后就是'\0',于是%s处理结束。

没问题吧?
code_tin 2006-05-15
  • 打赏
  • 举报
回复
等下结
我还不知道为什么sprintf(buf,“1%d”,buf)
会是1111
而不是1boy
或者1oy
或者1bo
code_tin 2006-05-15
  • 打赏
  • 举报
回复
可能他知道或者觉得strcat内部实现里面会有引入一个临时变量
又可能他完全不知道或者没想起来strcat这个函数。
结帖以后我不要分。
铖邑 2006-05-15
  • 打赏
  • 举报
回复
这个话题可以结束了。楼主结帖吧
铖邑 2006-05-15
  • 打赏
  • 举报
回复
strcat(prs_buf,prs_word);
这句话需要临时变量吗???晕死
code_tin 2006-05-15
  • 打赏
  • 举报
回复
习惯???难道这样写会比strcat好吗?自己复制自己为啥啊???

============================
省却一个临时变量
code_tin 2006-05-15
  • 打赏
  • 举报
回复
#include "stdio.h"
main()
{

char buf[256]="boy";
sprintf(buf, "1%s abc", buf);
printf("%s\n",buf);
}

结果:
1111 abc

我试着分析一下
首先他会判断后面参数的长度。然后一位一位的复制到目标指针里面
sprintf(buf, "1%s abc", buf);
先打印1到buf里面
这个时候buf的内容就是1
然后重复复制buf原始长度次数
就是复制了3个1到buf里面
这样前面就变成1111
然后加上后面的 abc
这个情况可能有些类似递归
需要看汇编代码才能确定它到底搞了什么

这里贴出关键的ASM代码

; 10 : char buf[256]="boy";

push 252 ; 000000fcH
lea eax, DWORD PTR _buf$[esp+268]
push 0
push eax
mov DWORD PTR _buf$[esp+272], 7958370 ; 00796f62H
call _memset

; 11 : sprintf(buf, "2%s", buf);

lea ecx, DWORD PTR _buf$[esp+272]
push ecx
mov edx, ecx
push OFFSET ??_C@_03LOANLOPH@2?$CFs?$AA@
push edx
call DWORD PTR __imp__sprintf

; 12 : printf("%s\n",buf);

lea eax, DWORD PTR _buf$[esp+284]
push eax
push OFFSET ??_C@_03OFAPEBGM@?$CFs?6?$AA@
call DWORD PTR __imp__printf

可惜他只是去调用sprintf。所以还是没法看出什么
还是需要跟踪进去。我懒得做了。看谁跟进去看看
FallenAngel 2006-05-15
  • 打赏
  • 举报
回复
具体看sprintf库的实现,不过到目前为止,我看到的sprintf实现似乎都会第一步把buffer清空,所以连接不会成功
铖邑 2006-05-15
  • 打赏
  • 举报
回复
习惯???难道这样写会比strcat好吗?自己复制自己为啥啊???
code_tin 2006-05-15
  • 打赏
  • 举报
回复
没什么歧义阿
既然了解sprintf的用法
那么这个就是把两串字符串合并以后放到第一个参数所指的字符串
高手用这个的原因
不外乎是他习惯了这种写法
因为sprintf比strcat可以更多样化的使用,因为可以通过%来控制输出
这样写可以省却一个临时变量
所以这样写咯
stidio_zhougang 2006-05-15
  • 打赏
  • 举报
回复
看看sprintf的汇编实现吧
sprintf并不会申请什么临空间,借xpdavis的代码我分析一下
首先,输入1的时候,buf的数据变为buf[256] = "1oy"
然后%s输入,首先输入buf[0]为1,这时候buf[256]="11y" 然后是buf[1]还是为1,这时候变为buf[256]="111",然后是buf[2],还是为1,这时候buf[3]=0,结束,后面的不在多说...
pacman2000 2006-05-15
  • 打赏
  • 举报
回复
这种写法本来就不如strcat好。在sprintf过程中改变buf本身只会导致未定义的行为。
铖邑 2006-05-14
  • 打赏
  • 举报
回复
只是最好不要这样用吧。如果这样写呢?sprintf(prs_buf,"1%s%s",prs_buf,prs_word);
各位可以看看这样写的结果。

#include "stdio.h"
main()
{

char buf[256]="boy";
sprintf(buf, "1%s abc", buf);
printf("%s\n",buf);
}

结果:
1111 abc

各位想想看为什么?
就算是大虾写的,我也是要说的!
铖邑 2006-05-14
  • 打赏
  • 举报
回复
sprintf(prs_buf,"%s%s",prs_buf,prs_word);这样写可能没问题
加载更多回复(11)

69,369

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧