misc.c文件注释

/*

 * misc.c -- Miscellaneous routines.//一些通用的、常规的例程

 *

 * Copyright (c) GoAhead Software Inc., 1995-2010. All Rights Reserved.

 *

 * See the file "license.txt" for usage and redistribution license requirements

 *

 */

/********************************* Includes ***********************************/

#include  "uemf.h"

/*

 * 16 Sep 03 -- added option to use memcpy() instead of strncpy() in the

 * ascToUni and uniToAsc functions.

 */

#define kUseMemcopy

/********************************* Defines ************************************/

/*

 *    Sprintf buffer structure. Make the increment 64 so that

 *    a balloc can use a 64 byte block.

 */

#define STR_REALLOC              0x1                       /* Reallocate the buffer as required */

#define STR_INC                 64                         /* Growth increment */

//字符串缓冲区strbuf_t结构定义

//strbuf_t定义了一个字符串缓冲区,其中s指向缓冲区,size是当前缓冲区的大小,该大小//可以调整。max是缓冲区的最大长度。count是缓冲区中有效字符串中最后一个字符(不包含nul)在缓冲区中的字节索引数。flag是分配标志,如果其置为STR_REALLOC(即0x1),那么在相关函数(如put_char等)中可以通过balloc或者reballoc重新分配缓冲区。

typedef struct {

       char_t     *s;                                             /* Pointer to buffer */

       int          size;                                    /* Current buffer size */

       int          max;                                          /* Maximum buffer size */

       int          count;                                        /* Buffer count */

       int          flags;                                         /* Allocation flags */

} strbuf_t;

/*

 *    Sprintf formatting flags

 */

enum flag {

       flag_none = 0,

       flag_minus = 1,

       flag_plus = 2,

       flag_space = 4,

       flag_hash = 8,

       flag_zero = 16,

       flag_short = 32,

       flag_long = 64

};

/************************** Forward Declarations ******************************/

static int        dsnprintf(char_t **s, int size, char_t *fmt, va_list arg,

                            int msize);

static void       put_char(strbuf_t *buf, char_t c);

static void       put_string(strbuf_t *buf, char_t *s, int len,

                            int width, int prec, enum flag f);

static void       put_ulong(strbuf_t *buf, unsigned long int value, int base,

                            int upper, char_t *prefix, int width, int prec, enum flag f);

static int  gstrnlen(char_t *s, unsigned int n);

/************************************ Code ************************************/

/*

 *    "basename" returns a pointer to the last component of a pathname

 *  LINUX, LynxOS and Mac OS X have their own basename function

 */

#if (!defined (LINUX) && !defined (LYNX) && !defined (MACOSX))

#endif /* ! LINUX & ! LYNX & ! MACOSX */

/******************************************************************************/

/*

 *    Returns a pointer to the directory component of a pathname. bufsize is

 *    the size of the buffer in BYTES!

 */

//函数dirname返回一个输入路径的上一层目录的路径

char_t *dirname(char_t *buf, char_t *name, int bufsize)

{

       char_t *cp;

       int          len;

       a_assert(name);

       a_assert(buf);

       a_assert(bufsize > 0);

#if (defined (WIN) || defined (NW))

#else

       if ((cp = gstrrchr(name, '/')) == NULL)

#endif

       {

              gstrcpy(buf, T("."));

              return buf;

       }

       if ((*(cp + 1) == '\0' && cp == name)) {

              gstrncpy(buf, T("."), TSZ(bufsize));

              gstrcpy(buf, T("."));

              return buf;

       }

       len = cp - name;

       if (len < bufsize) {

              gstrncpy(buf, name, len);

              buf[len] = '\0';

       } else {

              gstrncpy(buf, name, TSZ(bufsize));

              buf[bufsize - 1] = '\0';

       }

       return buf;

}

/******************************************************************************/

/*

 *    sprintf and vsprintf are bad, ok. You can easily clobber memory. Use

 *    fmtAlloc and fmtValloc instead! These functions do _not_ support floating

 *    point, like %e, %f, %g...

sprintf和vsprintf都很容易造成内存溢出,这里提出了两种替代解决方案。

 */

int fmtAlloc(char_t **s, int n, char_t *fmt, ...)

{

       va_list     ap;

       int          result;

       a_assert(s);

       a_assert(fmt);

       *s = NULL;

       va_start(ap, fmt);

       result = dsnprintf(s, n, fmt, ap, 0);

       va_end(ap);

       return result;

}

/******************************************************************************/

/*

 *    Support a static buffer version for small buffers only!

静态缓冲区版本

 */

int fmtStatic(char_t *s, int n, char_t *fmt, ...)

{

       va_list     ap;

       int          result;

       a_assert(s);

       a_assert(fmt);

       a_assert(n <= 256);

       if (n <= 0) {

              return -1;

       }

       va_start(ap, fmt);

       result = dsnprintf(&s, n, fmt, ap, 0);

       va_end(ap);

       return result;

}

/******************************************************************************/

/*

 *    This function appends the formatted string to the supplied string,

 *    reallocing if required.

该函数将格式化了的字符串添加到提供的字符串后面,如果需要的话,可以重新分配缓冲区。

 */

int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...)

{

       va_list     ap;

       int          result;

       a_assert(s);

       a_assert(fmt);

       if (msize == -1) {

              *s = NULL;

       }

       va_start(ap, fmt);

       result = dsnprintf(s, n, fmt, ap, msize);

       va_end(ap);

       return result;

}

/******************************************************************************/

/*

 *    A vsprintf replacement.

一种替代vsprintf的实现

 */

int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg)

{

       a_assert(s);

       a_assert(fmt);

       *s = NULL;

       return dsnprintf(s, n, fmt, arg, 0);//调用dsnprintf,这是sprinf的一种动态实现版本

}

/******************************************************************************/

/*

 *    Dynamic sprintf implementation. Supports dynamic buffer allocation.

 *    This function can be called multiple times to grow an existing allocated

 *    buffer. In this case, msize is set to the size of the previously allocated

 *    buffer. The buffer will be realloced, as required. If msize is set, we

 *    return the size of the allocated buffer for use with the next call. For

 *    the first call, msize can be set to -1.

//dsnprintf是sprintf的动态实现。支持动态分配缓冲区。这个函数可以多次调用,以增大一

//个已经存在的缓冲区。在这种情况下,msize设置为前一次分配的缓冲区的大小。如果msize //被设置,函数返回这次执行后分配的缓冲区的大小,以便下次调用dsnprintf时使用。当第//一次调用dsnprintf时,msize可以被置为-1.

//int sprintf(char *buffer,char const *format,…);sprintf把它的结果作为一个NUL结尾的字符串//存储到指定的buffer缓冲区而不是写入到流中。Sprintf是一个潜在的错误根源。缓冲区的//大小并不是sprintf函数的一个参数,所以如果输出结果很长溢出缓冲区时,就可能改写缓//冲区后面内存位置中的数据。

 */

static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize)

{

       strbuf_t   buf;

       char_t            c;

       a_assert(s);

       a_assert(fmt);

       memset(&buf, 0, sizeof(buf));

       buf.s = *s;

       if (*s == NULL || msize != 0) {

              buf.max = size;

              buf.flags |= STR_REALLOC;

              if (msize != 0) {

                     buf.size = max(msize, 0);

              }

              if (*s != NULL && msize != 0) {

                     buf.count = gstrlen(*s);

              }

       } else {

              buf.size = size;

       }

       while ((c = *fmt++) != '\0') {

              if (c != '%' || (c = *fmt++) == '%') {

                     put_char(&buf, c);

              } else {

                     enum flag f = flag_none;

                     int width = 0;

                     int prec = -1;

                     for ( ; c != '\0'; c = *fmt++) {

                            if (c == '-') {

                                   f |= flag_minus;

                            } else if (c == '+') {

                                   f |= flag_plus;

                            } else if (c == ' ') {

                                   f |= flag_space;

                            } else if (c == '#') {

                                   f |= flag_hash;

                            } else if (c == '0') {

                                   f |= flag_zero;

                            } else {

                                   break;

                            }

                     }

《C和指针》P314:如果用于表示字段宽度和/或精度的十进制整数由一个行星号代替,那么printf的下一个参数(必须是个整数)就提供宽度和(或)精度。因此,这些值可以通过计算获得而不必预先指定。

                     if (c == '*') {

                            width = va_arg(arg, int);

                            if (width < 0) {

                                   f |= flag_minus;

                                   width = -width;

                            }

                            c = *fmt++;

                     } else {

                            for ( ; gisdigit((int)c); c = *fmt++) {

                                   width = width * 10 + (c - '0');

                            }

                     }

                     if (c == '.') {

                            f &= ~flag_zero;

                            c = *fmt++;

                            if (c == '*') {

                                   prec = va_arg(arg, int);

                                   c = *fmt++;

                            } else {//计算精度

                                   for (prec = 0; gisdigit((int)c); c = *fmt++) {

                                          prec = prec * 10 + (c - '0');

                                   }

                            }

                     }

h代表short,l代表long.《C和指针》P314:当字符或者短整数值作为printf函数的参数时,它们在传递给函数之前先转换为整数。有时候转换可以影响函数产生的输出。同样,在一个长整数的长度大于普通整数的环境里,当一个长整数作为参数传递给函数时,printf必须知道这个参数是个长整数。详见《C和指针》表15.7.在有些环境里,int和short int的长度相等,此时h修改符就没有效果。否则,当short int作为参数传递给函数时,这个被转换的值将升级为(无符号)int类型。这个修改符在转换发生之前使它被裁减回原先的short形式。在十进制转换中,一般并不需要进行裁减。但在有些八进制数或十六进制数的转换中,h修改符将保证适当位数的数字被打印。在int和long int 长度相同的机器中,l修改符并无效果。在所有其他机器上,需要使用l修改符,因为这些机器上的长整型分为两部分传递到运行时堆栈。如果这个修改符并未给出,那就只有第1个部分被提取用于转换。这样,不仅转换将产生不正确的结果,而且这个值的第二部分将被解释为一个单独的参数,这样破坏了后续参数和他们的格式代码之间的对应关系。

                     if (c == 'h' || c == 'l') {

                            f |= (c == 'h' ? flag_short : flag_long);

                            c = *fmt++;

                     }

                     if (c == 'd' || c == 'i') {//参数作为一个十进制整数打印

                            long int value;

                            if (f & flag_short) {//短整型

                                   value = (short int) va_arg(arg, int);

                            } else if (f & flag_long) {//长整型

                                   value = va_arg(arg, long int);

                            } else {//一般整型

                                   value = va_arg(arg, int);

                            }

                            if (value >= 0) {

                                   if (f & flag_plus) {

+标志在printf家族的作用:当用于格式化某个有符号值的代码时,如果值非负,正号标志就会给它加上一个正号。如果该值为负,就像往常一样显示一个符号。在缺省情况下,正号并不会显示。

                                          put_ulong(&buf, value, 10, 0, T("+"), width, prec, f);

                                   } else if (f & flag_space) {

空格在printf家族的作用:只用于转换有符号值的代码。当值非负时,这个标志把一个空格添加到它的开始位置。注意这个标志和正号标志是相互排斥的,如果两个同时给出,空格标志便被忽略。

                                          put_ulong(&buf, value, 10, 0, T(" "), width, prec, f);

                                   } else {

                                          put_ulong(&buf, value, 10, 0, NULL, width, prec, f);

                                   }

                            } else {

                                   put_ulong(&buf, -value, 10, 0, T("-"), width, prec, f);

                            }

                     } else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {

《C和指针》P313表15.5:u,o,x,X:参数作为一个无符号值打印,u使用十进制,o使用八进制,x和X使用十六进制,两者的区别是x约定abcdef,而X约定ABCDEF

                            unsigned long int value;

                            if (f & flag_short) {//短整型

                                   value = (unsigned short int) va_arg(arg, unsigned int);

                            } else if (f & flag_long) {//长整型

                                   value = va_arg(arg, unsigned long int);

                            } else {//一般整数

                                   value = va_arg(arg, unsigned int);

                            }

                            if (c == 'o') {

                                   if (f & flag_hash && value != 0) {

《C和指针》P314表15.8:#标志用于o,保证产生的值以一个零开头。

                                          put_ulong(&buf, value, 8, 0, T("0"), width, prec, f);

                                   } else {

                                          put_ulong(&buf, value, 8, 0, NULL, width, prec, f);

                                   }

                            } else if (c == 'u') {

                                   put_ulong(&buf, value, 10, 0, NULL, width, prec, f);

                            } else {

                                   if (f & flag_hash && value != 0) {

                                          if (c == 'x') {

《C和指针》P314表15.8:#标志用于x,在非零值前面加上0x前缀。

                                                 put_ulong(&buf, value, 16, 0, T("0x"), width,

                                                        prec, f);

                                          } else {

                                                 put_ulong(&buf, value, 16, 1, T("0X"), width,

                                                        prec, f);

                                          }

                                   } else {

                  /* 04 Apr 02 BgP -- changed so that %X correctly outputs

                   * uppercase hex digits when requested.

                                          put_ulong(&buf, value, 16, 0, NULL, width, prec, f);

                   */

                                          put_ulong(&buf, value, 16, ('X' == c) , NULL, width, prec, f);

                                   }

                            }

                     } else if (c == 'c') {//参数被裁减为unsigned char类型并作为字符进行打印

                            char_t value = va_arg(arg, int);

                            put_char(&buf, value);

                     } else if (c == 's' || c == 'S') {//打印一个字符串

                            char_t *value = va_arg(arg, char_t *);

                            if (value == NULL) {

                                   put_string(&buf, T("(null)"), -1, width, prec, f);

                            } else if (f & flag_hash) {

                                   put_string(&buf,

                                          value + 1, (char_t) *value, width, prec, f);

                            } else {

                                   put_string(&buf, value, -1, width, prec, f);

                            }

                     } else if (c == 'p') {

格式p表示指针指被转换为一串因编译器而异的可打印字符。这个代码主要是和scanf中的%p组合使用。

                            void *value = va_arg(arg, void *);

                            put_ulong(&buf,

                                   (unsigned long int) value, 16, 0, T("0x"), width, prec, f);

                     } else if (c == 'n') {

格式n是独特的,因为它并不产生任何输出。相反,到目前为止函数所产生的输出字符数目将被保存到对应的参数中。

                            if (f & flag_short) {

                                   short int *value = va_arg(arg, short int *);

                                   *value = buf.count;

                            } else if (f & flag_long) {

                                   long int *value = va_arg(arg, long int *);

                                   *value = buf.count;

                            } else {

                                   int *value = va_arg(arg, int *);

                                   *value = buf.count;

                            }

                     } else {

                            put_char(&buf, c);

                     }

              }

       }

       if (buf.s == NULL) {

              put_char(&buf, '\0');

       }

/*

 *    If the user requested a dynamic buffer (*s == NULL), ensure it is returned.

 */

       if (*s == NULL || msize != 0) {

              *s = buf.s;

       }

       if (*s != NULL && size > 0) {

              if (buf.count < size) {

                     (*s)[buf.count] = '\0';

              } else {

                     (*s)[buf.size - 1] = '\0';

              }

       }

       if (msize != 0) {

              return buf.size;

       }

       return buf.count;

}

/******************************************************************************/

/*

 *    Return the length of a string limited by a given length

//gstrnlen返回字符串s的长度和限定值n两者中的较小者。

 */

static int gstrnlen(char_t *s, unsigned int n)

{

       unsigned int   len;

       len = gstrlen(s);

       return min(len, n);

}

/******************************************************************************/

/*

 *    Add a character to a string buffer

 */

//将一个字符放c放进字符串缓冲区buf中。该字符串缓冲区是strbuf_t类型的。在该strbuf_t                                                                                                                        //类型的对象buf中,其count表征了缓冲区中有效字符串的最后一个字符(不算nul)在缓//冲区中的字节偏移量加1,即为下一个有效字符即将放入的位置。总体思路就是把输入参//数c放到缓冲区中count偏移处,然后再把count增加,使其仍然指向下一输入字符要放入//的字节处,为了保证缓冲区内最多只有一个有效的字符串,如果加入的字符是nul,则count   //不加1,以便下次接收新字符时将其覆盖。但是如果//count已经是缓冲区最后一个字节处   //了,即再接受一个字符缓冲区就满了,则要从新分配缓//冲区的大小。

static void put_char(strbuf_t *buf, char_t c)

{

       if (buf->count >= (buf->size - 1)) {

              if (! (buf->flags & STR_REALLOC)) {

                     return;

              }

              buf->size += STR_INC;

              if (buf->size > buf->max && buf->size > STR_INC) {

/*

 *                  Caller should increase the size of the calling buffer

 */

                     buf->size -= STR_INC;

                     return;

              }

              if (buf->s == NULL) {

                     buf->s = balloc(B_L, buf->size * sizeof(char_t));

              } else {

                     buf->s = brealloc(B_L, buf->s, buf->size * sizeof(char_t));

              }

       }

       buf->s[buf->count] = c;

       if (c != '\0') {

              ++buf->count;

//思考:为什么当c是nul时,count不增加呢?

//答案很简单,是为了保证该字符串缓冲区内最多只有一个有效的字符串。为了保证缓冲区//内最多只有一个有效的字符串,如果加入的字符是nul,则count不加1,以便下次接收新//字符时将其覆盖。

       }

}

/******************************************************************************/

/*

 *    Add a string to a string buffer

 */

static void put_string(strbuf_t *buf, char_t *s, int len, int width,

              int prec, enum flag f)

{

       int          i;

如果传递进来的len是个负数

       if (len < 0) {

              len = gstrnlen(s, prec >= 0 ? prec : ULONG_MAX);

ULONG_MAX定义在系统头文件limits.h文件中,一般为0xffffffff,上面这条语句的功能是当传递进来的prec参数为负时,将prec置为ULONG_MAX,使len为字符串s的长度和ULONG_MAX中较小的那个(当然就是字符串s的长度了);当传递进来的prec参数为正数时,prec不变,将len置为字符串s的长度和prec中较小的那个数。

如果传递进来的len和prec都是非负数,且prec<len,则将len置为prec

       } else if (prec >= 0 && prec < len) {

              len = prec;

       }

下面的代码有些问题:不管f&flag_minus是真还是假,执行的代码都是一样的

       if (width > len && !(f & flag_minus)) {

              for (i = len; i < width; ++i) {

                     put_char(buf, ' ');

              }

       }

       for (i = 0; i < len; ++i) {

              put_char(buf, s[i]);

       }

       if (width > len && f & flag_minus) {

              for (i = len; i < width; ++i) {

                     put_char(buf, ' ');

              }

       }

}

/******************************************************************************/

/*

 *    Add a long to a string buffer 讲一个长整数放到字符串缓冲区中

 */

static void put_ulong(strbuf_t *buf, unsigned long int value, int base,

              int upper, char_t *prefix, int width, int prec, enum flag f)

{

       unsigned long x, x2;

       int                        len, zeros, i;

下面这个for循环实际是求出长整数value按base进制来算的话所占的位数,并将其赋值给len.例如1234十进制数求的结果是4

       for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) {

              x2 = x * base;

              if (x2 > value) {

                     break;

              }

       }

       zeros = (prec > len) ? prec - len : 0;

如果输入参数prec大于上面所求的len,则zeros为prec-len,否则为0.

       width -= zeros + len;

       if (prefix != NULL) {

              width -= gstrnlen(prefix, ULONG_MAX);

       }

       if (!(f & flag_minus)) {

              if (f & flag_zero) {

                     for (i = 0; i < width; ++i) {

                            put_char(buf, '0');

                     }

              } else {

                     for (i = 0; i < width; ++i) {

                            put_char(buf, ' ');

                     }

              }

       }

       if (prefix != NULL) {

              put_string(buf, prefix, -1, 0, -1, flag_none);

//put_string原型:static void put_string(strbuf_t *buf, char_t *s, int len, int width,

//            int prec, enum flag f)

       }

       for (i = 0; i < zeros; ++i) {

              put_char(buf, '0');

       }

下面的代码是从高位到低位依次取出value的数值,并依次存储到字符串缓冲区中

       for ( ; x > 0; x /= base) {

              int digit = (value / x) % base;

              put_char(buf, (char) ((digit < 10 ? '0' : (upper ? 'A' : 'a') - 10) +

                     digit));

       }

       if (f & flag_minus) {

              for (i = 0; i < width; ++i) {

                     put_char(buf, ' ');

              }

       }

}

/******************************************************************************/

/*

 *    Convert an ansi string to a unicode string. On an error, we return the

 *   original ansi string which is better than returning NULL. nBytes is the

 *    size of the destination buffer (ubuf) in _bytes_.

 */

将ansi格式的字符串转换为unicode格式的字符串。

char_t *ascToUni(char_t *ubuf, char *str, int nBytes)

{

#ifdef UNICODE

       if (MultiByteToWideChar(CP_ACP, 0, str, nBytes / sizeof(char_t), ubuf,

                     nBytes / sizeof(char_t)) < 0) {

              return (char_t*) str;

       }

#else

#ifdef kUseMemcopy

   memcpy(ubuf, str, nBytes);

#else

       strncpy(ubuf, str, nBytes);

#endif /*kUseMemcopy*/

#endif

       return ubuf;

}

/******************************************************************************/

/*

 *    Convert a unicode string to an ansi string. On an error, return the

 *    original unicode string which is better than returning NULL.

 *    N.B. nBytes is the number of _bytes_ in the destination buffer, buf.

 */

//将unicode编码格式的字符串转换为以ansicode格式编码的字符串

char *uniToAsc(char *buf, char_t *ustr, int nBytes)

{

#ifdef UNICODE

   if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes,

    NULL, NULL) < 0)

   {

      return (char*) ustr;

   }

#else

#ifdef kUseMemcopy

   memcpy(buf, ustr, nBytes);

#else

   strncpy(buf, ustr, nBytes);

#endif /* kUseMemcopy */

#endif

   return (char*) buf;

}

/******************************************************************************/

/*

 *    allocate (balloc) a buffer and do ascii to unicode conversion into it.

 *    cp points to the ascii buffer.  alen is the length of the buffer to be

 *    converted not including a terminating NULL.  Return a pointer to the

 *    unicode buffer which must be bfree'd later.  Return NULL on failure to

 *    get buffer.  The buffer returned is NULL terminated.

 */

//ballocAscToUnit函数是对于输入的ansi编码的字符串cp,调用balloc重新分配一块内存缓//冲区,用于容纳cp对应的unicode编码格式的字符串。

char_t *ballocAscToUni(char *cp, int alen)

{

       char_t *unip;

       int ulen;

       ulen = (alen + 1) * sizeof(char_t);

       if ((unip = balloc(B_L, ulen)) == NULL) {

              return NULL;

       }

       ascToUni(unip, cp, ulen);

       unip[alen] = 0;

       return unip;

}

/******************************************************************************/

/*

 *    allocate (balloc) a buffer and do unicode to ascii conversion into it.

 *    unip points to the unicoded string. ulen is the number of characters

 *    in the unicode string not including a teminating null.  Return a pointer

 *    to the ascii buffer which must be bfree'd later.  Return NULL on failure

 *    to get buffer.  The buffer returned is NULL terminated.

 */

ballocUnitToAsc与ballocAscToUni类似,只是转换方向相反。

char *ballocUniToAsc(char_t *unip, int ulen)

{

       char * cp;

       if ((cp = balloc(B_L, ulen+1)) == NULL) {

              return NULL;

       }

       uniToAsc(cp, unip, ulen);

       cp[ulen] = '\0';

       return cp;

}

/******************************************************************************/

/*

 *    convert a hex string to an integer. The end of the string or a non-hex

 *    character will indicate the end of the hex specification.

 */

函数hextoi是将一个以字符串形式存储的十六进制数转换为一个整数。该字符串可以以0x或0X开头,也可以直接以十六进制的数字(当然是字符形式的)开头,当该字符串碰到nul结束符或者非十六进制数里要求的字符时,转换结束。

unsigned int hextoi(char_t *hexstring)

{

       register char_t               *h;

       register unsigned int      c, v;

       v = 0;

       h = hexstring;

       if (*h == '0' && (*(h+1) == 'x' || *(h+1) == 'X')) {

              h += 2;

       }

       while ((c = (unsigned int)*h++) != 0) {

              if (c >= '0' && c <= '9') {

                     c -= '0';

              } else if (c >= 'a' && c <= 'f') {

                     c = (c - 'a') + 10;

              } else if (c >=  'A' && c <= 'F') {

                     c = (c - 'A') + 10;

              } else {

                     break;

              }

              v = (v * 0x10) + c;

       }

       return v;

}

/******************************************************************************/

/*

 *    convert a string to an integer. If the string starts with "0x" or "0X"

 *    a hexidecimal conversion is done.

 */

gstrtoi是将一个字符串形式存储的数转换为整数。当这个字符串是以0x或者0X开头时,把它当做十六进制数调用上面的hextoi进行转换。如果这个字符串直接是以数字开头时,则将其当做十进制数调用gatoi(视编码情况,一般即为标准库函数atoi)进行转换。

unsigned int gstrtoi(char_t *s)

{

       if (*s == '0' && (*(s+1) == 'x' || *(s+1) == 'X')) {

              s += 2;

              return hextoi(s);

       }

       return gatoi(s);

}

/******************************************************************************/

转载于:https://www.cnblogs.com/strider/articles/2071254.html

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值