client程序接收参数的方法
本文为原创,若有错误欢迎批评指正!
在做公司笔试题的时候,自己尝试写算法的时候,经常被接收用户参数的问题搞得很蒙。于是决定把一些常用的要求和方法整理在这里。
这里主要考虑C的情况。
一. 输入单行参数
这种情况最简单,直接cin或者scanf,例如输入日期1992-5-8就直接
scanf("%d-%d-%d",&year,&month,&day);
但是scanf函数根据输入数据类型输入的格式有很多讲究。例如要考虑回车之类的字符会不会被算作输入。参考资料[1]里面的回答很专业,以下分情况讨论一下。从键盘读入键盘缓冲区(buffer)的数据都是以ASCII码存储的(包括回车0AH、空格20H)。区别就产生在scanf函数对不同的数据类型采用不同的策略读取缓冲区。以下分情况讨论一下。
1.1 输入整型的情况
scanf从键盘输入两个整数,分别赋值给变量a和b。
int a, b; scanf("%d",&a); scanf("%d",&b); printf("%d %d",a,b); printf("\n");
输入97回车96回车就可以成功赋值,不会被回车干扰。具体过程是,在第一个scanf后buffer中有39H,37H和0AH。在扫描到0AH的时候认为%d类型的数据结束,此时把39H和37H按照%d的格式转化为97赋给a。第二个scanf同理。
1.2 输入字符型的情况
字符型比较麻烦的地方在于会把回车和空格等也算作输入。例如:
char a, b; scanf("%c",&a); scanf("%c",&b); printf("%d %d",a,b); printf("\n");
输入9回车,输出57和10。因为输入9回车以后buffer中有39H,0AH。scanf按照%c扫描buffer,只扫描一个字节,然后把39H送到变量a,以%d读出时就是57。此时buffer中剩下0AH,scanf第二次按照%c扫描,把0AH送入变量b,以%d输出就是10。
这个问题的一种解决办法就是在输入以后清楚键盘缓冲区。例如:
while(getchar());
或者C++中:
fflush(sdtin);
还有一种办法就是调整scanf的输入方法,在里面加入空格或者回车来吸收空格或者回车。
char a, b; scanf(" %c",&a);//%c前面有一个空格! scanf(" %c",&b); printf("%c %c",a,b); printf("\n");
第一个scanf的时候buffer里面没有数据,输入1回车以后buffer中有31H,0AH,按照%c读取31H赋值给a。
第二个scanf的时候buffer里面有一个字节0AH,发现是0AH/20H,于是要求buffer再来一个字节。此时输入2回车后buffer中有32H,0AH,于是32H被赋值给b。最终buffer缓冲区中会剩下一个0AH。
1.3 输入字符串的情况
scanf按照%s要求对buffer按照字节扫描时,遇到空格或回车时截止。
char a[100], b[100]; scanf("%s",a); //注意没有&! scanf("%s",b); printf("%s %s",a,b); printf("\n");
输入abc回车def回车,输出abc def。因为是在同一行输出了两个字符串,证明回车没有算在字符串里。
1.4 scanf和scanf_s的问题
scanf_s我一直没有搞明白,官方说法是防止造成内存访问越界,然而加上后缀以后貌似完全变了一个用法。在我搞清楚之前暂时先使用scanf,可是编译的时候会报错。
解决报错:工程-->属性-->配置属性-->C/C++-->命令行,增加一句/D_CRT_SECURE_NO_WARNINGS
二. 输入尺寸已知的矩阵(数组)
尺寸已知时初始化比较容易,输入时用逗号或者空格隔开就可以。
C:
for (i = 0; i < n; i++) scanf("%d",&arr[i]);
C++:
for (i = 0; i < n; i++) cin >> arr[i];
三. 输入行数、长度未知的数组
例如输入的第一行是数组大小,第二行是数组中的元素。
input: 5
1,2,3,4,5
3.1 动态分配内存的方法
int n, *p; int i; scanf("%d",&n); p = (int*)malloc(n*sizeof(n)); for (i = 0; i < n; i++) scanf("%d",p+i);
3.2 STL容器接收
多行数据最好按照STL中容器接收,一次接收完再处理。
vector<int> arr; int n, size; while (cin >> n) arr.push_back(n); size = arr[0]; //第一行输入的数组大小 arr.erase(arr.begin());
3.3 接收一组处理一组
int n, a, b; cin >> n; while (n--) { cin >> a >> b; //处理语句 }
以后遇到其他情况随时更新。
欢迎补充!
参考资料
[1] https://zhidao.baidu.com/question/145325291.html?fr=qrl&index=0&qbl=topic_question_0&word=c%D3%EF%D1%D4%20scanf%BB%D8%B3%B5
[2] http://blog.csdn.net/mj813/article/details/53219580