Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 81, средняя оценка - 4.83
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
#1

Как перенести параметры из ф-ции printf() в самодельную - C++

04.06.2011, 09:22. Просмотров 10814. Ответов 103
Метки нет (Все метки)

Ребят, подскажите как решить задачу.
Нужно перенести параметры функции printf() в самодельную ф-цию myfunk(). При условии если булева переменная Х==1. Если не равна 1, то не переносить.
Задача осложняется тем, что число параметров ф-ции может быть переменным.
Подскажите пожалуйста, буду очень признателен.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
04.06.2011, 09:22
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как перенести параметры из ф-ции printf() в самодельную (C++):

Передача ф-ции как параметра другой ф-ции - C++
struct pupil{ char surname; int school; int answer; int num; } tmp, a; int usl(int i, pupil a) { }

Параметры printf - C++
Здравствуйте дорогие форумчане ;) У меня есть вопрос по следующему куску кода. Решив по практиковаться с консольным приложением у меня...

Динамические параметры printf() - C++
Есть код printf("%5s <-- %14s\n", buffer0.c_str(), "n/a"); Что делать если я не знаю на этапе компиляции числа 5 и 14? Для...

Чем ::printf предпочтительнее printf? - C++
Смотрю на код одного толкового программиста и, как новичек в С++, удивляюсь: какой смысл писать в таком стиле? Это же вроде одно и то же....

Калькулятор на Си. Как реализовать триногометрические ф-ции и функцию логарифм? - C++
Написал код в котором надо вводить каждый елемент(первое число, знак операции, второе число, знак операции, 3... знак "=") по отдельности....

Как перенести параметры с XP на 7 - Windows
Не знаю в какой ветке разместить тему, то ли в XP, то ли в 7... Всё началось с того, что установив win7, я не смог установить драйвер на...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:08  [ТС] #61
Гыыыыы.
Попробовал и так сделать, в итоге оказалось что при инициализации переменной "с" int не нужен:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
    extern int  my_putchar([U][I]int[/I][/U] c); //убрал от сюда инт
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
Добавлено через 2 минуты
Ну в принципе теперь компилится нормально, пару замечаний есть(warnings). Но я конечно и по убирал не мало кода, в основном некоторые циклы if, где ругался. Щас довести до ума осталось.
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 14:09 #62
Uklunok, во-первых, зачем в этом фрагменте вообще нужна строка #3?
Во-вторых, в языке С, если у параметров и возвращаемого значения функции опущены аннотации типов, то считается, что тип - int.
0
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:22  [ТС] #63
Ого себе. Этот компилятор оказывается сохранил весь код в ассемблере, поместил его в папку debug, исходный код на Си весит 6,8кБ, а этот на ассемблере 70кБ))

Добавлено через 3 минуты
Цитата Сообщение от Nameless One Посмотреть сообщение
Uklunok, во-первых, зачем в этом фрагменте вообще нужна строка #3?
Не знаю, разве Вы ещё не поняли, что я в Си мало что знаю??))) Ну если строка тут стоит - думаю её лучше оставить, мало ли...
Цитата Сообщение от Nameless One Посмотреть сообщение
Во-вторых, в языке С, если у параметров и возвращаемого значения функции опущены аннотации типов, то считается, что тип - int.
Честно сказать, не знал этого. Ну почему тогда компилятору это не понравилось... Программисты такие чтоль??

Добавлено через 4 минуты
Мистика какая-та. Сделал так:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
    extern   my_putchar(int c);
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
и тоже работает. Почему не ругается на my_putchar()?, её ведь нет нигде

Добавлено через 2 минуты
Может вобще так оставить?:
C
1
2
3
4
5
6
7
8
9
10
static void printchar(char **str, int c)
{
      putchar( c);
 
    if (str) {
        **str = c;
        ++(*str);
    }
    else (void)putchar(c);
}
Так тоже компилится
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 14:29 #64
Uklunok, extern my_putchar - это прототип (объявление интерфейса) функции my_putchar, которая должна быть определена где-то в другой единице трансляции. my_putchar - прототип функции, которая определяется в текущей единице трансляции. Так как эта функция нигде не вызывается, то сам факт, что она не определена, к ошибкам не приводит.

Цитата Сообщение от Uklunok Посмотреть сообщение
Может вобще так оставить?:
Так - нельзя (потому что здесь уже не определение putchar, а ее вызов). Убери вообще 3 строку, она не нужна.
0
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:49  [ТС] #65
else (void)putchar(c); - эту тоже убрать?
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 14:51 #66
Uklunok, а вот это уже убирать не надо
0
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 14:54  [ТС] #67
Ещё ругается на эту строку:
if (*format == '%') goto out;
я её убрал
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 14:57 #68
Uklunok, что именно говорит?

Добавлено через 1 минуту
Цитата Сообщение от Uklunok Посмотреть сообщение
я её убрал
а вот это зря, теперь ты не сможешь вывести символ % в своей функции printf
0
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 15:21  [ТС] #69
дак у меня комилятор виснет.
Тут такая штука получается:
C
1
2
3
4
5
6
7
8
if (*format == '%') goto out;
//дальше ещё if-ы
 
    else  {
        out:
        printchar (out, *format);
        ++pc;
       }
может как-нить по другому реализовать переход на out?

Ни какой ошибки не выдаёт, просто виснет компилятор((

Добавлено через 4 минуты
Хотя в самом исходнике для МК есть такие строки:
C
1
2
main_loop:
    goto main_loop;
значит через goto переходить можно.

Добавлено через 2 минуты
Всё разобрался, тут имя out такое у метки и у переменной одно и тоже.
сделал так:
if (*format == '%') goto out1;
//дальше ещё if-ы

else {
out1:
printchar (out, *format);
++pc;
}

Добавлено через 9 минут
А как быть с параметром %p:
C
1
my_printf("Pointers %p %p %p\n", &uart_iocb, &ch, &ush);
Его к сожалению нету...

Добавлено через 17 секунд
А как быть с параметром %p:
C
1
my_printf("Pointers %p %p %p\n", &uart_iocb, &ch, &ush);
Его к сожалению нету...
0
Evg
Эксперт CАвтор FAQ
17826 / 6036 / 388
Регистрация: 30.03.2009
Сообщений: 16,566
Записей в блоге: 26
05.06.2011, 15:55 #70
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
А во-вторых, надо знать, как НА САМОМ деле реализуются стандартные средства...
То, что написано - это НЕ "как на самом деле реализуются", а "как реализуются в программных соглашениях для архитектуры i386". Перенеси этот код на другую платформу - и он почти наверняка отработает неправильно.

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Все зависит от конкретной ситуации...
Гавнокод в большинстве случаев тоже является следствием конкретной ситуации

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Ибо в-третьих, профи придумали это механизм для себя любимых. Если этого не пробовать, как становиться профи...
У меня нет претензии к статье как таковой. У меня есть претензии к тому, что нигде ни разу не написано, что код не переносимый и так писать код не надо. И как-то неявно проскальзывает, что va_arg'и придумали чисто ради удобства, хотя на самом деле их придумали в первую очередь чтобы разные программные соглашения накрыть универсальным интерфейсом (чтобы коды были переносимыми)

Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Вы про реализацию таблицы виртуальных функций помните? Указатель на указателе сидит, и указателем погоняет!
Только вот никто не пишет кодов таким образом, чтобы через поинтерную арифметику выковыривать из экземпляра класса таблицу виртуальных функций и конечный адрес метода

Добавлено через 1 минуту
Цитата Сообщение от Uklunok Посмотреть сообщение
Залез в <stdio.h> и прототипа ф-ции vprintf() не нашёл
vfprintf есть? В данном случае тебе покатит только функция, начинающаяся на "v" (от "vararg"), ибо она принимает указатель на стек, который в общем случае неизвестно как реализован, но получение этого значения накрыто интерфейсом va_start

Добавлено через 5 минут
Цитата Сообщение от Uklunok Посмотреть сообщение
Значит нужно сделать так, чтобы ф-ция myprintf() вызывала из библиотеки stdio ф-цию printf(), вставляла туда нужные нам параметры для вывода и вывела их на экран
В такой постановке задача невыполнима, потому что функции с переменны числом параметров можно вызвать только напрямую. Никакие функции-прокладки здесь уже не канают. Чтобы можно было делать прокладки, сделаны функции типа vprintf (а сам printf внутри себя так же вызывает vprintf). Если у тебя этой функции нет (ну или нет vfprintf, vsprintf, и т.п.), то единственный способ сделать твою задачу - это ручками написать весь код printf'а. Хотя, если речь идёт о микроконтроллере, то тебе нужен будет ограниченно-кастрированный вариант printf'а, в котором можно будет ограничиться самыми простыми описателями %s, %c, %d, %x
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 15:56 #71
Цитата Сообщение от Uklunok Посмотреть сообщение
А как быть с параметром %p:
чтобы реализовать %p, нужно указатель привести к типу int и вывести его через спецификатор "%#x"
0
Evg
Эксперт CАвтор FAQ
17826 / 6036 / 388
Регистрация: 30.03.2009
Сообщений: 16,566
Записей в блоге: 26
05.06.2011, 15:58 #72
Цитата Сообщение от Nameless One Посмотреть сообщение
чтобы реализовать %p, нужно указатель привести к типу int и вывести его через спецификатор "%#x"
На 32-битных системах %p эквивалентен %x, на 64-битных - эквивалентен %lx. Эквивалентен в смысле реализации
1
ValeryLaptev
Эксперт С++
1041 / 820 / 48
Регистрация: 30.04.2011
Сообщений: 1,659
05.06.2011, 16:00 #73
Цитата Сообщение от Evg Посмотреть сообщение
То, что написано - это НЕ "как на самом деле реализуются", а "как реализуются в программных соглашениях для архитектуры i386". Перенеси этот код на другую платформу - и он почти наверняка отработает неправильно.
Вот к сожалению у меня нет никакой возможности в настоящее время проверить этот все на другой архитектуре. Хотя сам работал на множестве архитектур.
А было бы действительно интересно посмотреть...
Хотя навскидку - только преобразования типов указателей претендуют на специфику архитектуры.
Остальное - вполне стандартный С++...
Хотя на 64-битной - весьма вероятны проблемы. Но написано это было еще в 2003 году...
0
Uklunok
3 / 3 / 0
Регистрация: 08.05.2010
Сообщений: 135
05.06.2011, 16:02  [ТС] #74
Нет, на "v" ничего не начинается. Только
va_start(ap, v) (ap = (va_list) & v + sizeof(v))
va_arg(ap, t) (*(t *) ((ap += sizeof(int)) - sizeof(int)))
va_end(ap) (ap = (va_list) 0)

Как господин Nameless One, сказал сделать, вроде должно работать, ведь проверяться будет на железе
0
Nameless One
Эксперт С++
5773 / 3424 / 255
Регистрация: 08.02.2010
Сообщений: 7,447
05.06.2011, 16:03 #75
Цитата Сообщение от Evg Посмотреть сообщение
На 32-битных системах %p эквивалентен %x, на 64-битных - эквивалентен %lx. Эквивалентен в смысле реализации
ну ТС'у код нужно написать под определенный контроллер, так что, думаю, это не проблема.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.06.2011, 16:03
Привет! Вот еще темы с ответами:

Не могу понять как исправить ошибку Warning: printf() [function.printf]: Too few arguments in Z:\home\ksards.ru\www\id\1.php on line 76 - PHP БД
Помогите связать бд с сайтом я новичок в этом вот код php &lt;?php do { printf(&quot;&lt;div class='blog'&gt;&lt;a href='2.php?id=%s'&gt;%s&lt;/a&gt;...

Узнать в ф-ции имя вызвавшей ф-ции - Python
Это возможно? Т.е. есть некая ф-ция debug(msg), передавать имя вызвавшей ее процедуры в параметрах не вариант, можно ли как-то внутри это...

DLL - как подменить функцию, используя самодельную DLL? - C++ Builder
Очень прошу пособить, кому не трудно... . Проблема в целом не сложная: имеется сторонняя программа (только exe), которая при определенном...

Перетаскивание формы за самодельную рамку - C#
Всем привет. Подскажите, убрал стандартную рамку у программы (FormBorderStyle = None) и сделал свою рамку из picturebox. Теперь я делаю...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
05.06.2011, 16:03
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru