字符串输入时的strlen()与\0
在做串的数据结构时,被字符串printf %s输出时的结尾判断、strlen();长度、自定义StrCopy();字符串复制函数、StrAssign();字符串赋值函数卡了一下,固写此博巩固相关知识点。
正文如下:
串的结构
这里操作实现的串T是一个0位存储长度、其余位置用于存储字符的串。
相关模块代码
首先,给出字符串赋值函数的代码,便于之后的理解。
#define OK 1
#define MAXSTRLEN 40
typedef int Status;
typedef char SString[MAXSTRLEN];
Status StrAssign(SString T,char *chars)
{
int i;
if(strlen(chars)>MAXSTRLEN)
{
for(i = 1;i <= MAXSTRLEN;i++)
{
T[i] = *(chars + i - 1);
}
T[0] = MAXSTRLEN; //T[0]存入int 型数据,%s无法打印
}
else
{
T[0] = strlen(chars);
for(i = 1;i <= strlen(chars);i++)
{
T[i] = *(chars + i - 1);
}
}
return OK;
}
代码易错点分析
尤其要注意 strlen() 函数,它在计算长度时没有将' \0 '计算在内,不然就没有空串(长度为零的串)这一说,下面举一个例子去论证·:
#include <string.h>
#include <stdio.h>
#include <conio.h>
#include <dos.h>
int main( void )
{
char buffer[61] = "How long am I?";
int len;
len = strlen( buffer );
printf( "'%s' is %d characters long\n", buffer, len );
}
/****************
output:
'How long am I?' is 14 characters long
*******************/
然后我们运用这个结论再去看串赋值函数,就能明白由于循环结束条件是 i <= strlen(chars) ,chars中的' \0 ‘ 是不会赋值给T的,所以当你用printf %s 输出时,数组的存储内容中找不到' \0 ',所以就会一直读下去,直到某个内容是’ \0 ‘ 为止。
以下是我的代码论证:
1. 通过gets(); 或者 scanf(); 由于gets();的特性是将输入的' \n ' 转化为 ' \0 ' 然后赋值给字符串,scanf();的特性是串中读到空白字符(' \n ',' ',与' \t ') 的时候将空白字符转化为\0赋值给字符串,并在缓存区中载入' \n ',因此当用gets();或者scanf();输入'abc'后,str中的char数组都将被赋值为 ' a ' ,' b ',’ c ‘,’ \0 ‘ 。
2. 通过StrAssign();函数 将str的串值赋值给s1,由于循环结束条件是 i <= strlen(chars) ,所以’ \0 ‘不会被赋值到s1当中去。
3.printf(%s, ); 找不到串尾标识‘ \0 ',不断向下查找知道下一个' \0 '的出现,所以导致乱码
代码修改
想到达到printf(%s,);能够正常输出的结果,则需要在串赋值时加上\0,修改情况以及程序执行情况如下:
或者对于串首存长度这种特性的字符串单独写一个Print函数,将s1[1]到s1[MAX]给打印出来。
修改情况以及执行情况如下:
#define OK 1
typedef int Status;
/* 打印字符串 */
Status StrPrint(SString T)
{
int i;
for(i = 1;i <= T[0];i++)
printf("%c",T[i]);
printf("\n");
return OK;
}
学会并运用数据结构,的确不易,应潜下心来好好钻研,忌一蹴而就。