Конвертировать из печати в стиле C ++ в my_printf () - PullRequest
2 голосов
/ 08 октября 2010

C ++ пуристы могут захотеть отвести взгляд сейчас. Ты будешь ненавидеть это.

Мне дали консольное приложение с открытым исходным кодом, которое я объединяю с уже существующим, очень старым, очень большим собственным приложением для Windows. Моя старая программа начала свою жизнь как чистый C, хотя недавно была изменена, чтобы она могла компилироваться как C ++. Моя программа широко использует функцию my_printf (), которая печатает текст в окне.

Старое консольное приложение печатает в стиле C ++ с помощью потоков (я никогда раньше не использовал этот тип механизма печати).

При преобразовании консольного приложения для работы под моей системой я мог вручную редактировать все строки, которые печатают, чтобы они вместо этого использовали my_printf (). Но прежде чем приступить к этому, я подумал, что я просто проверю StackOverflow, чтобы увидеть, пропустил ли я трюк. Например, я мог бы представить, как каким-то образом можно распечатать C ++ через поток, а затем каким-то образом закопать окончательный текст где-нибудь и затем вызвать my_printf () с результатом. Может ли это быть возможным?

РЕДАКТИРОВАТЬ: пожалуйста, обратите внимание, что мои знания C ++ чрезвычайно ограничены, и мне, возможно, придется поискать некоторые вещи, чтобы понять ваши ответы, поэтому, пожалуйста, используйте язык, который облегчает это.

Ответы [ 5 ]

7 голосов
/ 08 октября 2010

Там действительно тривиальный трюк. Но сторонники C ++ будут ненавидеть тот факт, что C ++ имеет чистое решение;)

std::ostream отвечает за форматирование, но не саму печать. Это обрабатывается std::streambuf. std::cout объединяет форматер std::ostream с std::streambuf -обработанным объектом, который пишет в стандартный вывод.

Однако вы можете изменить streambuf поддержку ostream с помощью ostream::rdbuf(newbuf). Поскольку std::cout - это просто еще один ostream, вы также можете заменить его streambuf. В этом случае вам нужно только создать класс streambuf, который записывает уже отформатированный вывод в my_printf(). Это должно быть довольно тривиально.

4 голосов
/ 08 октября 2010

Возможно, вам пригодятся строковые потоки.Например:

std::ostringstream os;
os << "Print " << whatever << data;
my_printf( "%s", os.str().c_str() );

В случае, если вы чувствуете себя авантюрным, вы можете написать вместо этого свой собственный streambuf, который использовал my_printf, и вставить его в объект потока, который в настоящее время используется в выходных выражениях (например, std ::соиЬ).Имейте в виду, что этот последний подход может быть не тривиальным, однако он почти не приведет к изменениям в существующей кодовой базе.

0 голосов
/ 09 октября 2010

Что-то в этом роде может быть полезным:

http://www.codeproject.com/KB/debug/debugout.aspx

Должно быть очевидно, где оно находится, чтобы вы могли напечатать его через свои собственные системы или чтовы.Теоретически вам нужно только найти ссылки на std::cout и заменить их ссылками на ваш собственный объект.

0 голосов
/ 08 октября 2010

Перегрузка глобальной operator<<, вероятно, решит вашу проблему:

#include <iostream>
#include <cstdio>

static int
my_printf (const char* s)
{
  printf ("my_printf: %s\n", s);
}

namespace std {
    std::ostream& operator<< (std::ostream& out, const char* s)
    {
      my_printf (s);
      return out;
    }
}

int
main ()
{
  std::cout << "hello, world"; // => my_printf: hello, world
  return 0;
}
0 голосов
/ 08 октября 2010

Подкласс std::ostream и сделать operator << вызов my_print_f().Вы можете использовать внутренний stringstream в своем потоке для получения строкового представления operator << аргументов.

Тогда вам просто нужно будет найти и заменить, заменив cout (или любой другой поток, на который вы направили выводконсольное приложение) с экземпляром вашего потокового класса.

...