我创建了一个程序来模拟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行。我该如何纠正? 谢谢。
答案 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()
存在问题,并且循环仍然需要进一步的重组!