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

C K&;R练习1.16-线路长度限制,c,kernighan-and-ritchie,c89,C,Kernighan And Ritchie,C89,我正在从K&R的书中学习C。我正在做书中指定的练习。我在练习1.16,但我不明白 练习1.16: 修改最长线程序的主例程,使其 正确打印任意长输入行的长度,如 尽可能多地阅读课文 我的问题是: “…尽可能多的文本…”-字符串长度有限制吗?也许在标准标题中有一个变量的最大允许值为字符串长度 “…任意长输入线的长度…”-但在代码中,MAXLINE定义为1000。它的尺寸也很有限。我看到了一些解决方案,但我认为这不是解决方案的决定,因为在前者中,对行的长度(1000个字符)有限制 也许我不明白这个任务

我正在从K&R的书中学习C。我正在做书中指定的练习。我在练习1.16,但我不明白

练习1.16:

修改最长线程序的主例程,使其 正确打印任意长输入行的长度,如 尽可能多地阅读课文

我的问题是:

  • “…尽可能多的文本…”-字符串长度有限制吗?也许在标准标题中有一个变量的最大允许值为字符串长度

  • “…任意长输入线的长度…”-但在代码中,MAXLINE定义为1000。它的尺寸也很有限。我看到了一些解决方案,但我认为这不是解决方案的决定,因为在前者中,对行的长度(1000个字符)有限制

  • 也许我不明白这个任务。我的理解是我必须取消1000个字符的限制

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

  • 他们希望您添加某种循环来读取字符和查找换行符,而不是假设读入
    MAXLINE
    大小的缓冲区中肯定会包含换行符


  • 这是K&R中的一个相当早期的练习,您只需要对代码进行一些小的更改,而不是对代码进行完全的重新设计

  • “…尽可能多的文本…”

    由你来解释。我会打印存储在
    最长的
    缓冲区中的内容。i、 e.打印出最多1000个字符的行。同样,这是一个早期的练习,对动态分配内存的介绍还很少。在编写K&R的时候,存储任意长的文本行并不像今天这样可行

  • “…任意长输入线的长度…”

    这是一项严格的要求。无论长度有多长,都应该找到正确的长度(至少在
    int
    的范围内)

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

    • 在调用getline()之后,检查读入
      缓冲区的最后一个字符是否是换行符('\n')
    • 如果是,则阅读完整的一行。
      len
      变量是行的正确长度(getline()的返回值),与原始代码相比无需特别考虑
    • 如果不是,则表示您没有读取整行,需要查找此行的结尾。添加一个while循环,调用getchar(),直到它返回一个换行符(或EOF),然后计算在该循环中读取的字符数。只需执行
      len++
      进行计数
    • 当while循环完成时,新的
      len
      现在是行的实际长度,但是我们的缓冲区只有它的前999个字符
    • 如前所述,如果当前
      缓冲区(最大1000个字符)是迄今为止最长的,则存储(copy()函数调用)当前
    • 完成后,您将像以前一样打印存储的行(最长的
      缓冲区)和长度的
      max
      变量。
      • 由于上述while循环,
        max
        长度现在是正确的
      • 如果
        最长的
        行确实超过1000个字符,那么至少要打印出前999个字符,这是“尽可能多的”
    我不会破坏它并发布完成此任务所需的代码,但您只需要将6行代码添加到练习1-16的最长行程序中。

    以下是我的版本:

    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;
    
    intgetline(字符s[],intlim)
    {
    int c,i;
    对于(i=0;i1)
    {
    如果(长度>最大值)
    {
    max=len;
    副本(最长,行);
    }
    }
    如果(最大值>0)
    {
    printf(“%d:%s”,最大,最长);
    }
    返回0;
    
    由于一些未知的原因,示例代码在我的电脑中不起作用 特别是,当条件为“len>0”时,循环不会结束 我认为主要原因是,当您什么都不键入时,您仍然必须按enter键,因此它被接收为“\n”,len为1; 我认为它满足了打印任意长度输入行的要求,并且尽可能多地打印文本。

    根据我的理解,这个问题只需要任意一行的长度+最后是整个文本的长度


    试着运行这段代码,并告诉我它是否正确,因为我在这个问题上太困惑了。

    我想说的是,如果假设您可以复制的字符数的限制非常小(比如100个字符),并且您的程序应该在这两行之间进行判断,那么这个练习实际上更有意义e超过该限制

    (如果您确实更改了限制,使其非常小,那么代码就更容易测试:如果它选择了达到该小限制的第一行,您将知道您的代码不起作用,而如果它返回最长行的第一个字符,那么它就起作用了。)


    保留用于复制和计数字符的代码部分,直到它达到换行符或EOF或行大小限制。添加用于拾取此计数和复制结束位置的代码,并在复制停止后继续计数,只要getchar()仍然没有返回EOF或换行符。

    我的解决方案:就在对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

    我现在没有带K&R,因此我无法真正检查最长行程序的要求。不过,请记住,您可以读取、打印和计数单个字符,而无需将它们保存在字符串中。@pmg但根据任务的文本,我
    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
    }