题目描述
最近刷到一道题,大概就是说要接收输入用户名和密码,如果都是admin,就显示成功,否则失败。
题目来源及自己的思路
我觉得样例一定会有超纲的地方,比如题目中根本没有限制使用字串的长度,所以我写了一个自动缩回字串总长度的方法
相关代码
/*...*/
int max_length = 500;
char *usr *pwd;
usr = calloc(sizeof(char) * max_length, sizeof(char));
pwd = calloc(sizeof(char) * max_length, sizeof(char));
scanf("%s %s", usr, pwd);
getchar(); /*这是为了给个输入终止*/
realloc(usr, sizeof(char) * strlen(usr));
realloc(pwd, sizeof(char) * strlen(pwd));
if(*usr == "admin" && *pwd == "admin"){
puts("OK!");
}
else{
puts("FAIL!!!");
}
/*...*/
实际看到的错误信息又是什么?
首先是看到有这样一条报错信息:
warning: ignoring return value of ‘realloc’, declared with attribute warn_unused_result [-Wunused-result]
realloc(usr, sizeof(char) * strlen(usr));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
warning: ignoring return value of ‘realloc’, declared with attribute warn_unused_result [-Wunused-result]
realloc(pwd, sizeof(char) * strlen(pwd));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
意思好像是说我忽略了realloc的返回值,但是realloc是void *类型的,我应该申请个什么类型的变量捕获它呢?
另外我应该也用不到这个返回值才对吧?
此外我发现第一组样例:admin abc
居然显示了OK!……
这又是为什么?
realloc的返回值是有意义的,你不该忽略它,realloc的返回值是新分配的地址,你不能假设realloc不会移动usr的地址,虽然缩小长度通常不会移动内存,但如果是增加长度很多情况都会重新分配一块内存。即使是缩小长度,c标准里也没有说不能移动分配的内存。
所以正确可靠的写法是
usr=realloc(usr, sizeof(char) * strlen(usr));
pwd=realloc(pwd, sizeof(char) * strlen(pwd));
重新分配之后usr和pwd可能会改变。
另外字符串比较应该用strcmp吧,不要直接用==,*usr其实只是一个字符,而"admin"则是一个字符串,c中字符串是一个指针,你用字符和指针进行==比较,肯定会得到无法预测的结果。