2011-11-23 53 views
2

我有一个现有的程序,其中一条消息(例如,电子邮件或其他类型的消息)将进入stdin上的程序。 我知道stdin是一个FILE *,但我对它还有什么其他的特性有些困惑。我目前正试图在程序中添加一个检查,并且如果它包含一个特定的行(例如,单词“hello”),则会以不同的方式处理该消息。问题是,我需要搜索文件中的那个单词,但是我仍然需要stdin在程序中稍后指向它的原始位置。结构的概况如下:C文件指针,stdin上的多个读取

目前:

//actual message body is coming in on stdin 
read_message(char type) 
{ 

//checks and setup 

if(type == 'm') 
    { 
    //when it reaches this point, nothing has touched stdin 
     open_and_read(); //it will read from stdin 
    } 

//else, never open the message 
} 

我想添加其他检查,但在这里我要搜索邮件正文中。 像这样:

//actual message body is coming in on stdin 
read_message(char type) 
{ 

//checks and setup 

//new check 
if(message_contains_hello()) //some function that reads through the message looking for the word hello 
{ 
    other_functionality(); 
} 

if(type == 'm') 
    { 
     //when it reaches this point, my new check may have modified stdin 
    open_and_read(); //it will read from stdin 
    } 

//else, never open the message 
} 

的问题,这是搜索的邮件正文,我触摸到文件指针标准输入。但是,如果我仍然需要在第二个if语句中打开并阅读消息(如果type ='m'),则stdin需要指向它指向程序开始处的相同位置。我试图创建一个指针的副本,但只能成功创建一个副本,如果修改本身,它也会修改stdin。

我没有关于如何传递消息的选择 - 它必须留在stdin上。我如何访问标准输入框中的消息的实际主体而不修改标准输入自身? 基本上,我怎样才能读取它,然后让另一个函数能够从消息的开头读取呢?

回答

2

简短的答案是,你不能。一旦你从标准输入中读取数据,它就消失了。

因此,您唯一真正的选择是保存您阅读的内容,并对其进行后期处理,而不是直接从标准输入中读取。如果后来的处理要求从文件中读取数据,则有一种可能性是将其作为两个独立的程序构建,一个作为另一个的过滤器。

+0

好吧,喂。谢谢你的信息! – VMills

+0

另一种可能性是使用'tmpfile'并将所有读取的数据存储到它提供的'FILE'中,然后倒带并从那里读取。 –

+0

也unputc ... :) –

2

一般而言,您只能从stdin中读取一次字节。没有fseek()功能。为了解决这个问题,你可以在你的程序中将字节读入缓冲区,查看字节,然后将缓冲区传递给另一个实际上对其他数据执行操作的函数。

根据您的程序,您可能只需要读取stdin中的部分数据,或者您可能需要将其全部读入该缓冲区。无论如何,您可能需要以某种方式修改程序中的现有代码。

1

我知道stdin是一个FILE *,但我对它还有什么其他特性有些困惑。

好吧,它已开放阅读。但它不保证是可搜索的,所以你需要完全读取它的内容,然后处理结果字符串(或字符串列表,或其他)。

0

您应该使用并利用缓冲(<stdio.h>提供缓冲的I/O,但请参阅setbuf)。

我的建议是逐行读取您的stdin,例如,使用getline。一旦你读完整行,你可以在里面做一些最小的预见。

也许你可能读了更多关于parsing技术。

+0

'setbuf'与OP的问题无关(实际上完全没用)。 –

+0

是的,除了要求行缓冲.... –

+0

'setbuf'不能要求行缓冲。只有'setvbuf'可以。 –