当前位置:首页
开发技术指南» 文章正文
    引言:

    摘要: rt ......
 ·pos机4614-104能否装上win95或win98    »显示摘要«
    摘要: 请问谁有在4614-104上装过win95或win98,我每次装后了以后重启都进不去系统,一到booting from drive c....就停住了,下不去啊 ......


字符数组转为浮点值,并带2位小数,谢谢

大家帮我看看这个函数,怎样才能把字符数组返回浮点数值,并且后面要带2位小数,如17822.88   17899.00.传入的pText参数是一个char   buf(128)字符数组.  
   
  /*********************************************************************  
    *   LONG_   StrTofloat(   LPCSTR_   pText   )  
    *   Purpose:    
    *       translate   string   to   float  
    *    
    *   return  
    *       translated   value,   -1   is   error.  
    *********************************************************************/  
  float   StrTofloat(LPCSTR_   pText)  
  {  
  LPSTR_   p;  
  //LONG_     sum;  
  float   sum;                   //05-07-26   原先sum定义为LONG值,我改为float  
   
  if(pText   ==   NULL)   return   -1;  
  p   =   (*pText   ==   -   ?   (LPSTR_)(pText   +   1)   :   (LPSTR_)pText);  
  sum   =   0;  
  while(   *p   )    
  {  
  if(   *p   <   0   &&   *p   >   9   )   return   -1;  
  sum   =   sum*   10   +   (*p++   -   0);           //这句话我看不懂  
  }  
  return   (*pText   ==   -   ?   -sum   :   sum);  
  }  
 

NO.1   作者: Bible_Chou

sprintf....

NO.2   作者: jsjjms

sum   =   sum*   10   +   (*p++   -   0);           //这句话我看不懂  
   
  *p++   -   0     --->转化成   数字  
   
  sum   =   sum*10   +   ...     --->转化成   具体的数

NO.3   作者: jsjjms

昨天   有高人贴的  
  //转  
   
  选自《CSDN   社区电子杂志——C/C++杂志》  
  http://emag.csdn.net   2005   年1   月   总第1   期   -   93   -  
  本文作者:steedhorse  
  printf   可能是许多程序员在开始学习C   语言时接触到的第二个函数,说  
  起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf   了解多  
  吗?在将各种类型的数据构造成字符串时,sprintf   的强大功能很少会让你失望。  
  由于sprintf   跟printf   在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,  
  后者则直接在命令行上输出。这也导致sprintf   比printf   有用得多。所以本文着重介绍sprintf,有时  
  也穿插着用用pritnf。  
  sprintf   是个变参函数,定义如下:  
  int   sprintf(   char   *buffer,   const   char   *format   [,   argument]   ...   );  
  除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:  
  格式化字符串上。  
  printf   和sprintf   都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的  
  格式说明符来占据一个位置,在后边的变参列表中提供相应的变量,最终  
  函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。  
  格式化数字字符串  
  sprintf   最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf   在大多数场合可以替代  
  itoa。如:  
  //把整数123   打印成一个字符串保存在s   中。  
  sprintf(s,   "%d",   123);   //产生"123"  
  可以指定宽度,不足的左边补空格:  
  sprintf(s,   "%8d%8d",   123,   4567);   //产生:"   123   4567"  
  当然也可以左对齐:  
  sprintf(s,   "%-8d%8d",   123,   4567);   //产生:"123   4567"  
  也可以按照16   进制打印:  
  sprintf(s,   "%8x",   4567);   //小写16   进制,宽度占8   个位置,右对齐  
  sprintf(s,   "%-8X",   4568);   //大写16   进制,宽度占8   个位置,左对齐  
  这样,一个整数的16   进制字符串就很容易得到,但我们在打印16   进制内容时,通常想要一  
  种左边补0   的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0   就可以了。  
  sprintf(s,   "%08X",   4567);   //产生:"000011D7"  
  上面以”%d”进行的10   进制打印同样也可以使用这种左边补0   的方式。  
  这里要注意一个符号扩展的问题:比如,假如我们想打印短整数-1   的内存16   进制表  
  示形式,在Win32   平台上,一个short   型占2   个字节,所以我们自然希望用4   个16   进制数字来打  
  印它:  
  short   si   =   -1;  
  sprintf(s,   "%04X",   si);  
  产生“FFFFFFFF”,怎么回事?因为spritnf   是个变参函数,除了前面两个参数之外,后面的  
  参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈  
  时被压进来的到底是个4   字节的整数还是个2   字节的短整数,所以采取了统一4   字节的处理方式,  
  导致参数压栈时做了符号扩展,扩展成了32   位的整数-1,打印时4   个位置不够了,就把32   位整数  
  -1   的8   位16   进制都打印出来了。如果你想看si   的本来面目,那么就应该让编译器做0   扩展而不是  
  符号扩展:  
  sprintf(s,   "%04X",   (unsigned   short)si);  
  就可以了。或者:  
  unsigned   short   si   =   -1;  
  sprintf(s,   "%04X",   si);  
  sprintf   和printf   还可以按8   进制打印整数字符串,使用”%o”。注意8   进制和16   进制都不会打  
  印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16   进制或8   进制表示。  
  控制浮点数打印格式  
  浮点数的打印和格式控制是sprintf   的又一大常用功能,浮点数使用格式符”%f”控制,默认保  
  留小数点后6   位数字,比如:  
  sprintf(s,   "%f",   3.1415926);   //产生"3.141593"  
  但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m   表  
  示打印的宽度,n   表示小数点后的位数。比如:  
  sprintf(s,   "%10.3f",   3.1415626);   //产生:"   3.142"  
  sprintf(s,   "%-10.3f",   3.1415626);   //产生:"3.142   "  
  sprintf(s,   "%.3f",   3.1415626);   //不指定总宽度,产生:"3.142"  
   
  注意一个问题,你猜  
  int   i   =   100;  
  sprintf(s,   "%.2f",   i);  
  会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:  
  sprintf(s,   "%.2f",   (double)i);  
  第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i  
  相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,  
  于是可怜的保存整数i   的那4   个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。  
  不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手  
  工编排的结果是否正确。?  
  字符/Ascii   码对照  
  我们知道,在C/C++语言中,char   也是一种普通的scalable   类型,除了字长之外,它与short,  
  int,long   这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。  
  于是,使用”%d”或者”%x”打印一个字符,便能得出它的10   进制或16   进制的ASCII   码;反过  
  来,使用”%c”打印一个整数,便可以看到它所对应的ASCII   字符。以下程序段把所有可见字符的  
  ASCII   码对照表打印到屏幕上:  
  for(int   i   =   32;   i   <   127;   i++)   {  
  printf("[   %c   ]:   %3d   0x%#04X\n",   i,   i,   i);  
  }  
  连接字符串  
  sprintf   的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连  
  接字符串,从而在许多场合可以替代strcat,但sprintf   能够一次连接多个字符串。比如:  
  char*   who   =   "I";  
  char*   whom   =   "CSDN";  
  sprintf(s,   "%s   love   %s.",   who,   whom);   //产生:"I   love   CSDN.   "  
  strcat   只能连接字符串,  
  但有时我们有两段字符缓冲区,他们并不是以’\0’结尾。比如许多从第三方库函数中返回的字符数  
  组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’\0’来结  
  尾。如果直接连接,不管是sprintf   还是strcat   肯定会导致非法内存操作,而strncat   也至少要求第  
  一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数  
  时可以指定宽度,字符串也一样的。比如:  
  char   a1[]   =   {A,   B,   C,   D,   E,   F,   G};  
  char   a2[]   =   {H,   I,   J,   K,   L,   M,   N};  
  如果:  
  sprintf(s,   "%s%s",   a1,   a2);   //Dont   do   that!  
  十有八九要出问题了。是否可以改成:  
  sprintf(s,   "%7s%7s",   a1,   a2);  
  也没好到哪儿去,正确的应该是:  
  sprintf(s,   "%.7s%.7s",   a1,   a2);//产生:"ABCDEFGHIJKLMN"  
  这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m   表示占用宽度,n   才表示从相应的字符串中最多取用的字符数。通常在打印字  
  符串时m   没什么大用,还是点号后面的n   用的多。自然,也可以前后都只取部分字符:  
  sprintf(s,   "%.6s%.5s",   a1,   a2);//产生:"ABCDEFHIJKL"  
  在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是  
  静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种  
  动态的宽度/精度设置功能在sprintf   的实现中也被考虑到了,sprintf   采用”*”来占用一个本来需要一  
  个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一  
  样被提供出来,于是,上面的例子可以变成:  
  sprintf(s,   "%.*s%.*s",   7,   a1,   7,   a2);  
  或者:  
  sprintf(s,   "%.*s%.*s",   sizeof(a1),   a1,   sizeof(a2),   a2);  
  实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:  
  sprintf(s,   "%-*d",   4,   A);   //产生"65   "  
  sprintf(s,   "%#0*X",   8,   128);   //产生"0X000080","#"产生0X  
  sprintf(s,   "%*.*f",   10,   2,   3.1415926);   //产生"   3.14"  
 

NO.4   作者: jsjjms

//再接  
   
  打印地址信息  
  有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32   位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:  
  sprintf(s,   "%u",   &i);  
  不过通常人们还是喜欢使用16   进制而不是10   进制来显示一个地址:  
  sprintf(s,   "%08X",   &i);  
  然而,这些都是间接的方法,对于地址打印,sprintf   提供了专门的”%p”:  
  sprintf(s,   "%p",   &i);  
  我觉得它实际上就相当于:  
  sprintf(s,   "%0*x",   2   *   sizeof(void   *),   &i);  
  利用sprintf   的返回值  
  较少有人注意printf/sprintf   函数的返回值,但有时它却是有用的,spritnf   返回了本次函数调用  
  最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf   调用结束以后,你无须再调用一次  
  strlen   便已经知道了结果字符串的长度。如:  
  int   len   =   sprintf(s,   "%d",   i);  
  对于正整数来说,len   便等于整数i   的10   进制位数。  
  下面的是个完整的例子,产生10   个[0,   100)之间的随机数,并将他们打印到一个字符数组s   中,  
  以逗号分隔开。  
  #include   <stdio.h>  
  #include   <time.h>  
  #include   <stdlib.h>  
  int   main()   {  
  srand(time(0));  
  char   s[64];  
  int   offset   =   0;  
  for(int   i   =   0;   i   <   10;   i++)   {  
  offset   +=   sprintf(s   +   offset,   "%d,",   rand()   %   100);  
  }  
  s[offset   -   1]   =   \n;//将最后一个逗号换成换行符。  
  printf(s);  
  return   0;  
  }  
  设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字  
  符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat   效率高,因为strcat   每次调用  
  都需要先找到最后的那个’\0’的位置,而在上面给出的例子中,我们每次都利用sprintf   返回值把这  
  个位置直接记下来了。  
  使用sprintf   的常见问题  
  sprintf   是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访  
  问错误,但好在由sprintf   误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通  
  常用眼睛再把出错的代码多看几眼就看出来了。  
  ??   缓冲区溢出  
  第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问  
  题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。  
  ??   忘记了第一个参数  
  低级得不能再低级问题,用printf   用得太惯了。//偶就常犯。:。。  
  strftime  
  sprnitf   还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也  
  是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为  
  了在出现问题时可以推卸责任吧。这里举个例子:  
  time_t   t   =   time(0);  
  //产生"YYYY-MM-DD   hh:mm:ss"格式的字符串。  
  char   s[32];  
  strftime(s,   sizeof(s),   "%Y-%m-%d   %H:%M:%S",   localtime(&t));  
  sprintf   在MFC   中也能找到他的知音:CString::Format,strftime   在MFC   中自然也有她的同道:  
  CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。  
  后记  
  本文介绍的所有这些功能,在MSDN   中都可以很容易地查到,笔者只是根据自己的使用经验,  
  结合一些例子,把一些常用的,有用的,而可能为许多初学者所不知的用法介绍了一点,希望大  
  家不要笑话,也希望大家批评指正。  
  有人认为这种带变参的函数会引起各种问题,因而不提倡使用。但笔者本人每每还是抵挡不  
  了它们强大功能的诱惑,在实际工作中一直在使用。实际上,C#.NET   从开始就支持变参,刚发布  
  不久的Java5.0   也支持变参了。  
  感谢ericzhangali仔细审阅了全稿,纠正了很多小错误,并提出了一些建议。  
  也感谢laomai阅读了全稿并给出了增删一些内容的建议。  
 

NO.5   作者: jixingzhong

sprintf   好象没有用吧?  
   
  这个是把   数值的转化倒字符呀  
   
  和楼主的要求反了...  
   
   
   
   
   
  sum   =   sum*   10   +   (*p++   -   0);           //这句话我看不懂  
   
  字符的0和数值的0是步一样的,  
   
  (*p++   -   0);           就是把一个字符型的数据,   //‘0’!=0     !!  
   
  转化到大小和这个数值大小一样  
   
  sum*   10   是因为后面增加一位的时候,前面的要全部前进一位   就是*10

NO.6   作者: jixingzhong

楼主的程序有个问题呀  
   
   
  就是没有处理小数点呀...  
   
   
   
   
   
  我很奇怪怎么不使用库函数呢?    
   
  atof     将字符串转换成浮点数  
   
  例子:      
   
  #include   <stdio.h>  
  #include   <stdlib.h>  
  #include   <conio.h>  
  #include   <math.h>  
   
  main()  
  {  
  float   f;  
  char   *str   =   "12345.67";    
  f   =   atof(str);    
  printf("string   =   %s\nfloat   =   %f\n",   str,   f);  
  getch();  
  }  
 

NO.7   作者: jixingzhong

我修改了楼主的函数  
   
  可以运行了  
   
  输出也正确  
   
   
   
   
  float   StrTofloat(char   *str)  
  {  
  int   n=1;  
  float   sum,point;  
  char   *p;  
   
  p=str;  
  sum   =   0;  
  point=0;  
          while(   *p!=.   )  
          {  
                  if(   *p   <   0   &&   *p   >   9   )   return   -1;  
                  sum   =   sum*   10   +   (*p++   -   0);  
          }  
  *p++;  
          while(   *p   )  
          {  
                if(   *p   <   0   &&   *p   >   9   )   return   -1;  
                point   =   point*   10   +   (*p++   -   0);  
                n=n*10;  
          }  
   
  sum   =   sum   +     point/n   ;  
   
  return   sum;  
  }  
   
   
  main()  
  {  
  float   sum;  
  char   *str   =   "12345.67";  
  sum=StrTofloat(str);  
  printf("string   =   %s\nfloat   =   %f\n",   str,   sum);  
  getch();  
  }  
 


 ·更新系统表的问题    »显示摘要«
    摘要: 我想通过删除系统表中的登陆信息来删除登陆, 比如删除系统视图syslogins中的记录,一般情况下sql不允许更新系统表(视图)的内容,也出现错误提示,如何才能将sql的设置变更,以便可以更新系统表的内容呢? ......
» 本期热门文章:

©2000-2007 All Rights Reserved. 最佳浏览:1024X768 MSIE