我该如何纠正此代码,以便获得预期的结果

时间:2018-09-04 10:35:06

标签: c linux

我创建了一个程序来模拟Linux中的“ cat”命令。 我想制作一个程序来满足“ cat”的“ -n”选项的要求,该选项显示行号以及文件内容。 这是我到目前为止所做的。

int numline = 1;
int i = 2;

printf("\t%d  ", numline);

for(i; i < argc ; i++)
{
    fptr = fopen(argv[i], "r");
    if(fptr == NULL)
    {
        printf("Can not open file");
        return -1;  
    }

    c = fgetc(fptr);
    while(c != EOF)
    {
        if(c == '\n')
        {
            numline++;
            printf("\n\t%d  ", numline);    
        }
        else
            printf("%c", c);
        c = fgetc(fptr);
    }
    fclose(fptr);
}

这是示例输出。

1  hi how are you
2  
3  
4  i am fine
5  
6  thank you
7  
8  bye
9  cya
10  garbage text
11  
12  
13  bye
14 

问题出在第14行。文件在第13行结束,但是程序仍然打印第14行。我该如何纠正? 谢谢。

5 个答案:

答案 0 :(得分:2)

阅读时,'\n'表示文本文件中的行尾,而不是新文件的开头,即使C称它为新行

请检查上一个c 是否为if (c == '\n'),而不是测试'\n'来确定新行。

请务必使用int c

// Commented out, not needed
// printf("\t%d  ", numline);

int c;
int previous_c = '\n';
while((c = fgetc(fptr)) != EOF) {
  if (previous_c == '\n') {
    numline++;
    printf("%d  ", ++numline);    
  }
  printf("%c", c);
  previous_c = c;
}

由于输入的最后一个字符可能与'\n'不同,因此代码可以在循环后检测到该字符并添加一个。

if (previous_c != '\n') {
  printf("\n");
}

答案 1 :(得分:1)

之所以会这样,是因为最后一行以O结尾。 您需要重组程序,以使network_mode = "host" 仅在\n之后有一个字符时递增

答案 2 :(得分:0)

colA red blue green 'square' 10 11 12 'circle' 14 15 13 循环中移动printf("\n\t%d ", numline);,并在检查下一行是否有字符后将其放置。

if

答案 3 :(得分:0)

这是while循环的一种解决方法,可以解决此问题。仅当每行末尾最多有一个换行符时,此方法才有效。如果需要多个换行符,则需要一种更通用的方法。

while( c != EOF )
    {
    if( c == '\n' )
        {
        c = fgetc( fptr );
        numline++;
        if( c != EOF )
            {
            printf( "\n\t%d  ", numline );
            }
        }
    else
        {
        printf( "%c", c );
        c = fgetc( fptr );
        }
    }

答案 4 :(得分:-1)

虽然您使用了一种非常通用的设计模式,但有人认为这是古怪的(但不是),我可以谨此指出,当您将c定义为char时, ,函数fgetc()实际上返回int,而EOF实际上是-1而不是字符。

作为更正确的方法,您应先检查EOF,然后再转换为char

int inp = fgetc( fptr );

while ( inp != EOF )
{
  char c = (char)( inp );
  ...
  inp = fgetc( fptr );
}      

一种更好的检测文件结尾的方法是使用feof()和一个do / while循环...

do
{
  int inp = fgetc( fptr );
  if ( inp != EOF )
  {
    char c = (char)( inp )
    ...
  }
}
while( !feof( fptr ) )

尽管已经指出,feof()存在问题,并且循环仍然需要进一步的重组!