代码:
#include <stdio.h>
#define MAXLINE 1000 /* 允许输入行的最大长度 */
int get_line(char line[], int maxline);
void copy(char to[], char from[]);
/* 打印最长的输入行 */
int main()
{
int len;
int max;
char line[MAXLINE];
char longest[MAXLINE];
max = 0;
while ((len = get_line(line, MAXLINE)) > 0)
{
if(len > max)
{
max = len;
copy(longest, line);
}
}
if(max > 0)
{
printf("The longest line is: %s", longest);
}
return 0;
}
/* get_line 函数:将一行读入到S中并返回其长度 */
int get_line(char s[], int max_len)
{
int c = 0, i = 0;
for( i = 0; i < max_len - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
{
s[i] = c;
}
if(c == '\n')
{
s[i] = c;
++i;
}
s[i]='\0'; /* 字符串最后必须以'\0'结束 */
return i;
}
/* copy函数:将from复制到to;假定to足够大 */
void copy(char to[], char from[])
{
int i;
i = 0;
while ((to[i] = from[i]) != '\0')
{
++i;
}
}
运行结果:
分析:
(一)书上写的是getline(char line[], int maxline),咱们这里改成get_line(char line[], int maxline)。因为在linuxc中,stdio.h中包含了getline()函数,所以在Linux/Unix/Mac中,若咱们自定义getline()函数,会与stdio.h.中的getline()函数互相冲突,导致程序编译不过去。
而另外一些编译器,比如VC6中,stdio.h并不包含getline()函数。这种情况下,咱们可以自定义getline()函数。
为了安全起见,咱们把书上的getline()函数改为get_line()函数。同时也可以看出,作者是在Windows下编的程序。
(二)C语言的字符串以’\0’结尾,并且结束符’\0’不算在字符串的长度内。
(三)get_line函数中,i< max_len - 1 && (c = getchar()) != EOF && c != '\n'
这里有三个判断条件:
(1)i < max_len -1;这里max_len = MAXLINE = 1000,所以i的取值范围为(0~998),也就是说最大循环次数为999次,但是字符串的最大长度是1000,还有一个字符是用来做什么的呢?从下面的代码if(c == ‘\n’){s[i] = c; ++i;}可以看出,最后一个位置是用来放换行符\n的。
(2)(c = getchar())!= EOF,这句表示判断输入的字符不是文件结束符EOF。
在Windows系统下,EOF为换行后再按ctrl + z。在Linux/Unix/Mac下,EOF为换行后再按ctrl + d。
(3)c != ‘\n’,表示字符不是换行符。因为碰到换行符时,该行结束。
(四)从get_line函数可以看出,假如一行的内容为ab,那么该行的字符串实际为”ab\n\0”,其实长度为3(包括’\n’但不包括’\0’)。
(五)while ((to[i] = from[i]) != '\0')
这里先把from[i]的值赋给to[i],再让to[i]与’\0’比较。
以from=’ab\n\0’为例
i = 0时,to[0] =from[0] = ‘a’, i = 1
i = 1时,to[1] =from[1] = ‘b’, i = 2
i = 2时,to[2] =from[2] = ‘\n’, i = 3
i = 3时,to[3] =from[3] = ‘\0’, i = 4。此时不符合(to[i] = from[i]) != '\0',循环结束。