• unix


    格式化输出是由5个printf 函数来处理的

    #include <stdio.h>
    int printf(const char *restrict format, ...);
    int fprintf(FILE *restrict fp, const char *restrict format, ...);
    int dprintf(int fd, const char *restrict format, ...);
    int sprintf(char *restrict buf, const char *restrict format, ...);
    int snprintf(char *restrict buf, size_t n, const char *restrict format, ...);
    

    printf将格式化数据写到标准输出
    fprintf写至指定的流
    dprintf写至指定的文件描述符
    sprintf将格式化字符写入buf中。 sprintf在该字符串的文段自动加上一个NULL,但该字节不包括在返回值中
    注意,sprintf函数可能会造成有buf指向的缓冲区的溢出。
    为了解决缓冲区溢出安全隐患,引入了snprintf函数,超过缓冲区尾端写的所有字符都被丢弃。与sprintf相同,该返回值不包括结尾的null字节。

    printf的变体: 可变参数(...)替换成arg

    #include <stdarg.h>
    #include <stdio.h>
    int vprintf(const char *restrict format, va_list arg);
    int vfprintf(FILE *restrict fp, const char *restrict format, va_list arg);
    int vdprintf(int fd, const char *restrict format, va_list arg);
    int vsprintf(char *restrict buf, const char *restrict format, va_list arg);
    int vsnprintf(char *restrict buf, size_t n, const char *restrict format, va_list arg);
    

    格式化输入,3个scanf函数

    #include <stdio.h>
    int scanf(const char *restrict format, ...);
    int fscanf(FILE *restrict fp, const char *restrict format, ...);
    int sscanf(char *restrict buf, const char *restrict format, ...);
    

    可变参数

    #include <stdarg.h>
    
    int VarArgFunc(int dwFixedArg, ...){ //以固定参数的地址为起点依次确定各变参的内存起始地址
    
        va_list pArgs = NULL;  //定义va_list类型的指针pArgs,用于存储参数地址
    
        va_start(pArgs, dwFixedArg); //初始化pArgs指针,**使其指向第一个可变参数。该宏第二个参数是变参列表的前一个参数,即最后一个固定参数**
    
        int dwVarArg = va_arg(pArgs, int); //该宏返回变参列表中的当前变参值并使pArgs指向列表中的下个变参。该宏第二个参数是要返回的当前变参类型
    
        //若函数有多个可变参数,则依次调用va_arg宏获取各个变参
    
        va_end(pArgs);  //将指针pArgs置为无效,结束变参的获取
    
        /* Code Block using variable arguments */
    
    }
    
    //可在头文件中声明函数为extern int VarArgFunc(int dwFixedArg, ...);,调用时用VarArgFunc(FixedArg, VarArg);
    

    stdarg.h头文件内变参宏定义如下:

    typedef char * va_list;
    
    #define _INTSIZEOF(n)       ( (sizeof(n)+sizeof(int)-1) & ~(sizeof(int)-1) )
    
    #define va_start(ap,v)        ( ap = (va_list)&v + _INTSIZEOF(v) )
    
    #define va_arg(ap, type)    ( *(type *)((ap += _INTSIZEOF(type)) - _INTSIZEOF(type)) )
    
    #define va_end(ap)             ( ap = (va_list)0 )
    

    示例:

    #include <stdio.h>
    #include <stdarg.h>
     
    double average(int num,...)
    {
     
        va_list valist;
        double sum = 0.0;
        int i;
     
        /* 为 num 个参数初始化 valist */
        va_start(valist, num);
     
        /* 访问所有赋给 valist 的参数 */
        for (i = 0; i < num; i++)
        {
           sum += va_arg(valist, int);
        }
        /* 清理为 valist 保留的内存 */
        va_end(valist);
     
        return sum/num;
    }
     
    int main()
    {
       printf("Average of 2, 3, 4, 5 = %f
    ", average(4, 2,3,4,5));
       printf("Average of 5, 10, 15 = %f
    ", average(3, 5,10,15));
    }
    

    习题:
    下面的代码在一些机器上运行正确,而在另一些机器上运行时出错,解释问题所在

    #include <stdio.h>
    int main(void)
    {
      char c;
      while((c=getchar())!=EOF)
        putchar(c);
    }
    

    答案:
    getchar返回值为int型,当系统的char型为有符号型时能正常运行,当系统的char为无符号型时,EOF 不再是-1, 运行死循环

    int getchar(void);
    
  • 相关阅读:
    SQL Server2005重新安装不上的问题及其解决(转)
    取消2003默认共享
    自写生成实体类工具
    双核886针CPU简明制作教程
    VS 2008 在安装SP1后智能提示变成英文的解决办法
    VS2008 安装盘的问题
    拖放 DataGrid 列摘自MSDN
    VB.net SP1 的兼容性问题
    Windows Server 2008+VS2008
    Combobox 的解决方法
  • 原文地址:https://www.cnblogs.com/feiwatson/p/15373990.html
Copyright © 2020-2023  润新知