C указатели файла, многократные чтения на стандартном вводе - PullRequest
2 голосов
/ 23 ноября 2011

У меня есть существующая программа, в которой сообщение (например, электронное письмо или другой вид сообщения) будет входить в программу на stdin.Я знаю, что stdin - это ФАЙЛ *, но я не совсем понимаю, какие у него особые характеристики.В настоящее время я пытаюсь добавить проверку в программу и обработать сообщение по-разному, если оно содержит определенную строку (скажем, слово «привет»).Проблема в том, что мне нужно поискать в файле это слово, но мне все еще нужно, чтобы 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
}

Проблема в том, что для поиска в теле сообщения мне нужно прикоснуться к указателю файла stdin.Но, если мне все еще нужно открыть и прочитать сообщение во втором операторе if (если type = 'm'), stdin должен указывать на то же место, на которое он указывал в начале программы.Я попытался создать копию указателя, но был успешным только при создании копии, которая также изменила бы стандартный ввод, если изменился сам.

У меня нет выбора, как передать сообщение - оно должно оставаться наSTDIN.Как я могу получить доступ к реальному телу сообщения, поступающего на стандартный ввод, не изменяя сам стандартный ввод?По сути, как я могу читать с него, а затем сделать так, чтобы другая функция могла читать и с начала сообщения?

Ответы [ 4 ]

3 голосов
/ 23 ноября 2011

Короткий ответ: ты не можешь.Когда вы читаете данные со стандартного ввода, они исчезают.

Таким образом, ваш единственный реальный выбор - сохранить то, что вы прочитали, и выполнить последующую обработку, а не считывать данные прямо со стандартного ввода.Если ваша последующая обработка требует чтения из файла, одной из возможностей было бы структурировать это как две отдельные программы, одна из которых выступает в качестве фильтра для другой.

2 голосов
/ 23 ноября 2011

Как правило, вы можете читать байты из stdin только один раз. Функций fseek() нет. Чтобы решить эту проблему, вы можете прочитать байты в буфере в вашей программе, просмотреть байты, а затем передать буфер другой функции, которая фактически что-то делает с остальными данными.

В зависимости от вашей программы вам может потребоваться прочитать только некоторые данные на stdin, или вам может понадобиться прочитать все эти данные в этот буфер. В любом случае вам, вероятно, придется каким-то образом изменить существующий код в программе.

1 голос
/ 23 ноября 2011

Я знаю, что stdin - это ФАЙЛ *, но я несколько смущен тем, какие другие специальные характеристики он имеет.

Ну, он открыт для чтения.Но он не гарантированно будет доступен для поиска, поэтому вы захотите полностью прочитать его содержимое, а затем обработать полученную строку (или список строк, или что-то еще).

0 голосов
/ 23 ноября 2011

Вы должны использовать и использовать буферизацию (<stdio.h> обеспечивает буферизованный ввод / вывод , но смотрите setbuf ).

Я предлагаю прочитать ваш stdin построчно, например, используя getline .Прочитав всю строку, вы можете сделать минимальный прогноз внутри.

Возможно, вы могли бы прочитать больше о разборе методов.

...