K& R练习1.16 - 线路长度的限制

时间:2013-02-27 18:41:17

标签: c kernighan-and-ritchie c89

我正在从K& R的“The C Programming Language”书中学习C.我正在做本书中指定的练习。我的运动编号为1.16,但我不明白。

练习1.16:

  

修改最长线程序的主程序,以便它   正确打印任意长输入行的长度,并作为   尽可能多的文本。

我的问题:

  1. “...尽可能多的文字......” - 字符串长度是否存在一些限制?也许在标准头文件中有一个变量,其中包含字符串长度的最大允许值?

  2. “...任意长输入行的长度......” - 但在代码中MAXLINE被定义为1000.它的大小也是有限的。我看到了一些解决方案here,但在我看来这不是解决方案决定,因为前者对行的长度有限制(1000个字符)。

  3. 也许我不明白这项任务。我的理解是我必须删除1000个字符的限制。

6 个答案:

答案 0 :(得分:15)

在K& R中这是一个非常早期的练习,你只是应该对代码做一些小改动,而不是对代码进行全面的重新设计。

  1.   

    “......尽可能多的文字......”

    取决于你解释。我是通过打印存储在longest缓冲区中的内容来完成的。即打印出最多1000个字符的行。同样,这是一个早期的练习,几乎没有介绍动态分配的内存。在编写K& R时,存储任意长的文本行并不像现在这样可行。

  2.   

    “......任意长输入行的长度......”

    是一项艰难的要求。你应该找到正确的长度,无论它有多长(至少在int的范围内。)

  3. 解决此问题的一种方法是:

    • 调用getline()之后,检查读入line缓冲区的最后一个字符是否为换行符('\ n')
    • 如果是,请阅读完整的一行。 len变量是行的正确长度(getline()的返回值,与原始代码相比,不需要特别考虑。
    • 如果,则您没有读取整行,需要寻找此行的结尾。你添加一个while循环,调用getchar()直到它返回换行符(或EOF),并计算你在该循环中读取的字符数。只需要len++来计算。
    • 当while循环完成时,新的len现在是该行的实际长度,但我们的缓冲区只有它的前999个字符。
    • 和以前一样,如果这条线到目前为止最长,你可以存储(copy()函数调用)当前的line缓冲区(最多1000个字符)。
    • 完成后,打印出以前存储的行(longest缓冲区)和max变量的长度。
      • 由于上面提到的max长度现在正确的while循环。
      • 如果longest行确实长于1000个字符。你至少打印出前999个字符 - 这是“尽可能多”。

    我不会破坏它并发布你需要完成的代码,但只需要6行代码就可以添加到练习1-16的最长行程序中。

答案 1 :(得分:1)

  1. 在现代机器上,“尽可能多的文本”可能是所有文本,这要归功于自动换行终端程序。那本书是在电传终端仍在使用时编写的。除了您正在使用的机器的内存限制外,对字符串长度没有限制。

  2. 他们期望你添加某种循环来读取字符并查找换行符,而不是假设读入MAXLINE大小的缓冲区肯定会包含换行符。

答案 2 :(得分:1)

这是我的版本:

int getline(char s[],int lim)
{
    int c,i;
    for(i=0;i<lim-1&&(c=getchar())!=EOF&&c!='\n';++i)
        s[i]=c;
    if(c=='\n')
    {
        s[i]=c;
        ++i;
    }
    if(c!=EOF)
    {
        while((c=getchar())!=EOF&&c!='\n')
            i++;
    }
    s[i]='\0';
    return i;
}
    #define MAXLINE 1000
    int len;
    int max;
    char line[MAXLINE];
    char longest[MAXLINE];

    max=0;
    while((len=getline(line,MAXLINE))>1)
    {
        if(len>max)
        {
            max=len;
            copy(longest,line);
        }
    }
    if(max>0)
    {
        printf("%d:%s",max,longest);
    }
    return 0;

由于某些未知原因,示例代码在我的PC中不起作用 特别是当条件为“ len> 0”时,循环不会结束 我认为主要原因是当您不输入任何内容时,您仍然必须按Enter键,因此它被接收为“ \ n”,并且len为1; 我认为它满足了打印任意长输入行的长度以及尽可能多的文本的要求。 And it works like this

答案 3 :(得分:0)



    #include

    main()
    {
       long tlength = 0;
       short input, llength = 1;
       while (llength > 0)  {
          llength = 0;
          while ((input = getchar()) != EOF) {
              ++llength;
              if (input == '\n')
              break;
          }
          tlength = tlength + llength;
          printf("\nLength of just above line : %5d\n\n", llength);
       }
       printf("\n\tLength of entire text : %8ld\n", tlength);
       return 0;
    }

据我说,这个问题只需要每行的长度+最后是整个文本的长度。

尝试运行此代码,并告诉我根据问题是否正确,因为我对此问题也感到困惑。

答案 4 :(得分:0)

我想提供的是,如果想象一下您可以复制的字符数限制非常小(例如100个字符),并且您的程序应该判断行数之间的差别,那么此练习实际上更有意义。超过该限制。

(如果您实际上将限制更改为非常小的限制,则代码将变得更易于测试:如果它选择了达到该限制的第一行,您将知道您的代码不起作用,而如果它返回最长行的头几个字符,它可以正常工作。)

保留代码中复制和计数字符的部分,直到遇到换行符或EOF或行大小限制为止。添加代码,该代码将在此计数和复制停止的地方进行拾取,即使在复制停止后,只要getchar()仍未返回EOF或换行符,它将继续计数。

答案 5 :(得分:0)

我的解决方案:就在对 getLine 的调用下方

if ( line[len-1] != '\n' && line[len-1] != EOF) //if end of line or file wasnt found after max length
{
    int c;
    while ( ( c = getchar() ) != '\n' && c != EOF ) 
        len++; //keep counting length until end of line or file is found
}

为了测试它,将 MAXLINE 更改为 25