鱼C论坛

 找回密码
 立即注册
查看: 2170|回复: 4

[已解决]strcpy函数不安全问题

[复制链接]
发表于 2020-7-4 15:03:52 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include<iostream>
  2. #include<string>

  3. using namespace std;

  4. char select(char a[], char b[], char c[]);

  5. int main()
  6. {
  7.         char a[20];
  8.         char b[20];
  9.         char c[20];
  10.         cout << "输入三个国家的英文名:";
  11.         cin >> a >> b >> c;

  12.         cout << "按首字母排序最靠前的国家是:" << select(a, b, c);
  13. }
  14. char select(char a[], char b[], char c[])
  15. {
  16.         char x[20];
  17.         if (strcmp(a, b) > 0)
  18.         {
  19.                 if (strcmp(b, c) > 0)
  20.                         strcpy(x, c);
  21.                 else
  22.                         strcpy(x, b);
  23.         }
  24.         else
  25.         {
  26.                 if (strcmp(a, c) > 0)
  27.                         strcpy(x, c);
  28.                 else
  29.                         strcpy(x, a);
  30.         }
  31.         return x[20];
  32. }
复制代码

调试的时候编译器报错strcpy不安全,无法运行,但是课本上就是这么教的...
我用的编译器是vs2019
麻烦各位大神帮忙看下该怎么改啊
最佳答案
2020-7-4 22:09:49
本帖最后由 superbe 于 2020-7-5 22:15 编辑

select()函数,如果本意是要返回国家的首字母,应该是return x[0],不是x[20]。x下标范围是0到19,实际国家名可能还不到19,x[20]是一个未知的字符。

如果是要返回完整的国家名,可以参考下面改法。这时不能只返回 x 的地址,因为 x 数组是局部变量,函数结束后 x 内容不存在了,main()输出就不正确。

改法一,在main里添加一个数组用来保存select()比较的结果,把这个数组做为参数传给select()
  1. #include<iostream>
  2. #include <cstring>
  3. //#include<string>

  4. using namespace std;

  5. void select(char a[], char b[], char c[], char result[]);

  6. int main()
  7. {
  8.     char a[20];
  9.     char b[20];
  10.     char c[20];
  11.     char result[20];  //result[]保存比较结果
  12.     cout << "输入三个国家的英文名:";
  13.     cin >> a >> b >> c;

  14.     select(a, b, c, result);
  15.     cout << "按首字母排序最靠前的国家是:" << result << endl;
  16. }

  17. void select(char a[], char b[], char c[], char result[])
  18. {
  19.     if (strcmp(a, b) > 0)
  20.     {
  21.         if (strcmp(b, c) > 0)
  22.             strcpy(result, c);
  23.         else
  24.             strcpy(result, b);
  25.     }
  26.     else
  27.     {
  28.         if (strcmp(a, c) > 0)
  29.             strcpy(result, c);
  30.         else
  31.             strcpy(result, a);
  32.     }
  33. }
复制代码


其中select()函数也可以改成返回result[]的地址:
char * select(char a[], char b[], char c[], char result[])
{
    ......
    return result;
}
这样的好处是cout可以直接 cout << select(a, b, c, result)
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-7-4 15:40:17 | 显示全部楼层
第一行加上:
  1. #define _CRT_SECURE_NO_WARNINGS
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-7-4 15:51:51 | 显示全部楼层


你好请问为什么运行结果会出现,cout的结果是一个“?”的情况呢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-4 22:09:49 | 显示全部楼层    本楼为最佳答案   
本帖最后由 superbe 于 2020-7-5 22:15 编辑

select()函数,如果本意是要返回国家的首字母,应该是return x[0],不是x[20]。x下标范围是0到19,实际国家名可能还不到19,x[20]是一个未知的字符。

如果是要返回完整的国家名,可以参考下面改法。这时不能只返回 x 的地址,因为 x 数组是局部变量,函数结束后 x 内容不存在了,main()输出就不正确。

改法一,在main里添加一个数组用来保存select()比较的结果,把这个数组做为参数传给select()
  1. #include<iostream>
  2. #include <cstring>
  3. //#include<string>

  4. using namespace std;

  5. void select(char a[], char b[], char c[], char result[]);

  6. int main()
  7. {
  8.     char a[20];
  9.     char b[20];
  10.     char c[20];
  11.     char result[20];  //result[]保存比较结果
  12.     cout << "输入三个国家的英文名:";
  13.     cin >> a >> b >> c;

  14.     select(a, b, c, result);
  15.     cout << "按首字母排序最靠前的国家是:" << result << endl;
  16. }

  17. void select(char a[], char b[], char c[], char result[])
  18. {
  19.     if (strcmp(a, b) > 0)
  20.     {
  21.         if (strcmp(b, c) > 0)
  22.             strcpy(result, c);
  23.         else
  24.             strcpy(result, b);
  25.     }
  26.     else
  27.     {
  28.         if (strcmp(a, c) > 0)
  29.             strcpy(result, c);
  30.         else
  31.             strcpy(result, a);
  32.     }
  33. }
复制代码


其中select()函数也可以改成返回result[]的地址:
char * select(char a[], char b[], char c[], char result[])
{
    ......
    return result;
}
这样的好处是cout可以直接 cout << select(a, b, c, result)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-7-4 22:18:15 | 显示全部楼层
这是改法二,也就是select()比较后返回相应数组的地址,这样就不用添加result数组了。
  1. #include<iostream>
  2. #include <cstring>

  3. using namespace std;

  4. char * select(char a[], char b[], char c[]);

  5. int main()
  6. {
  7.     char a[20];
  8.     char b[20];
  9.     char c[20];
  10.     cout << "输入三个国家的英文名:";
  11.     cin >> a >> b >> c;

  12.     cout << "按首字母排序最靠前的国家是:" << select(a, b, c) << endl;

  13. }

  14. char * select(char a[], char b[], char c[])
  15. {
  16.     char * temp;
  17.     if (strcmp(a, b) > 0)
  18.     {
  19.         if (strcmp(b, c) > 0)
  20.             temp = c;
  21.         else
  22.             temp = b;
  23.     }
  24.     else
  25.     {
  26.         if (strcmp(a, c) > 0)
  27.             temp = c;
  28.         else
  29.             temp = a;
  30.     }
  31.     return temp;
  32. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-8-6 20:00

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表