tips:本期有挑战题

你我不曾感受过

# C 语言笑传又来了说是

最近用了 copilot,真不是一般的小机灵鬼,感觉被狠狠监视了

image-20241223090938881

你坝还啥也没写呢,先给我猜出来了

练题还是把它老人家闭了吧,否则手写代码的时候直接变小丑

上题!

注意,以下答案仅供参考,指针这部分我也还在学习中,答案对了也可能不代表规范性适合严格的考试!

# 6.7 字符串

我说我本来想学指针,结果突然发现字符串忘没了于是滚回去复习有人信吗哈哈哈哈哈哈哈

image-20241223091738394

此题注意事项

  1. 博主脑子有点不灵活,先不上链表动态内存之类的高级操作,先用大数组苟分,后面再试高级操作(挖坑)
  2. 打 pwn 后遗症犯了总想来点阴的
  3. 同学,你的思路是什么?我的思路不一定就适合你哦

# 思路知识点:

  1. scanf ("% s") 遇到空格就会停止读取,不会读入空格,在读取字符串时会自动在末尾添加 '\0' 结束符(可以想象 scanf 格式化字符串的本质)
  2. gets (): 会自动添加 '\0', 但不安全,已废弃(但也许考试的话是可以用的)
  3. 如果要处理带空格的字符串输入,更推荐用 fgets ()(但也许考试的话是没必要的)
char word[1000];
fgets(word, sizeof(word), stdin);
  1. strlen () 不会把 '\0' 计算在内,它只计算到 '\0' 之前的字符个数,比如 "hello" 的 strlen () 结果是 5,但是 '\0' 确实会占用数组的一个位置 (word [5])。
char word[1000];
scanf("%s", word);
word[0] = 'h'
word[1] = 'e'
word[2] = 'l'
word[3] = 'l'
word[4] = 'o'
word[5] = '\0'   //scanf 自动添加的结束符
  1. 回车键 (\n) 不会被 scanf ("% s") 存储,如果用 fgets (),回车符会被存储,并且 '\0' 会在回车符之后

是的我刚才拿 scanf 搓半天才发现自己是人机,阴 4 你 8 了

上 wp!!

#include<stdio.h>
#include<string.h>
int main()
{
  char word[1000];
  int num=0,i;
  fgets(word,1000,stdin);// 别忘了,假设用 scanf 的话,字符串变量名本身就是个指针,不要加取地址符
  for(i=0;i<strlen(word);i++) if(word[i] == ' ') num++;
  num++;// 最后一个词算上
  printf("%d",num);
  return 0;
}

<u> 好了我们可以去干一把指针了 </u>

# 挑战:8.7 字符变换

image-20241223101047226

真成笑传了,西八

# 思路知识点:

  1. ASCII 中,32 是空格也就是上文的‘ ’,0-9 是 48-57,A-Z 是 65-90,a-z 是 97-122,也就是大写加 32 就是小写
  2. 这个挑战只是题干长,我们用心想想是可以秒的。可以回看上面字符串在内存里的存储,可能可以更直观一点
  3. 首尾相连考虑 strcat,注意它会干掉第一个 \0

char *strcat(char *dest, const char *src);

  1. 指针的基本知识要牢牢掌握,另外要理解字符和数字的变换

  2. 思路上没有太复杂的东西,一定要注意 * 和 & 的运用,以及字符串变量名指针的本质

此题注意事项:

  1. 此题主要是指针部分比较难,可以对着源码回忆,想想如果是你你会怎么做
  2. 好好读题,不要看见长题干就不想做,啊对我说的就是我自己
  3. 由于函数传虚参实参规则,拿指针打会更稳

我们先一步一步来,以下是我个人解题过程中进行的尝试

对,都来看我没了 copilot 后的铸币操作吧哈哈哈哈哈哈哈我真得不想活辣!!

# 解题过程(最终答案在最后面):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int lens=0;
void StringCode(char *a,char *b)
{
    char c[200];
    c[0]='\0';
    strcat(c,a);
    strcat(c,a);// 首尾相连完成了,暂时存在 c 里,其实就是为了方便第 slen/2 以后的字符
    for(int i=0;i<lens;i++)// 开始遍历了
      {
        if(*(c+i)-*(c+i+(lens/2)) <'a')
        {
            while (*(c+i)<'a')  *(c+i)=*(c+i)+26;
        }
        else if (*(c+i)-*(c+i+(lens/2)) >'z')
        {
            while (*(c+i)>'z')  *(c+i)=*(c+i)-26;
        }
        
      }
    *(c+lens)='\0';
    printf("source=%s",c);// 手动截断
}
int main()
{ 
  char a[100],b[100];
  scanf("%s",a);
  lens=strlen(a);
  StringCode(a,b);
//   printf ("原字符串 =% s\n 新字符串 =% s",a,b);
//   printf("source=%s",a);
  return 0;
}

以下是个人独白,各位低血压可以看看。其实写到这里就差一句话就成功了,可惜后面越改越偏:

先到这里。输入 Weihua,得到的结果是 source=qeihua

也就是 W 正常变了,其他的还没变,迈出了第一步。理论是可行的

但是,为什么别的没有变呢???

在第 10 行后加入 printf ("source=% s\n",c);,发现结果是

source=WeihuaWeihua
source=qeihua

字符串正常拼接了。再把 i 全都打印发现确实已经循环过五次了,手动加的截断点也是正常的

岂有此理?

先把 a 和 b 加上吧,先不调试了,

等等。。。。????

渐渐的写入迷了,导致忘记了题目,接下来半小时越改越偏

最后突然发现,WTF 不对啊,我要打的不是差值吗,这给我干哪来了

image-20241223143929154

有时候就感觉这脑子里面装的是一坨

好了,没啥想说的了已经,上最终 wp

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int lens=0;
void StringCode(char *a,char *b)
{
    char c[200];
    c[0]='\0';
    strcat(c,a);
    strcat(c,a);// 首尾相连完成了,暂时存在 c 里,其实就是为了方便第 slen/2 以后的字符
    for (int i = 0; i < lens; i++) *(c+i)=*(c+i)-*(c+i+(lens/2));
    for(int i=0;i<lens;i++)// 开始遍历了
      {
        if(*(c+i) <'a')  while (*(c+i)<'a')  *(c+i)=*(c+i)+26;     
        if (*(c+i) >'z') while (*(c+i)>'z')  *(c+i)=*(c+i)-26;
        *(b+i)=*(c+i);
      }
    *(b+lens)='\0';
}
int main()
{ 
  char a[100],b[100];
  scanf("%s",a);
  lens=strlen(a);
  StringCode(a,b);
  printf("old=%s\nnew=%s",a,b);
  return 0;
}

image-20241223144241980

AI 依赖有时候真的会导致搓代码搓一半开始自嗨了,唉

今天就先做到这吧,已经铸币了

不懂的可以到 csdn dd 我,我看到后一定第一时间尽力解答