读书人

请问一个C有关问题关于scanfstrle

发布时间: 2012-09-13 09:51:52 作者: rapoo

请教一个C问题,关于scanf,strlen,数组和指针的问题。请向下看。。。
类似代码,四种结果。

C/C++ code
#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){          char str[1];    char n;    printf("Please input a string!");          scanf("%s",&str);    n=strlen(str);          printf("str=%s\n",str);    printf("str=%s\n",&str);    printf("str[0]=%s\n",&str[0]);    printf("str[0]=%c\n",str[0]);    printf("str[0]=%s\n",&str[0]);    printf("str[1]=%c\n",str[1]);        printf("sizeof=%d\n",sizeof(str));    printf("strlen=%d\n",n);    exit(0);}

运行结果:

[root@localhost 桌面]# ./test
Please input a string!123456789
str=13456789
str=13456789
str[0]=13456789
str[0]=1
str[0]=13456789
str[1]=
sizeof=1
strlen=9
问题在第二个字符出错了。。。;
第二次改代码:
C/C++ code
#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){          char str[1];    char n;    printf("Please input a string!");          scanf("%s",&str);    //n=strlen(str);//注释掉          printf("str=%s\n",str);    printf("str=%s\n",&str);    printf("str[0]=%s\n",&str[0]);    printf("str[0]=%c\n",str[0]);    printf("str[0]=%s\n",&str[0]);    printf("str[1]=%c\n",str[1]);        printf("sizeof=%d\n",sizeof(str));    printf("strlen=%d\n",n);    exit(0);}

运行结果:[root@localhost 桌面]# ./test
Please input a string!123456789
str=123456789
str=123456789
str[0]=123456789
str[0]=1
str[0]=123456789
str[1]=2
sizeof=1
strlen=50
第二个字符没问题了。。。只是缺少strlen(str);
第三次改代码:
C/C++ code
#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){          char str[1];    int n;//此时n改为INT ;    printf("Please input a string!");          scanf("%s",&str);    n=strlen(str);          printf("str=%s\n",str);    printf("str=%s\n",&str);    printf("str[0]=%s\n",&str[0]);    printf("str[0]=%c\n",str[0]);    printf("str[0]=%s\n",&str[0]);    printf("str[1]=%c\n",str[1]);        printf("sizeof=%d\n",sizeof(str));    printf("strlen=%d\n",n);    exit(0);}

结果变了:
[root@localhost 桌面]# ./test
Please input a string!123456789
str=1
str=1
str[0]=1
str[0]=1
str[0]=1
str[1]=
sizeof=1
strlen=9
第四次改代码:
C/C++ code
#include "stdio.h"#include "stdlib.h"#include "string.h"int main(){          char str[1];    int n;//此时n改为INT ;    printf("Please input a string!");          scanf("%s",&str);    //n=strlen(str);          printf("str=%s\n",str);    printf("str=%s\n",&str);    printf("str[0]=%s\n",&str[0]);    printf("str[0]=%c\n",str[0]);    printf("str[0]=%s\n",&str[0]);    printf("str[1]=%c\n",str[1]);        printf("sizeof=%d\n",sizeof(str));    printf("strlen=%d\n",n);    exit(0);}

结果又变了:

[root@localhost 桌面]# ./test
Please input a string!123456789
str=123456789
str=123456789
str[0]=123456789
str[0]=1


str[0]=123456789
str[1]=2
sizeof=1
strlen=892613426
我想知道strlen()在这些函数中到底起到了什么作用,为什么影响这么大?

PS:我分不多。。。。

[解决办法]
我也得学学C,高层语言用惯了~~
[解决办法]
首先,要问错误代码会什么会得到某个结果,去看编译原理和编译后的汇编代码
然后,这些代码的问题其实就出在一个地方:str数组越界因而修改了n的内存

局部变量是存放在栈空间里的,你定义一个m字节大小的变量,执行时就将m个字节压入栈空间(本质上是栈顶指针移动,将m字节划入栈)。因此你连续定义str和n两个局部变量,它们的内存空间就是相连的
因此,str数组被scanf函数越界访问的时候,n的内存数据就被改变了

第一个例子,n和str[1]占用同一个字节,n被赋值导致str[1]也同样变成了strlen的返回值9——这是一个不可见字符,因此printf无法让你看见它
第二个例子没什么可说的
第三个例子,跟第一个例子一样,str[1]被改成了不可见字符9,但为什么不输出str[2]之后的东西?因为int型占用4字节,除了最低字节是9之外,其他三个高字节都是有效数据0——没错,对于C风格字符串来说,str[2]就是结束符0了
第四个例子,n没有被初始化,strlen也没有被执行,那么由于scanf访问越界,n的四个字节就等同于str[1]到str[4],按字节换算就是53*256*256*256+52*256*256+51*256+50=892613426

读书人网 >C语言

热点推荐