sprintf函数的使用

学C语言的同学对printf函数都不陌生。从世界上第一个程序(我认为的)"hello world”到你手里正写的某个程序,都少不了printf的影子。不过你也许不知道,printf还有一些兄弟——比如wprintf、sprintf等。

过几天就要考C语言了,学校先把上机考试的系统公布了,里面有十几道测试题目让我们练练手。都是一些基础题,像什么水仙花数、哥德巴赫猜想之类的(好像这些题已成了必不可少的经典)。其中有一道题,简化一下就是这样:输入一个不长于9位的整数,输出每个位子上的数字的和,比如输入123,输出1+2+3=6。

基础题,用字符串来写可以是这样:

#include<stdio.h>
void  main(){
    char  ch[9]={'0'};
    int  i=0,c,s=0;
    while((c  =  getchar()) !=  '\n')
       ch[i++]  =  c;
    i=0;
    while(ch[i]  !=  '\0')
       s+=ch[i++]-'0';
    printf("%d\n",s);
}   

写题的时候发现,"不长于9位的整数"这个条件很微妙。9位就是亿位,我们知道long最大到21亿,也就是说我们这个数是可以保存在一个long型变量里的。就这样,我想到如果有一个现成的函数,能把一个数变成一个字符串,那就方便多了。非标准库里提供了一个itoa函数,标准库里提供了一个sprintf函数。

sprntf函数功能挺强大的,可以格式化任意类型的参数并存入字符串中。函数原型是这样:

int sprintf( char *buffer, const char *format, [ argument]  );

buffer是个字符串数组,保存我们需要得到的数据。format是个字符串,比如"%d%d",和printf里第一个参数相似。[argument]就是任意类型的数据,比如整型。

举个例子,sprintf(ch,"%ld",123456789); 什么意思?将长整型数123456789保存在字符数组ch里。就如同我们的printf("%ld",123456789);作用是输出长整型数123456789。

那么我们这一题还可以这样写:

#include<stdio.h>
void  main(){
  long n;
  char  ch[10]={'0'};
  int  i=0,s=0;
  scanf("%d",&n);
  sprintf(ch,"%ld",n); //将n格式化保存在字符数组ch中
  while(ch[i]  !=  '\0')
  s +=  ch[i++]-'0';
  printf("%d\n",s);
}

如此一来,程序好想了不少。不过,sprintf可不是我们想象中的那么简单,用不好也会给我们带来大麻烦。比如缓冲区溢出的问题,假如用户输入的数不止9位,ch数组可就装不下了,后果可不是程序出错那么简单。还有,sprintf的宽字节与窄字节问题与对中文的支持问题也不是那么简单,这些我都碰到过,以后再讲。

今天说到的这个用法确实可以使我们的程序简单多了。另外,我在文章开头提到了itoa函数,这个函数和sprintf函数效果相似,但因为不是标准库函数,所以部分编译软件并不能识别。(在windows下itoa函数一般来说可以使用)

函数原型:

char *itoa(int value, char *string, int radix);

value指被转换的整数,string指保存结果的字符数组,radix指转换成的进制。比如我想把23转换成二进制数保存在ch数组里,直接itoa(23,ch,2);就可以实现。相对的,还有一个函数atoi,大家google查查什么意思,以后也会经常用到。

赞赏

喜欢这篇文章?打赏1元

评论

上帝 回复

这道题直接scanf("%s",)输入到字符数组中不行吗

落沐萧萧 回复

@上帝:我不这样用。
仔细分析一下似乎也有问题,因为计算机不知道你输入的字符串以何种方式结束。
电脑不知道你输入回车表示已经完成输入了。所以我用while(getchar() != '\n')
当然也可以用gets

aoyama 回复

@落沐萧萧 哈哈,scanf就是回车结束啊!而且scanf比你的while更好,因为用户如果输入数字之后不小心输了英文或者符号,scanf会自动屏蔽掉后面的,而你的getchar会把所有东西都读进去!

phithon 回复

@aoyama 严禁挖坟

T 回复

@phithon 哈哈哈哈

captcha