鱼C论坛

 找回密码
 立即注册
查看: 1874|回复: 8

[已解决]关于C语言中string函数的使用问题

[复制链接]
发表于 2022-7-17 23:13:41 | 显示全部楼层 |阅读模式

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

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

x
代码如下:
#include<stdio.h>
#include<string.h>

int main()
{
        char F1[]="########";
        char F2[]="##      ";
        
        char I1[]=("####");
        char I2[]=(" ## ");
        
        char S1[]=(" ######  ");
        char S2[]=("##    ## ");
        
        char H1[]=("##    ##");
        char H2[]=("##    ##");
        
        char C1[]=(" ###### ");
        char C2[]=("##    ##");
        
        
        int a,i;
        
        printf("请输入字母的间隔(空格数):");
        scanf("%d",&a);
        
        char kg[]=" ";
        
        for(i=0;i<a;i++)
        {
                strcat(kg," ");
        }
        
        strcat(F1,kg);
        strcat(F1,I1);
        strcat(F1,kg);
        strcat(F1,S1);
        strcat(F1,kg);
        strcat(F1,H1);
        strcat(F1,kg);
        strcat(F1,C1);
        
        strcat(F2,kg);
        strcat(F2,I2);
        strcat(F2,kg);
        strcat(F2,S2);
        strcat(F2,kg);
        strcat(F2,H2);
        strcat(F2,kg);
        strcat(F2,C2);
        
        printf("%s\n",F1);//第一次只打印这一行,把F2那行注释
        printf("%s",F2);//第二次只打印这一行,把F1那行注释
                                //第三次把两行都打印出来
        
        return 0;
}

第一次打印的结果:
@HX(HM36$BG12BSA4AQ{1(1.png ,是正确的
第二次打印的结果:
8WFG7T70I]SECZN633{ZI.png ,也是正确的
第三次打印的结果:
Q}XTBIOQV}S{MY95AAE5251.png ,第一行(也即打印的F1)结果错误,第二行(也即打印的F2)结果正确

求问为什么会这样???
最佳答案
2022-7-18 13:33:14
治愈罗小黑 发表于 2022-7-18 11:16
但是你看第一次打印结果,是没问题的啊

没有内存空间怎么cat ?
#include <stdio.h>
#include <string.h>

int main() {
    char F1[1024] = "########";
    char F2[1024] = "##      ";

    char I1[] = ("####");
    char I2[] = (" ## ");

    char S1[] = (" ######  ");
    char S2[] = ("##    ## ");

    char H1[] = ("##    ##");
    char H2[] = ("##    ##");

    char C1[] = (" ###### ");
    char C2[] = ("##    ##");

    int a, i;

    printf("请输入字母的间隔(空格数):");
    scanf("%d", &a);

    char kg[1024] = " ";

    for (i = 0; i < a; i++) {
        strcat(kg, " ");
    }

    strcat(F1, kg);
    strcat(F1, I1);
    strcat(F1, kg);
    strcat(F1, S1);
    strcat(F1, kg);
    strcat(F1, H1);
    strcat(F1, kg);
    strcat(F1, C1);

    strcat(F2, kg);
    strcat(F2, I2);
    strcat(F2, kg);
    strcat(F2, S2);
    strcat(F2, kg);
    strcat(F2, H2);
    strcat(F2, kg);
    strcat(F2, C2);

    printf("%s\n", F1); //第一次只打印这一行,把F2那行注释
    printf("%s", F2);   //第二次只打印这一行,把F1那行注释
                        //第三次把两行都打印出来

    puts("");
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-7-18 07:27:10 From FishC Mobile | 显示全部楼层

回帖奖励 +10 鱼币

溢出了吧
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-18 10:23:35 | 显示全部楼层

具体是啥溢出了啊?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-18 10:33:23 From FishC Mobile | 显示全部楼层
治愈罗小黑 发表于 2022-7-18 10:23
具体是啥溢出了啊?

char F1[]="########";
这里F1的空间已经确定了,那么后面你再用strcat
往里面增加数据,就会溢出,会产生一些未知的结果
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-18 11:16:18 | 显示全部楼层
wp231957 发表于 2022-7-18 10:33
char F1[]="########";
这里F1的空间已经确定了,那么后面你再用strcat
往里面增加数据,就会溢出,会 ...

但是你看第一次打印结果,是没问题的啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-18 13:33:14 | 显示全部楼层    本楼为最佳答案   
治愈罗小黑 发表于 2022-7-18 11:16
但是你看第一次打印结果,是没问题的啊

没有内存空间怎么cat ?
#include <stdio.h>
#include <string.h>

int main() {
    char F1[1024] = "########";
    char F2[1024] = "##      ";

    char I1[] = ("####");
    char I2[] = (" ## ");

    char S1[] = (" ######  ");
    char S2[] = ("##    ## ");

    char H1[] = ("##    ##");
    char H2[] = ("##    ##");

    char C1[] = (" ###### ");
    char C2[] = ("##    ##");

    int a, i;

    printf("请输入字母的间隔(空格数):");
    scanf("%d", &a);

    char kg[1024] = " ";

    for (i = 0; i < a; i++) {
        strcat(kg, " ");
    }

    strcat(F1, kg);
    strcat(F1, I1);
    strcat(F1, kg);
    strcat(F1, S1);
    strcat(F1, kg);
    strcat(F1, H1);
    strcat(F1, kg);
    strcat(F1, C1);

    strcat(F2, kg);
    strcat(F2, I2);
    strcat(F2, kg);
    strcat(F2, S2);
    strcat(F2, kg);
    strcat(F2, H2);
    strcat(F2, kg);
    strcat(F2, C2);

    printf("%s\n", F1); //第一次只打印这一行,把F2那行注释
    printf("%s", F2);   //第二次只打印这一行,把F1那行注释
                        //第三次把两行都打印出来

    puts("");
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2022-7-18 13:37:10 | 显示全部楼层
治愈罗小黑 发表于 2022-7-18 11:16
但是你看第一次打印结果,是没问题的啊

这可是C语言
输出结果正确就意味着程序一定正确?
这是我这边的输出
我这边是直接输出报错信息
具体报错信息自己看吧
$ cat main.c
#include <stdio.h>
#include <string.h>

int main() {
    char F1[] = "########";
    char F2[] = "##      ";

    char I1[] = ("####");
    char I2[] = (" ## ");

    char S1[] = (" ######  ");
    char S2[] = ("##    ## ");

    char H1[] = ("##    ##");
    char H2[] = ("##    ##");

    char C1[] = (" ###### ");
    char C2[] = ("##    ##");

    int a, i;

    printf("请输入字母的间隔(空格数):");
    scanf("%d", &a);

    char kg[] = " ";

    for (i = 0; i < a; i++) {
        strcat(kg, " ");
    }

    strcat(F1, kg);
    strcat(F1, I1);
    strcat(F1, kg);
    strcat(F1, S1);
    strcat(F1, kg);
    strcat(F1, H1);
    strcat(F1, kg);
    strcat(F1, C1);

    strcat(F2, kg);
    strcat(F2, I2);
    strcat(F2, kg);
    strcat(F2, S2);
    strcat(F2, kg);
    strcat(F2, H2);
    strcat(F2, kg);
    strcat(F2, C2);

    printf("%s\n", F1); //第一次只打印这一行,把F2那行注释
    printf("%s", F2);   //第二次只打印这一行,把F1那行注释
                        //第三次把两行都打印出来

    puts("");
    return 0;
}
$ gcc-debug -o main main.c
$ ./main
请输入字母的间隔(空格数):2
=================================================================
==168734==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffd7c63cf52 at pc 0x7f678425f427 bp 0x7ffd7c63cf00 sp 0x7ffd7c63c6a8
WRITE of size 2 at 0x7ffd7c63cf52 thread T0
    #0 0x7f678425f426 in __interceptor_memcpy /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
    #1 0x55c70fb62924 in main /tmp/main.c:28
    #2 0x7f678362928f  (/usr/lib/libc.so.6+0x2928f)
    #3 0x7f6783629349 in __libc_start_main (/usr/lib/libc.so.6+0x29349)
    #4 0x55c70fb62174 in _start (/tmp/main+0x1174)

Address 0x7ffd7c63cf52 is located in stack of thread T0 at offset 50 in frame
    #0 0x55c70fb62258 in main /tmp/main.c:4

  This frame has 12 object(s):
    [32, 36) 'a' (line 20)
    [48, 50) 'kg' (line 25) <== Memory access at offset 50 overflows this variable
    [64, 69) 'I1' (line 8)
    [96, 101) 'I2' (line 9)
    [128, 137) 'F1' (line 5)
    [160, 169) 'F2' (line 6)
    [192, 201) 'H1' (line 14)
    [224, 233) 'H2' (line 15)
    [256, 265) 'C1' (line 17)
    [288, 297) 'C2' (line 18)
    [320, 330) 'S1' (line 11)
    [352, 362) 'S2' (line 12)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /usr/src/debug/gcc/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827 in __interceptor_memcpy
Shadow bytes around the buggy address:
  0x10002f8bf990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bf9a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bf9b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bf9c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bf9d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10002f8bf9e0: 00 00 00 00 f1 f1 f1 f1 04 f2[02]f2 05 f2 f2 f2
  0x10002f8bf9f0: 05 f2 f2 f2 00 01 f2 f2 00 01 f2 f2 00 01 f2 f2
  0x10002f8bfa00: 00 01 f2 f2 00 01 f2 f2 00 01 f2 f2 00 02 f2 f2
  0x10002f8bfa10: 00 02 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bfa20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x10002f8bfa30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==168734==ABORTING
$
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-18 15:55:40 | 显示全部楼层
人造人 发表于 2022-7-18 13:33
没有内存空间怎么cat ?

明白了,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2022-7-18 15:59:20 | 显示全部楼层
wp231957 发表于 2022-7-18 10:33
char F1[]="########";
这里F1的空间已经确定了,那么后面你再用strcat
往里面增加数据,就会溢出,会 ...

我明白了,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-10-6 08:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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