鱼C论坛

 找回密码
 立即注册
查看: 1578|回复: 12

[已解决]小甲鱼课后习题进阶版strncpy函数

[复制链接]
发表于 2021-11-15 20:35:52 | 显示全部楼层 |阅读模式

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

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

x
本帖最后由 林江楠 于 2021-11-15 20:37 编辑
  1. #include <stdio.h>

  2. #define MAX 1024

  3. int main()
  4. {
  5.         char str1[MAX];
  6.         char str2[MAX];

  7.         char *target1 = str1;
  8.         char *target2 = str2;

  9.         char ch;
  10.         int n;

  11.         printf("请输入一个字符串到 str1 中:");
  12.         fgets(str1, MAX, stdin);

  13.         printf("请输入需要拷贝的字符个数:");
  14.         scanf("%d", &n);

  15.         printf("开始拷贝 str1 的内容到 str2 中...\n");
  16.         while (n--)
  17.         {
  18.                ch = *target2++ = *target1++;
  19.                if (ch == '\0')
  20.                {
  21.                        break;
  22.                }
  23.                if ((int)ch < 0)
  24.                {
  25.                        *target2++ = *target1++;
  26.                        *target2++ = *target1++;
  27.                }
  28.         }

  29.         *target2 = '\0';

  30.         printf("拷贝完毕!\n");
  31.         printf("现在,str2 中的内容是:%s\n", str2);

  32.         return 0;
  33. }
复制代码


为什么要写那麽多*target2++ = *target1++;
这串代码从while开始就不懂了


为社么能拷贝中英混合的字符串

看不懂
最佳答案
2021-11-15 22:06:13
本帖最后由 wutianlong220 于 2021-11-15 22:18 编辑

先贴上我自己写的答案,测试有效:
  1. #include <stdio.h>
  2. #define MAX 1024


  3. int main(void) {
  4.    
  5.     char str1[MAX] = {'\0'};
  6.     char str2[MAX] = {'\0'};
  7.     int num;
  8.     int start = 0;


  9.     printf("请输入一个字符串到 str1 中:");


  10.     fgets(str1, MAX, stdin);
  11.    
  12.     printf("请输入您需要拷贝的字符个数:");
  13.     scanf("%d",&num);
  14.    
  15.     printf("您输入的字符是:%s\n",str1);
  16.    
  17.     printf("开始拷贝 str1 的内容到 str2 中...\n");

  18.     char *str1_p = str1;
  19.     char *str2_p = str2;


  20.     while((start < num)  &&  *str1_p != '\0'     ) {
  21.         int ch = (int)*str1_p;
  22.         if (ch < 0) { //这里是专门对中文的处理,因为中文是4个字节,3个负数1个0,所以指针需要复制3次
  23.             *str2_p++ = *str1_p++;
  24.             *str2_p++ = *str1_p++;
  25.             *str2_p++ = *str1_p++;
  26.         } else {
  27.             *str2_p++ = *str1_p++;
  28.         }
  29.         start++;
  30.     }
  31.    
  32.     printf("拷贝完毕!\n");
  33.     printf("现在,str2 中的内容是:%s\n",str2);


  34.     return 0;
  35. }
复制代码


然后来给你解释一下
  1. *target2++ = *target1++;
复制代码


这句话到底是什么意思。

这句话的其实就是著名的代码:*p++
所谓的*p++,就是分成两个步骤:
第一,*p
第二,p++


因为p++,是先把p拿过来用,用完了以后再+1,所以整个*p++的意思就是:
p这个指针,先用*符号解引用,拿出里面的东西,然后指针p再向后面移动一位。
如果不太理解,可以点击这里:https://www.bilibili.com/video/BV1sJ411E7St?p=87
可以参考这个视频,从12分28秒开始看,相信你会有所领悟。

懂了之后
然后我们再来看
  1. *target2++ = *target1++
复制代码


这段代码的意思就是说:
先执行:
  1. *target2 = *target1
复制代码

也就是先把target1指针,指向的内容,赋值给target2指针指向的地方,
然后:
  1. target2++;
  2. target1++;
复制代码

也就是两个指针,同时向后移动一位。

懂了吧?
放在这个题目里面就相当于:
str1[0] = str2[0]
然后
str1[1] = str2[1]
然后
str1[2] = str2[2]
然后
str1[3] = str2[3]
一直这样下去。

所以就是,str2和str1这个数组,两个同时向后,一个一个去遍历,遍历一个,str2把内容给str1,然后再遍历到下一个,str2再把内容给str1,然后从数组的最初,一直折腾到指定位置,这样就完成了复制。
所以,关键在于你要记住:
*p++
这个东西,一定要牢牢记住,这个非常重要。


小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2021-11-15 21:36:57 | 显示全部楼层
  1. #include <stdio.h>

  2. #define MAX 1024

  3. int main()
  4. {
  5.         char str1[MAX];
  6.         char str2[MAX];

  7.         char *target1 = str1;
  8.         char *target2 = str2;

  9.         char ch;
  10.         int n;

  11.         printf("请输入一个字符串到 str1 中:");
  12.         fgets(str1, MAX, stdin);

  13.         printf("请输入需要拷贝的字符个数:");
  14.         scanf("%d", &n);

  15.         printf("开始拷贝 str1 的内容到 str2 中...\n");
  16.         while (n--)
  17.         {
  18.                //ch = *target2++ = *target1++;
  19.                *target2 = *target1;
  20.                ch = *target2;
  21.                target1++;
  22.                target2++;

  23.                if (ch == '\0')
  24.                {
  25.                        break;
  26.                }
  27.                if ((int)ch < 0)
  28.                {
  29.                        //*target2++ = *target1++;
  30.                        *target2 = *target1;
  31.                        target1++;
  32.                        target2++;

  33.                        //*target2++ = *target1++;
  34.                        *target2 = *target1;
  35.                        target1++;
  36.                        target2++;

  37.                }
  38.         }

  39.         *target2 = '\0';

  40.         printf("拷贝完毕!\n");
  41.         printf("现在,str2 中的内容是:%s\n", str2);

  42.         return 0;
  43. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-15 22:06:13 | 显示全部楼层    本楼为最佳答案   
本帖最后由 wutianlong220 于 2021-11-15 22:18 编辑

先贴上我自己写的答案,测试有效:
  1. #include <stdio.h>
  2. #define MAX 1024


  3. int main(void) {
  4.    
  5.     char str1[MAX] = {'\0'};
  6.     char str2[MAX] = {'\0'};
  7.     int num;
  8.     int start = 0;


  9.     printf("请输入一个字符串到 str1 中:");


  10.     fgets(str1, MAX, stdin);
  11.    
  12.     printf("请输入您需要拷贝的字符个数:");
  13.     scanf("%d",&num);
  14.    
  15.     printf("您输入的字符是:%s\n",str1);
  16.    
  17.     printf("开始拷贝 str1 的内容到 str2 中...\n");

  18.     char *str1_p = str1;
  19.     char *str2_p = str2;


  20.     while((start < num)  &&  *str1_p != '\0'     ) {
  21.         int ch = (int)*str1_p;
  22.         if (ch < 0) { //这里是专门对中文的处理,因为中文是4个字节,3个负数1个0,所以指针需要复制3次
  23.             *str2_p++ = *str1_p++;
  24.             *str2_p++ = *str1_p++;
  25.             *str2_p++ = *str1_p++;
  26.         } else {
  27.             *str2_p++ = *str1_p++;
  28.         }
  29.         start++;
  30.     }
  31.    
  32.     printf("拷贝完毕!\n");
  33.     printf("现在,str2 中的内容是:%s\n",str2);


  34.     return 0;
  35. }
复制代码


然后来给你解释一下
  1. *target2++ = *target1++;
复制代码


这句话到底是什么意思。

这句话的其实就是著名的代码:*p++
所谓的*p++,就是分成两个步骤:
第一,*p
第二,p++


因为p++,是先把p拿过来用,用完了以后再+1,所以整个*p++的意思就是:
p这个指针,先用*符号解引用,拿出里面的东西,然后指针p再向后面移动一位。
如果不太理解,可以点击这里:https://www.bilibili.com/video/BV1sJ411E7St?p=87
可以参考这个视频,从12分28秒开始看,相信你会有所领悟。

懂了之后
然后我们再来看
  1. *target2++ = *target1++
复制代码


这段代码的意思就是说:
先执行:
  1. *target2 = *target1
复制代码

也就是先把target1指针,指向的内容,赋值给target2指针指向的地方,
然后:
  1. target2++;
  2. target1++;
复制代码

也就是两个指针,同时向后移动一位。

懂了吧?
放在这个题目里面就相当于:
str1[0] = str2[0]
然后
str1[1] = str2[1]
然后
str1[2] = str2[2]
然后
str1[3] = str2[3]
一直这样下去。

所以就是,str2和str1这个数组,两个同时向后,一个一个去遍历,遍历一个,str2把内容给str1,然后再遍历到下一个,str2再把内容给str1,然后从数组的最初,一直折腾到指定位置,这样就完成了复制。
所以,关键在于你要记住:
*p++
这个东西,一定要牢牢记住,这个非常重要。


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 08:33:48 From FishC Mobile | 显示全部楼层
wutianlong220 发表于 2021-11-15 22:06
先贴上我自己写的答案,测试有效:



自增运算符的优先级高于取值运算符
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 08:37:05 From FishC Mobile | 显示全部楼层
wutianlong220 发表于 2021-11-15 22:06
先贴上我自己写的答案,测试有效:



这个相当于*(target++)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 08:41:01 From FishC Mobile | 显示全部楼层
人造人 发表于 2021-11-15 21:36

为什么小于0的时候需要两次target1++=target2++
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 11:21:45 | 显示全部楼层
因为小于0的时候,代表这个字符是中文啊,正常的英文字母只占1个位置,所以
  1. target1++=target2++
复制代码

只需要这样复制且移动一下就行。
但是一个中文,比一个英文多占用2个字节,所以指针还得多向后面移动2位,才能把一个中文完整复制过来,懂了吧?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 11:23:32 | 显示全部楼层
林江楠 发表于 2021-11-17 08:37
这个相当于*(target++)

你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:
  1. *target++ //这个代码就等于下面的代码

  2. *target;
  3. target++;
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 11:51:02 | 显示全部楼层
林江楠 发表于 2021-11-17 08:41
为什么小于0的时候需要两次target1++=target2++

因为这里假设一个中文字符是3个字节
你那边可能是2个字节也可能是3个字节
这个程序假设是3个字节
这个程序还假设中文字符的3个字节都是负数
所以,小于0就加2次
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 11:55:31 | 显示全部楼层
wutianlong220 发表于 2021-11-17 11:23
你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:
  1.     int num = *p++;
复制代码


这个相当于下面这样

  1.         int *temp = p;
  2.         p++;
  3.         num = *temp;
复制代码


完整的代码
  1. #include <stdio.h>

  2. int main(void) {
  3.     int array[5] = {1, 2, 3, 4, 5};
  4.     int *p = array;
  5.     int num = *p++;
  6.     {
  7.         int *temp = p;
  8.         p++;
  9.         num = *temp;
  10.     }
  11.     return 0;
  12. }
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 14:49:14 | 显示全部楼层
学习 来了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2021-11-17 17:10:05 | 显示全部楼层
wutianlong220 发表于 2021-11-17 11:23
你这样括号括起来就错了,括号括起来代表括号必须先执行。
实际上是相当于:

不是吧

自增运算符的优先级高于取值运算符

先加在解引用
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-11-17 20:47:58 | 显示全部楼层
林江楠 发表于 2021-11-17 17:10
不是吧

自增运算符的优先级高于取值运算符

自增运算符的优先级高于取值运算符,这个是对的。但是q++这个自增,是先用完q之后再自增,跟++q的先加了数字再用,是不一样的。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-7-4 20:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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