K& R- ex 5.13:编写我自己的UNIX命令尾的基本版本;由于删除了评论而导致意外输出

时间:2017-03-27 20:20:13

标签: c unix

问题要求

  

编写程序尾部,打印其输入的最后n行。默认情况下,n为10,我们可以说,但可以通过可选的参数进行更改,以便

     

tail -n

     

打印最后n行

现在,我的程序在命令行中获取一个可选的参数n,在执行时询问输入的文件名并打印其最后n行。它还会在开头打印一些数字,指定数组中相应行的索引。

这是错误:

当我使用12作为命令行参数运行此程序并输入此源文件作为文件名时,它无限打印。这是代码:

/*PROGRAM TO PRINT THE LAST 'n' LINES OF INPUT
 *CHECKLILST:
 *  -stores the lines as an array of pointers
 *  -accepts n from the command line
 */

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

#define SIZE 100    /*maximum no. of characters in each line*/
#define DMAX 5      /*default value of no. lines to print*/

void readlines(int *, int *, char **);
void printlines(int *, int *, char **);

int main(int argc, char *argv[])
{
    int start= 0; /*stores the location of the oldest line read*/
    int n= (argc==1)?DMAX:atoi(argv[1]+1);
            printf("Value of n is %d\n\n", n);
    char *line[n];
    int i;
    for(i=0; i<n; i++)
        line[i]= NULL;
    readlines(&start, &n, line);
    printlines(&start, &n, line);
    return EXIT_SUCCESS;
}

/*readlines(): reads lines from a file and stores it as required*/
void readlines(int *start, int *n, char *line[])
{
    char cline[SIZE];
    printf("Enter the name of the file\n");
    char filename[20];
    scanf("%s", filename);
    FILE *fin= fopen(filename, "r");

    int i= 0;
    while(fgets(cline, SIZE, fin)) {
        if(line[i%*n]!=NULL)
            free(line[i%*n]);
        line[i%*n]= strdup(cline);

        ++i;

        if(*start+1==*n) {
            *start= 0;
            continue;
        }
        if(i>=*n)
            ++*start;
    }
    --*start;   /*compensate for the extra updation*/
    fclose(fin);
}

/*printlines(): prints the lines*/
void printlines(int *start, int *n, char *line[])
{
    int i=*start;
    do {
        printf("%d. %s\n", i, line[i]);
        if(i==*n-1)
            i= 0;
        else
            ++i;
    }
    while(i!=*start && line[i]!=NULL);
}

注意 - 此程序对所有其他输入和争论完全正常。更奇怪的是,当我输入评论(任何评论),甚至在do语句结束前插入一个空行时,

do {
        printf("%d. %s\n", i, line[i]);
        if(i==*n-1)
            i= 0;
        else
            ++i;
    }

它给出了预期的输出。

注意2-如果你修改了它,很可能你不会得到同样的错误,因为即使添加一个空白行也可以正常工作。

1 个答案:

答案 0 :(得分:1)

您的文件中有71行。这意味着,对于n == 12 readlines,您的*start函数会在将 --*start; /*compensate for the extra updation*/ 设置为0后完成循环。

但是你这样做了:

*start == -1

你真的应该确保&#34;更新&#34;碰巧开始了。因为如果它没有,你最终会得到i。然后你的循环会无限期地运行,因为if (*start) --*start; else *start = *n-1; 永远不会等于-1。

快速修复:

'<ul class="sortable">\n' + ul.call(sub_ul, indent+8) + '\n' + ul_spaces + '<ul>\n' +