K&R《C程序设计语言》p21:打印最长的输入行

代码:

#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',循环结束。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值