C_编写一个从输入流读入整数的函数,当这个整数是流末尾结束位置,返回EOF(对应的值)/灵活的调试宏的定义和使用/C语言对齐打印(指定下限宽度)
code
从K&R中改编过来
#include <stdio.h> #include <ctype.h> // 数值调试宏 #ifndef CXXU #define CXXU 1 #define dprint(expr) printf(#expr " = %d @%%d\n", expr) #define gprint(expr) printf(#expr " = %g\n", expr) #define fprint(expr) printf(#expr " = %f\n", expr) #define cprint(expr) printf(#expr " = %c @%%c\n", expr) #define sprint(expr) printf(#expr " = %s @%%s\n", expr) // #define sprint(expr) printf("\t@sprint"#expr " = %s\n", expr) // #define sprint(expr) printf(expr) #define sprintln(expr) printf(expr "\n") // 直接传递变量给pprint(取地址操作包含在了宏中) #define pprint(expr) printf(#expr " = %p &%%p\n", &expr) #define pprint_addr(expr) printf(#expr " = %p %%p\n", expr) // extern void func(); // extern int multiply(int a, int b); // extern char *str_multiplier; #endif // int getchar(void); // void ungetc(int); int getint(int *pn); int main() { // int integer[10] = {}; int integer = 0; int res = getint(&integer); dprint(res); dprint(integer); } /* getint: get next integer from input into *pn */ int getint(int *pn) { int c, sign; /* 利用while(isspace(c = getchar()))可以丢弃输入缓冲区中的空白符! 同时,被用于判断的(被预读)的字符会被记录在变量c中,不会丢失. */ while (isspace(c = getchar())) ; /* skip white space */ /* 判断第一个非空白字符是否为数字,并且这个数组不可以是文件结束符EOF(也是一个数字),是不是正/负号 */ // 我们假设用户输入的是构成数字的字符,那么 if (!isdigit(c) && c != EOF && c != '+' && c != '-') { ungetc(c, stdin); /* it is not a number */ return 0; } // 将正负号转换为正负1 sign = (c == '-') ? -1 : 1; // 转化之后,后废弃正负号,并读取下一个字符 if (c == '+' || c == '-') c = getchar(); // 将数字字符序列转化处理为整数(利用0的ascii码('0'=48),做char类型的减法,将得到的值作为int值(提升),得到数字字符char对应的整形int值) // pn为指针int型指针,*pn则为int型对象 for (*pn = 0; isdigit(c); c = getchar()) { *pn = 10 * *pn + (c - '0'); } // 修正正负性 *pn *= sign; // 至此,这个解析所得的整数就被记录在传入的参数pn中 /*EOF的判断.*/ // 判断本次调用getint是否恰好读完所有输入(如果不是,后面还有内容,将预读的字符打回输入缓冲区) if (c != EOF) ungetc(c, stdin); // 返回被解析整数(可以是多位整数)后的下一个字符 sprintln(); sprintln("last readed char:(it probably a white space char,so will will print it with %%d"); dprint(c); // 不过主要目的是为例能够再读取到结束符(譬如键入ctrl+D (for linux)),会返回该系统下定义的EOF对应的数(一般是-1) //这样,调用该函数的调用者就可以通过返回值来判断是否已经接触到文件末尾了 return c; } /* 测试输入: 449 last readed char:(it probably a white space char,so will will print it with %d(10 is carriage return;32 is tailing space key) c = -1 @%d res = -1 @%d integer = 449 @%d └─[130] <git:(master eecaaa7✱✈) > ./getint -56 测试2: last readed char:(it probably a white space char,so will will print it with %d c = 10 @%d res = 10 @%d integer = -56 @%d ┌─[cxxu@cxxuAli] - [~/cppCodes] - [2022-04-25 11:08:02] └─[0] <git:(master eecaaa7✱✈) > ./getint 45 测试3: last readed char:(it probably a white space char,so will will print it with %d c = 32 @%d res = 32 @%d integer = 45 @%d 测试4 └─[0] <git:(master eecaaa7✱✈) > ./getint 7923- last readed char:(it probably a white space char,so will will print it with %d c = 45 @%d res = 45 @%d integer = 7923 @%d */
调试宏(打印宏)与对齐
预览效果
code
使用制表符对齐的效果不太稳定,使用指定下限宽度的方法可以使得长度差异较大的输出串依然可以对齐
// 数值调试宏 #ifndef CXXU #define CXXU 1 // 修改sizeint来指定打印宽度:(注意,必须以字符串的形式修改,(数字要包裹双引号)) //负数,就是左对齐 #define sizeint__ "25" #define sizestr__ "%" sizeint__ "s" #define dprint(expr) printf(sizestr__ " = %d @%%d\n", #expr, expr) #define ldprint(expr) printf(sizestr__ " = %ld @%%ld\n", #expr, expr) #define cprint(expr) printf(sizestr__ " = %c @%%c\n", #expr, expr) #define sprint(expr) printf(sizestr__ " = %s @%%s\n", #expr, expr) #define gprint(expr) printf(sizestr__ " = %g\n", #expr, expr) #define fprint(expr) printf(sizestr__ " = %f\n", #expr, expr) // #define sprint(expr) printf("\t@sprint"#expr " = %s\n", expr) // #define sprint(expr) printf(expr) #define sprintln(expr) printf(expr "\n") // 直接传递变量给pprint(取地址操作包含在了宏中) #define pprint(expr) printf(sizestr__ " = %p &var%%p\n", "&" #expr, &expr) // 直接打印传入的地址(指针变量) #define pprinta(expr) printf(sizestr__ " = %p %%p (pointer:" #expr ")\n", #expr, expr) // extern void func(); // extern int multiply(int a, int b); // extern char *str_multiplier; #endif
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了