2012-10-01 50 views
0

可能重复:
Using fseek with a file pointer that points to stdinFSEEK不会在Linux工作

我有使用FSEEK清除我的输入缓冲器中的程序,它的工作原理以及在Windows中,BUF失败在Linux中。请帮帮我 。

#include <stdio.h> 
#define NO_USE_FSEEK 0 

int main(int argc, char *argv[]) 
{ 
    char ch = 'a'; 
    int i = 1; 
    long int fpos = -1; 

    while(1) 
    { 
     printf("loop : %d\n", i); 

     fseek(stdin, 0L, SEEK_END); /*works in Windows with MinGW, fails in Linux*/ 
     fpos = ftell(stdin); 
     if (-1 == fpos) 
     { 
     perror("ftell failure:"); /*perror tells it is Illegal Seek*/ 
     printf("\n"); 
     } 
     else 
     { 
     printf("positon indicator:%ld\n", fpos); 
     } 
     scanf("%c", &ch); 
     printf("%d : %c\n", (int)ch, ch); 
     i++; 

    } 

    return 0; 
} 

在此先感谢!

+4

想象一下'stdin'是一个水龙头。显然你想打开水龙头并“寻找”到最后一滴......然后(用'scanf()'调用)挤出更多的水滴:) – pmg

回答

1

我想fseek不会和stdin一起工作。因为标准输入的大小未知。

1

fseek()测试返回值(实际上,测试所有<stdio.h>输入函数的返回值)。

if (fseek(stdin, 0, SEEK_END) < 0) { perror("fseek"); exit(EXIT_FAILURE); } 

使用成语

while ((ch = getchar()) != '\n' && ch != EOF) /* void */; 
/* if (ch == EOF) 
**  call feof(stdin) or ferror(stdin) if needed; */ 

忽略在输入缓冲区中的所有字符到下一个ENTER(或文件或输入错误的结束)。

+0

为什么错误?使用EOF完成输入流是完全有效的:(a)当它从一个文件重定向时,并且你读完所有的文件; (b)当用户在终端中输入EOF字符时(例如,在Linux中使用Ctrl + D或在Windows cmd中使用AFAIR,Ctrl + Y/Z时)。 –

+0

@PiotrKalinowski:'getchar()'在两种情况下返回EOF。为了识别它,EOF是由于文件结束或某种错误需要调用另一个函数('feof()'或'ferror()')。当我在回答“输入错误”时说过,我在该组中包括文件结束条件。现在修好了,谢谢。 – pmg

2

这不是在Windows或Linux上“清除输入缓冲区”的可接受方式。

在windows上,使用MSVCRT版本的标准C函数,有一个扩展允许fflush(stdin)用于此目的。请注意,在其他系统上,这是未定义的行为。

Linux有一个功能叫做fpurge具有相同的目的。

但是,我要问,为什么是否要清除输入缓冲区?如果人们通常抱怨scanf没有读到行尾,那么最好编写代码来实际读取并丢弃行的其余部分(与getc一起循环直到读取'\n',例如,如pmg的回答)。清除输入缓冲区时,在使用重定向文件或管道而不是正常的控制台/ tty输入时,将趋向于跳过大量数据。