在做串的數據結構時,被字符串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;
}

學會並運用數據結構,的確不易,應潛下心來好好鑽研,忌一蹴而就。
