2006年9月5日

关于C语言的字符串的问题

这是最近一个同学问我的问题,大致如下


#include <stdio.h>
#include <string.>

void ShowFile(char *fileName);

int main()
{
ShowFile("test");
Printf("%s","Hello World");
}
void ShowFile(char *fileName)
{
FILE *pShowFile;
strcat(fileName,".txt");
fopen("fileName","r");
......
}

ShowFile函数的本意是打印一个文本文件的内容,但这个程序输出的时候,"Hello World"不见了,变成了”.txt"。
实际上常量字符串是作为静态(static)变量来存储的,位置在全局变量之后,strcat()语句在"test"这个字符串之后写上了信息,破坏了下一个字符串"Hello World"的结构。
改写前:t e s t '\0' H e l l o....
改写后:t e s t . t x t '\0'

这个问题通常是这样解决的

void ShowFile(char *fileName)
{
char tempFileName[MAX_FILE_NAME_LENGTH];
FILE *pShowFile;

strcpy(tempFileName, fileName);
strcat(tempFileName,".txt");
fopen("tempFileName","r");
......
}

C语言的字符串处理机制的却并不怎么好,而且不仅仅是静态字符串。想起《JOEL 说软件》提到的事情了。C语言中字符串是以‘\0'作为结束符的。获取字符串长度的办法就是:从串首开始遍历,直到遇到这个结束符。这个方案也许也并不怎样,效率很低。
Joel提到了Pascal的字符串处理机制,串的第一位存储长度,不仅获取长度的问题解决了,而且两个串合并的问题也变得更容易了。可以通过一次移位到字符串的末尾!

还讲了一个油漆匠的故事。他的名字我忘记了。就是说有一个油漆匠吧,他负责漆路面,第一天漆了很远,老板夸奖他。第二天没有前一天那么远了,但是也算不少。第三天,他非常的卖力,但是仅仅,漆了很短的距离。因为他离油漆桶越来越远了。这就是C语言的字符串,每一次操作都从头开始。要保留当前计算的结果,所以要带着油漆桶走。

1 条评论:

FrozenTPot 说...

写得真不错,油漆匠的故事很贴切~