powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / динамический #define
88 сообщений из 88, показаны все 4 страниц
динамический #define
    #39987271
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ой, только не спрашивайте зачем мне эта хрень.... абсурд, конечно, но надо для решения одной задачи !

Итак, есть ли возможность создать define по алгоритму, если есть, то как?

скажем есть у меня простой дефайн:
Код: plaintext
1.
#define N 7



и мне необходимо создать другой дефайн пусть будет ему имя "test" содержимое которого создавалось бы по алгоритму :
при встрече в коде программы test подменится на int i1=0; int i2=0; int i3=0; int i4=0;... int iN=0; N раз

Пример:
при N=7 схематично код выглядел бы примерно вот так :

Код: plaintext
1.
2.
3.
4.
5.
6.
#define N 7
#define test /*тут какой хитрый код макроса*/

int main {
   test ; // test должен подменится на int i1, int i2,int i3,int i4,int i5,int i6,int i7;
}



на самом деле эта подмена кажется абсурдом и бестолковщиной, но я алгоритм подмены упростил, чтобы не сильно грузить. мне ценна суть реализации.
p.s. хотелось бы это в рамках Си без плюсов.
...
Рейтинг: 0 / 0
динамический #define
    #39987277
L.Otujktd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
andron81,
А как предполагается работать с определенным через макрос набором переменных?
Если n конечно то имхо данное объявление можно реализовать через #if и #elif продублировав столько раз сколько необходимо
...
Рейтинг: 0 / 0
динамический #define
    #39987279
a guest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Код: plaintext
1.
2.
3.
4.
5.
6.
#include <boost/preprocessor/repetition/repeat.hpp>

#define N 7

#define DECL(z, n, text) text ## n = n;
BOOST_PP_REPEAT(N, DECL, int i)


Код: plaintext
1.
int i0 = 0; int i1 = 1; int i2 = 2; int i3 = 3; int i4 = 4; int i5 = 5; int i6 = 6;
...
Рейтинг: 0 / 0
динамический #define
    #39987281
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

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

Я думаю этого делать не нужно на дефайнах. Будешь долго мучится, а на выходе какое-то фуло выйдет. Лучше напиши кодогенератор на обычном Си и генерируй хоть чёрта лысого. Как два байта переслать.
...
Рейтинг: 0 / 0
динамический #define
    #39987334
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
L.Otujktd

Если n конечно то имхо данное объявление можно реализовать через #if и #elif продублировав столько раз сколько необходимо


Разумеется N конечное оно задается в макросе я это писал. вот и мне интересно как циклом сконструировать дефайн )
...
Рейтинг: 0 / 0
динамический #define
    #39987335
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
a guest
Код: plaintext
1.
2.
3.
4.
5.
6.
#include <boost/preprocessor/repetition/repeat.hpp>

#define N 7

#define DECL(z, n, text) text ## n = n;
BOOST_PP_REPEAT(N, DECL, int i)


Код: plaintext
1.
int i0 = 0; int i1 = 1; int i2 = 2; int i3 = 3; int i4 = 4; int i5 = 5; int i6 = 6;



вот это наверно круто ! но подключить вот это:
boost/preprocessor/repetition/repeat.hpp

мне пока не по зубам. где вы это берёте ? что-то гугль не помогает
...
Рейтинг: 0 / 0
динамический #define
    #39987336
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
andron81

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

Я думаю этого делать не нужно на дефайнах. Будешь долго мучится, а на выходе какое-то фуло выйдет. Лучше напиши кодогенератор на обычном Си и генерируй хоть чёрта лысого. Как два байта переслать.


полагаю repeat.hpp это и есть кодгенератор ?
...
Рейтинг: 0 / 0
динамический #define
    #39987354
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Автор напиши на Python динамический фрагмент кода.
...
Рейтинг: 0 / 0
динамический #define
    #39987358
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Автор напиши на Python динамический фрагмент кода.


этого мне ещё не хватало. )))
ну емоё ведь пишут же "stdarg.h", а он на макросах
...
Рейтинг: 0 / 0
динамический #define
    #39987361
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

boost/preprocessor внутри использует собственный фреймворк для работы с кортежами лексем, ну а BOOST_PP_REPEAT помимо этого еще и реализован через копипаст сотен однотипных define, которые наверняка через вспомогательный генератор сделаны.

Поэтому сделать то же самое с нуля без внешнего генератора будет непросто.
Намного проще как выше советовали сделать генератор, который будет данный код генерить.

Ну и главное.
Зачем?
Ведь все это не нужно если применить массив.

Код: plaintext
1.
2.
3.
//int i0 = 0; int i1 = 1; int i2 = 2; int i3 = 3; int i4 = 4; int i5 = 5; int i6 = 6;
int a[N];
for (i = 0; i < N; i++) { a[i] = i; }
...
Рейтинг: 0 / 0
динамический #define
    #39987372
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky

Зачем?
Ведь все это не нужно если применить массив.

Код: plaintext
1.
2.
3.
//int i0 = 0; int i1 = 1; int i2 = 2; int i3 = 3; int i4 = 4; int i5 = 5; int i6 = 6;
int a[N];
for (i = 0; i < N; i++) { a[i] = i; }



я ожидал тут такие ответы. )))
Зачем ? ну затем . НАДО !
...
Рейтинг: 0 / 0
динамический #define
    #39987376
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

отбой . нашёл способ решения проблемы !
...
Рейтинг: 0 / 0
динамический #define
    #39987399
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,

>Зачем?
>Ведь все это не нужно если применить массив.
+1
))
Если вам нужно много динамики или генератор, задумайтесь...) посчитайте до 10...отложите до утра...
...
Рейтинг: 0 / 0
динамический #define
    #39987402
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
mayton
Автор напиши на Python динамический фрагмент кода.


этого мне ещё не хватало. )))
ну емоё ведь пишут же "stdarg.h", а он на макросах

Я не уверен что юзкейс применения макросов "там" - тот что тебе нужен.

Макросы - это вобщем-то самый простой механизм для расширения возможностей языка.
Их специально сделали простыми. Без рекурсий и циклов в фазе трансляции.

Твоя задача ... хм... в некотором роде выходит за рамки простой замены. И вызввает
вопросы такие как "проблема остановки" и прочее. И если ты хочешь поверх макросов
поднять новый язык программирования - то тебе точно не в макросы.

Или в другие макросы. Там... макросы Lisp например. Но это далеко нас уводит от темы С++
...
Рейтинг: 0 / 0
динамический #define
    #39987406
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
PetroNotC Sharp
Anatoly Moskovsky,

>Зачем?
>Ведь все это не нужно если применить массив.
+1
))
Если вам нужно много динамики или генератор, задумайтесь...) посчитайте до 10...отложите до утра...




задача такова , что мне надо прогнать кучу sscanf (string,pattern1, setofVar ); по циклу
с разным параметром pattern1 (с его формированием проблем нет) и с соответствующим набором параметров setofVar .

Проблема только в setofVar . мне этот набор надо задавать динамически исходя из параметра N.
видимо это задача и не для макросов тоже.
...
Рейтинг: 0 / 0
динамический #define
    #39987407
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
petrav
пропущено...

Я думаю этого делать не нужно на дефайнах. Будешь долго мучится, а на выходе какое-то фуфло выйдет. Лучше напиши кодогенератор на обычном Си и генерируй хоть чёрта лысого. Как два байта переслать.


полагаю repeat.hpp это и есть кодгенератор ?

Ну... можно и так сказать. Но сделан он на таких жутких и противоестественных приёмах программирования — вы это даже представить себе не можете. Это не пример для подражания.
...
Рейтинг: 0 / 0
динамический #define
    #39987424
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,

весь этот "велосипед" исходя из условия задачи из K&R. а я дотошный как просят так выполняю.
вот эта задача :

"Перепишите основанную на постфиксной записи программу калькулятора таким
образом, чтобы для ввода и преобразования чисел она использовала scanf и/или sscanf."

как работает калькулятор ? он требует ввода от пользователя строки вида "10 30 + 90 70 - *" ,разносит числа в стек(на самом деле в массив) , а затем достает
числа, производит операции и результат опять заносится в стек. более глубокие подробности не очень важны.
Важно то, что теперь требуют использовать scanf и/или sscanf. то есть я полагаю, что необходимо считать строку scanf("%s",str), а потом "тупо" при помощи
sscanf разнести по переменным (лучше всего в качестве переменных использовать элементы двух массивов с типами int (для чисел) и char (для +, *, / , -) ).

как я вижу решение :
1. оговариваем сколько максимально параметров может быть . Пусть это дефайн N
2. нужно сформировать все различные паттерны исходя из N , скажем для примера это шаблон :
"%d %d %c %d %d %c %c"
и другие ...
3. затем подвергаем введенную строку анализу , для этого делаем череду :
sscanf(s,pattern1, набор параметров исходя из pattern1 )
sscanf(s,pattern2, набор параметров исходя из pattern2 )
sscanf(s,pattern3, набор параметров исходя из pattern3 )
sscanf(s,pattern4, набор параметров исходя из pattern4 )
...
sscanf(s,patternU, набор параметров исходя из patternU )

эти sscanf можно прогонять в цикле пока какой-то из них даст что-то отличное от 0.

проблема состоит лишь в третьем параметре - набор параметров. я этот набор не могу формировать динамически.

Всё это безумие ? ДА. но так я вижу реализацию . так как требуют использовать sscanf и scanf. конечно, я могу сделать куда более рациональней и без всяких сложностей.
...
Рейтинг: 0 / 0
динамический #define
    #39987430
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81Проблема только в setofVar . мне этот набор надо задавать динамически исходя из параметра N.

Используй массив. Заодно избавишься от переменного числа параметров у функции.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987437
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81, обрати внимание что *scanf возвращает целое число - количество заполненных значений. Используй его.
...
Рейтинг: 0 / 0
динамический #define
    #39987438
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81Всё это безумие ? ДА. но так я вижу реализацию .

Этим и отличается нуб от опытного программиста. Первый видит одну реализацию и утыкается в
неё, второй - несколько вариантов реализации и выбирает из них оптимальный.

Подсказка: элементы строки не обязательно читать все за раз. scanf способен остановиться
после первого и продолжить со второго при следующем вызове.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987439
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

andron81Проблема только в setofVar . мне этот набор надо задавать динамически исходя из параметра N.

Используй массив. Заодно избавишься от переменного числа параметров у функции.


длина массива задается вверху макросом (#define N=123) и программа должно подстраиваться исходя из этого N
а то, что массив надо использовать это однозначно. причем их должно быть в количестве 2.
но в ссканф все равно статично придется статично подставлять его элементы.
...
Рейтинг: 0 / 0
динамический #define
    #39987440
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
andron81, обрати внимание что *scanf возвращает целое число - количество заполненных значений. Используй его.


знаю.
...
Рейтинг: 0 / 0
динамический #define
    #39987445
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81длина массива задается вверху макросом (#define N=123) и программа должно подстраиваться
исходя из этого N а то, что массив надо использовать это однозначно. причем их должно быть
в количестве 2.
но в ссканф все равно статично придется статично подставлять его элементы.

Исходя из поставленной задачи:
а) Программа не должна подстраиваться и макрос не нужен.
б) Массива достаточно одного, причём лучше ему быть не массивом, а списком.
в) Да. Причём это будет ровно один элемент: следующее значение операнда.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987446
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
petrav,

весь этот "велосипед" исходя из условия задачи из K&R. а я дотошный как просят так выполняю.
вот эта задача :

"Перепишите основанную на постфиксной записи программу калькулятора таким
образом, чтобы для ввода и преобразования чисел она использовала scanf и/или sscanf."

Я даже не стал дочитывать постановку задачи. Керниган и Ритчи не могли предложить вам решать задачу таким способом как вы хотите. Вы что-то недопоняли в книге, нужно перечитать. И Сибиряков уже написал как нужно сделать.
...
Рейтинг: 0 / 0
динамический #define
    #39987496
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

andron81Всё это безумие ? ДА. но так я вижу реализацию .

Этим и отличается нуб от опытного программиста. Первый видит одну реализацию и утыкается в
неё, второй - несколько вариантов реализации и выбирает из них оптимальный.

Подсказка: элементы строки не обязательно читать все за раз. scanf способен остановиться
после первого и продолжить со второго при следующем вызове.


звучит годно , но он не продолжает, или я неверно тебя понимаю :



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
#define _CRT_SECURE_NO_WARNINGS 1
#define N 10

int main()
{
	int numb[N] = {0};
	char oper[N] = { '\0' };
	char str[] = "10 30 + 90 70 - *";
	int result = 0;
	int indexNumb = 0;
	int indexOper = 0;
	int curentnumValue = 0; 
	char curentchrValue = 0;

	for (int i = 0; i < N; i++)
		if ((sscanf(str, "%d", &numb[indexNumb])) > 0) indexNumb++;  
	else 
		if ((sscanf(str, "%s", &oper[indexOper])) > 0)   indexOper++;
}
...
Рейтинг: 0 / 0
динамический #define
    #39987510
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,
они и не предлагали . они решали задачу о разнесении введенной даты в переменные по средствам sscanf :

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
while (getline(line, sizeof(line)) > 0) {
 if (sscanf(line, "%d %s %d", &day, monthname, &year) == 3)
 printf("верно: %s\n", line); /* в виде 25 дек 1988 */
 else if (sscanf(line, "%d/%d/%d", &month, &day, &year) == 3)
 printf("верно: %s\n", line); /* в виде mm/dd/yy */
 else
 printf("неверно: %s\n", line); /* неверная форма даты */
}


где функция getline чтение из потока строки (до того как встретиться \n)
поэтому в этой задаче я решил пойти подобным путем. только паттернов больше будет и sscanf.
поэтому динамически планировал их делать
...
Рейтинг: 0 / 0
динамический #define
    #39987512
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

лучше всего в качестве переменных использовать элементы двух массивов с типами int (для чисел) и char (для +, *, / , -)

IMHO
Если понять, что "элементы двух массивов с типами int (для чисел) и char" полный бред, то желание использовать scanf так же пропадет.

Должно быть не два массива, а "токен" с типом: или константа (на самом деле, __операция__ записи числа в стек) или арифметическая операция (извлечение чисел из стека, выполнения операции над числами, запись результата в стек)

Соответственно scanf ничем помочь не сможет и он не нужен. Нужна ф-ция определяющая тип токена по его содержимому, можно для начала вообще какой нибудь гуано-код на if сделать:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
if strcmp( token_str, "+" ) {
  Plus_Operator;
} else if ( strcmp( token_str, "-" )==0 )  {
  Minus_Operator;
} else if ( strcmp( token_str, "*" )==0) ) {
   Mul_Operator;
} else if ( strcmp( token_str, "/" )==0 ) {
   Div_Operator;
} else {
   Parse_Value_And_Push( token_str );
}


p.s. На C давно не писал, т.ч. могу ошибаться
p.p.s. Сам бы я на if делать не стал бы, но для первого приблежения мне кажется сойдет.
...
Рейтинг: 0 / 0
динамический #define
    #39987514
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81или я неверно тебя понимаю

Да. С какого-то перепою ты scanf прочитал как sscanf.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987520
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

а разница ? одна читает из потока, вторая из строки. Ну ладно, сейчас переделаю на scanf
...
Рейтинг: 0 / 0
динамический #define
    #39987528
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,
scanf передвигает указатель потока на конец прочитанных данных
sscanf ничего не передвигает, поэтому его неудобно использовать для поэлементного чтения строки (надо вручную считать смещение с которого надо продолжать)
...
Рейтинг: 0 / 0
динамический #define
    #39987530
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
надо вручную считать смещение с которого надо продолжать

см. параметр %n в sscanf
...
Рейтинг: 0 / 0
динамический #define
    #39987533
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovskyего неудобно использовать для поэлементного чтения строки (надо вручную считать смещение с
которого надо продолжать)

man говорит, что есть шаблон %n, который способен это сделать за тебя.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987543
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
man говорит, что есть шаблон %n, который способен это сделать за тебя.

Да, я выше написал.
Но это нужна адресная арифметика, самое то для новичков ))
...
Рейтинг: 0 / 0
динамический #define
    #39987548
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

а как ваще ?
у меня 2 разных шаблона это
1.%d или как вы хотите %n (мне тоже с ним не повезло)
2.%с
я читаю "пообъектно" поток (под объектом будем подрузамевать или число или символ + * / - )
когда читается объект scanf() с шаблоном %n (- тут указана интовая переменная для сохранения), а объект оказался например символьной и в результате этот объект нигде не сохранен и утерян...
следующий scanf его уже не прочитает.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int main()
{
	int numb[N] = {0};
	char oper[N] = { '\0' };
//	char str[] = "10 30 + 90 70 - *";
	int indexNumb = 0;
	int indexOper = 0;

	for (int i = 0; i < N; i++)
		if ((scanf("%n ", &numb[indexNumb])) > 0) indexNumb++;  
	else 
		if ((scanf("%c ", &oper[indexOper])) > 0)   indexOper++;
}
...
Рейтинг: 0 / 0
динамический #define
    #39987555
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

%n надо использовать в том же вызове sscanf.

Код: plaintext
1.
2.
3.
4.
while (sscanf(line, " %d%n", &n, &offset) == 1) {
        line += offset;
        ...
}



Для scanf он вообще не нужен.
Код: plaintext
1.
2.
3.
while (scanf(" %d", &n) == 1) {
        ...
}
...
Рейтинг: 0 / 0
динамический #define
    #39987558
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81а как ваще ?

Моск включить, чтобы не тупо повторять всё, что тебе говорят, а ещё и понимать смысл,
скрытый за соловами.

scanf и %n две взаимозаменяемые вещи, а не совместно используемые.

выше тебе уже код привели.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
int main()
{
   char buf[20];
   while (scanf("%s", buf) != EOF)
   {
     if (strcmp(buf, "+") == 0)
       do_add();
     else
     {
       int i;
       if (sscanf(buf, "%d", &i) == 0) printf("хрень какая-то"); return 1;
       do_push(i);
     }
   }
   printf("результат = %d", do_pop());
}


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987563
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky


Для scanf он вообще не нужен.
Код: plaintext
1.
2.
3.
while (scanf(" %d", &n) == 1) {
        ...
}





ваш цикл будет выполняться пока в потоке числа идут, а если + * / - , то этот символ никуда не сохранится потому что n-интовая переменная наверно.
...
Рейтинг: 0 / 0
динамический #define
    #39987571
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
int main()
{
   char buf[20];
   while (scanf("%s", buf) != EOF)
   {
     if (strcmp(buf, "+") == 0)
       do_add();
     else
     {
       int i;
       if (sscanf(buf, "%d", &i) == 0) printf("хрень какая-то"); return 1;
       do_push(i);
     }
   }
   printf("результат = %d", do_pop());
}




Да но это не то, что я хотел бы увидеть. так и я умею. это тупое сливание объекта в "строку" и анализ на предмет какой это природы.
я предполагал , что использовав sscanf можно слить непосредственно в переменные исходя из шаблона: что - то вроде вот этого примера из K&R
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
while (getline(line, sizeof(line)) > 0) {
 if (sscanf(line, "%d %s %d", &day, monthname, &year) == 3)
 printf("верно: %s\n", line); /* в виде 25 дек 1988 */
 else if (sscanf(line, "%d/%d/%d", &month, &day, &year) == 3)
 printf("верно: %s\n", line); /* в виде mm/dd/yy */
 else
 printf("неверно: %s\n", line); /* неверная форма даты */
}
...
Рейтинг: 0 / 0
динамический #define
    #39987579
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

...что - то вроде вот этого примера из K&R

Примера как НЕ надо делать?

http://lib.ru/ANEKDOTY/osterwred.txt
...
Рейтинг: 0 / 0
динамический #define
    #39987590
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
andron81

...что - то вроде вот этого примера из K&R

Примера как НЕ надо делать?

http://lib.ru/ANEKDOTY/osterwred.txt


В книге и разобрана эта задача ранее токенами и читалось getchar ом. Ясен болт, что при помощи scanf и sscanf наверно не очень прикольно делать. Ну уж извините меня, что выбрал не ту книгу в которой только что пример был смотреть ввше и сделать просили именно scanами, и я буду иметь ввиду, что для вас K&R два маразматика.
...
Рейтинг: 0 / 0
динамический #define
    #39987614
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

и сделать просили именно scanами

Можно ссылку на книгу и страницу с оригинальной постановкой задачи.

В Вашем сообщении, два момента, которые "бредовые"
1. парсинг с помощью scanf
один токен преобразовать элементарно, банально заменив atoi на sscanf - зачем, не очень понятно, но можно.
парсить все выражение - какой-то безумство. Начиная с "оговариваем сколько максимально параметров может быть . Пусть это дефайн N", одно это все решение преврашает в какой-то .... (цензурных слов не находится) Сомневаюсь, что бы K&R были настолько садисты по отношению к пользователям.
2. даже если Вы отпарсите, как хотите, счастье это принести НЕ может. Т.к. ДВА разных массива с операндами и операциями это НЕ калькулятор, а какая-то помойка. Важен порядок следования операндов и операций, а он будет потерян.
к примеру:
10 30 + 90 70 - * = (10+30)*(90-70) = 800
а
10 30 90 70 + - *
при вычисление на стеке это: 10 * (30-(90+70)) = -1300
как бы две большие разницы

Т.ч. по всему топику, возникает два вопроса:

1) "Всё это безумие ? ДА"
2) "но так я вижу реализацию"
реализацию ЧЕГО Вы так видите?
Явно это НЕ "основанную на постфиксной записи программу калькулятора"
...
Рейтинг: 0 / 0
динамический #define
    #39987620
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
K & R делали книжки:
a) В Америки и для Америки, сейчас глобализация и их вольный подход к интерпритации строк в качестве дат дичь полнейшая.
b) Мало того, предположу, что кроме K & R над книжкой еще "поработал" переводчик и возможно технический редактор (после переводчика).
...
Рейтинг: 0 / 0
динамический #define
    #39987627
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
ваш цикл будет выполняться пока в потоке числа идут, а если + * / - , то этот символ никуда не сохранится потому что n-интовая переменная наверно.

Все правильно. Потому что я не решение вашей задачи писал, а показывал как работает scanf/sscanf на абстрактном примере.
...
Рейтинг: 0 / 0
динамический #define
    #39987637
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81я предполагал , что использовав sscanf можно слить непосредственно в переменные исходя из
шаблона

Теоретически можно. И я даже могу догадаться как, но попробуйте решить эту головоломку сами.

Подсказка: в строке может быть только повторяющая последовательность из следующих шаблонов:

%d %d %d
%d %d %c
%d %c
%c
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987643
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev

Можно ссылку на книгу и страницу с оригинальной постановкой задачи.

английской версией книги я не располагаю.
я вам копипастил текст из книги. но если вы не верите, то вот:


ссылка

стр. 153
и выше пример с обработкой даты


Leonid Kudryavtsev

В Вашем сообщении, два момента, которые "бредовые"
1. парсинг с помощью scanf
один токен преобразовать элементарно, банально заменив atoi на sscanf - зачем, не очень понятно, но можно.
парсить все выражение - какой-то безумство. Начиная с "оговариваем сколько максимально параметров может быть . Пусть это дефайн N", одно это все решение преврашает в какой-то .... (цензурных слов не находится) Сомневаюсь, что бы K&R были настолько садисты по отношению к пользователям.


я не отрицаю , что бредовые. но будь у #define возможности те о которых я запрашивал в самом начале думаю этот бред был бы реализуем. ну тут все точки над уже расставлены.

Leonid Kudryavtsev

2. даже если Вы отпарсите, как хотите, счастье это принести НЕ может. Т.к. ДВА разных массива с операндами и операциями это НЕ калькулятор, а какая-то помойка. Важен порядок следования операндов и операций, а он будет потерян.
к примеру:
10 30 + 90 70 - * = (10+30)*(90-70) = 800
а
10 30 90 70 + - *
при вычисление на стеке это: 10 * (30-(90+70)) = -1300
как бы две большие разницы


это не сильно относится к теме. я вам всем до какого-то момента про то что это постфиксный калькулятор вообще умалчивал, а потом пришлось. это всё для того чтобы вы не грузились лишним и не уходили не в то русло. Кроме вас кстати это никого и не взволновало. скажу одно, что для верной последовательности служил бы разбор подобранного шаблона . но даже если бы я и зашел бы в какой - нибудь косяк это был бы мой косяк, и я откатился бы назад, ничего в этом страшного нет. но повторюсь это другая тема.
...
Рейтинг: 0 / 0
динамический #define
    #39987645
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
K & R делали книжки:
a) В Америки и для Америки, сейчас глобализация и их вольный подход к интерпритации строк в качестве дат дичь полнейшая.


это ваше мнение.
...
Рейтинг: 0 / 0
динамический #define
    #39987648
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov



%d %d %d
%d %d %c
%d %c
%c


проблем с формированием различных комбинаций шаблонов я не вижу.
я вижу только то, что статично в скане надо подставить элементы массива в качестве параметров.
а это можно сделать только или прописав их - значит их количество прописывается жестко, ну а 2 ой вариант динамический макрос который потерпел фиаско.
...
Рейтинг: 0 / 0
динамический #define
    #39987650
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

Поищите в сети алгоритмы калькуляторов с поддержкой скобок и т.д. Очень простые и красивые. Они переводят выражение в естественном виде в польскую запись и там всё красиво вычисляется.
...
Рейтинг: 0 / 0
динамический #define
    #39987651
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
andron81,

Поищите в сети алгоритмы калькуляторов с поддержкой скобок и т.д. Очень простые и красивые. Они переводят выражение в естественном виде в польскую запись и там всё красиво вычисляется.


такая задача предо мной не стоит
...
Рейтинг: 0 / 0
динамический #define
    #39987661
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
я вижу только то, что статично в скане надо подставить элементы массива в качестве параметров.
а это можно сделать только или прописав их - значит их количество прописывается жестко, ну а 2 ой вариант динамический макрос который потерпел фиаско.


Из интернета:
Если длина массива известна на этапе компиляции, то можно упаковать его в struct и передать pass by value.

Сам так никогда не делал, ставить эксперименты и лень и не где.
...
Рейтинг: 0 / 0
динамический #define
    #39987665
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
andron81
я вижу только то, что статично в скане надо подставить элементы массива в качестве параметров.
а это можно сделать только или прописав их - значит их количество прописывается жестко, ну а 2 ой вариант динамический макрос который потерпел фиаско.


Из интернета:
Если длина массива известна на этапе компиляции, то можно упаковать его в struct и передать pass by value.

А если длина массива не известна на этапе компиляции, то можно ли его pass by value? Что там интернет говорит про это?
...
Рейтинг: 0 / 0
динамический #define
    #39987670
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
и так понятно, что можно
ключевое слово __asm никто не отменял )))
...
Рейтинг: 0 / 0
динамический #define
    #39987674
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Но вообще это даром не нужно, т.к. есть
http://www.cplusplus.com/reference/cstdio/vsscanf/
...
Рейтинг: 0 / 0
динамический #define
    #39987677
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81проблем с формированием различных комбинаций шаблонов я не вижу.

Не надо ничего формировать. Четыре шаблона я назвал, они жёсткие и фиксированные. Ничего
дополнительного не нужно.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987694
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

andron81проблем с формированием различных комбинаций шаблонов я не вижу.

Не надо ничего формировать. Четыре шаблона я назвал, они жёсткие и фиксированные. Ничего
дополнительного не нужно.


Ну можно было бы наверно примерять эти шаблоны последовательно, а "удачные" последовательности запоминать, а в случае неудачи откатывать поток в начало. Потом вспоминать все верные последовптелтности доходя до точки неудачи и примерить другой шаблон и тд...
...
Рейтинг: 0 / 0
динамический #define
    #39987698
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,
Вернее немного не так. Примеряем при помощи sscanf эти шаблоны последовательно. Если какой-то из шаблонов сработал, тогда заносим данные в стек, а строку режем и опять применяем алгоритм...
...
Рейтинг: 0 / 0
динамический #define
    #39987707
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
если уже есть написанная программа для польского калькулятора с постфиксными выражениями,
и по заданию парсить нужно с помощью scanf, то изменений там будет по минимуму.
парсинг как был так и остается character by character
вот как это должно происходить:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main() {
	char c;
	printf("Input string:\n");
	scanf("%c", &c);
	while (c != 'X'){
		// Character processing goes here, for example
                printf("%c", c);
                scanf("%c", &c);
	}
}
...
Рейтинг: 0 / 0
динамический #define
    #39987719
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab
если уже есть написанная программа для польского калькулятора с постфиксными выражениями,
и по заданию парсить нужно с помощью scanf, то изменений там будет по минимуму.
парсинг как был так и остается character by character
вот как это должно происходить:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
int main() {
	char c;
	printf("Input string:\n");
	scanf("%c", &c);
	while (c != 'X'){
		// Character processing goes here, for example
                printf("%c", c);
                scanf("%c", &c);
	}
}



это не круто совсем вырезать посимвольно при помощи scanf. для этого scanf и не нужен вовсе.
scanf умеет вырезать целыми словами исходя из шаблона. как минимум надо решать вырезая по одному "слову" (слово это набор символов заключенных между пробелов) как предлагалось выше. но так тоже не сильно прикольно :)
...
Рейтинг: 0 / 0
динамический #define
    #39987724
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попсовая задача этот калькулятор. Надо-бы его где-то отдельно опубликовать. Без этих scanf а в концептуальном виде.
...
Рейтинг: 0 / 0
динамический #define
    #39987726
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
Но вообще это даром не нужно, т.к. есть
http://www.cplusplus.com/reference/cstdio/vsscanf/



вот это я бы назвал решением с полноценным использованием scanf с учетом подсказок Сибирякова.
Пусть у калькулятора есть 2 команды push и execute ну и pop которая используется в execute (эти функции описаны и интереса не представляют), которые выполняются исходя из "природы" поступаемых слов(слово это либо число, либо + * - /), тогда решение я считаю должно выглядеть примерно вот так :

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <math.h>
#include <string.h>

#define N 500 //максимально возможная длина строки


const char pattern1[] = "%d %d %d";
const char pattern2[] = "%d %d %c";
const char pattern3[] = "%d %c";
const char pattern4[] = "%c";
bool allCalc = false;

void myTry(char* s) {

	int d1 = 0, d2 = 0, d3 = 0;
	int cutlengthString = 0;
	char c = '\0';
	if (strlen(s) == 0) { 
		allCalc = true; 
		return; 
	}
	if ((sscanf(s, pattern1, &d1, &d2, &d3)) == 3 && !allCalc) {
		printf("push numbers %d,%d,%d in stack \n", d1, d2, d3);
		cutlengthString = ((int)log10(d1) + 1) + ((int)log10(d2) + 1) + ((int)log10(d3) + 1)+3;//длина вырезаемой строки
		myTry(s+ cutlengthString);
	}
	if ((sscanf(s, pattern2, &d1, &d2, &c)) == 3 && !allCalc) {
		printf("push numbers %d,%d in stack and execute %c\n", d1, d2, c);
		cutlengthString = ((int)log10(d1) + 1) + ((int)log10(d2) + 1) + 1 + 3;//длина вырезаемой строки
		myTry(s + cutlengthString);
	}
	if ((sscanf(s, pattern3, &d1, &c)) == 2 && !allCalc) {
		printf("push number %d in stack and execute %c \n", d1, c);
		cutlengthString = ((int)log10(d1) + 1) +  3;//длина вырезаемой строки
		myTry(s + cutlengthString);
	}
	if ((sscanf(s, pattern4, &c)) == 1 && !allCalc) {
		printf("execute %c \n", c);
		cutlengthString = 2;//длина вырезаемой строки
		myTry(s + cutlengthString);
	}
	return;
}

int main()
{
	char String[N] = "40 123 456 890 123 - *";
	myTry(String);
}


вместо printf можно подставить команды push и execute
...
Рейтинг: 0 / 0
динамический #define
    #39987738
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81вот это я бы назвал решением

Я бы назвал это фигнёй, которая упадёт на первом отрицательном операнде. Надо таки
использовать %n.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
динамический #define
    #39987750
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Успокойтесь. Вещественные числа тоже провалятся если подходить строго. Я ограничился урезвнными возможностями. В книге калькулятор тоже не рубил отрицательные(работе с отрицательными надо было научить программу в упражнении), правда с вещественными он справлялся. Так или иначе это не так уже важно
...
Рейтинг: 0 / 0
динамический #define
    #39987758
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

andron81вот это я бы назвал решением

Я бы назвал это фигнёй, которая упадёт на первом отрицательном операнде. Надо таки
использовать %n.




Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
#define _CRT_SECURE_NO_WARNINGS 1

#include <stdio.h>
#include <math.h>
#include <string.h>

#define N 500 //максимально возможная длина строки


const char pattern1[] = "%d %d %d";
const char pattern2[] = "%d %d %c";
const char pattern3[] = "%d %c";
const char pattern4[] = "%c";
bool allCalc = false;

int lenNumber(const int d)
{
if (d == 0) return 1;
	return log10(abs(d)) + (d < 0);
}

void myTry(char* s) {
	char copy[N] = "\0";
	int d1 = 0, d2 = 0, d3 = 0;
	int cutlengthString = 0;
	char c = '\0';
	if (strlen(s) == 0) { 
		allCalc = true; 
		return; 
	}
	if ((sscanf(s, pattern1, &d1, &d2, &d3)) == 3 && !allCalc) {
		printf("push numbers %d,%d,%d in stack \n", d1, d2, d3);
		cutlengthString = (lenNumber(d1) + 1) + (lenNumber(d2) + 1) + (lenNumber(d3) + 1)+3;//длина вырезаемой строки
		myTry(s+ cutlengthString);
	}
	if ((sscanf(s, pattern2, &d1, &d2, &c)) == 3 && !allCalc) {
		printf("push numbers %d,%d in stack and execute %c\n", d1, d2, c);
		cutlengthString = (lenNumber(d1) + 1) + (lenNumber(d2) + 1) + 1 + 3;//длина вырезаемой строки
		strncpy(copy, s, cutlengthString);
		myTry(s + cutlengthString);
	}
	if ((sscanf(s, pattern3, &d1, &c)) == 2 && !allCalc) {
		printf("push number %d in stack and execute %c \n", d1, c);
		cutlengthString = (lenNumber(d1) + 1) +  3;//длина вырезаемой строки
		myTry(s + cutlengthString);
	}
	if ((sscanf(s, pattern4, &c)) == 1 && !allCalc) {
		printf("execute %c \n", c);
		cutlengthString = 2;//длина вырезаемой строки
		myTry(s + cutlengthString);
	}
	return;
}
int main()
{

	char String[N] = "-40 -123 456 890 -123 - *";
	myTry(String);

}
...
Рейтинг: 0 / 0
динамический #define
    #39987761
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
удалил
...
Рейтинг: 0 / 0
динамический #define
    #39987774
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
1)
Отрицательные числа в польской записи выглядят так:
0 10 -
2)
в польской постфикс записи используется один единственный шаблон: число число оператор
...
Рейтинг: 0 / 0
динамический #define
    #39987777
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab
1)
Отрицательные числа в польской записи выглядят так:
0 10 -
2)
в польской постфикс записи используется один единственный шаблон: число число оператор




1) неважно, уже научили работать с отрицательными
2) а как же классический пример ? ? 2 6 + 3 8 - *
...
Рейтинг: 0 / 0
динамический #define
    #39987778
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

это не круто совсем вырезать посимвольно при помощи scanf. для этого scanf и не нужен вовсе.
scanf умеет вырезать целыми словами исходя из шаблона. как минимум надо решать вырезая по одному "слову" (слово это набор символов заключенных между пробелов) как предлагалось выше. но так тоже не сильно прикольно :)

я согласна, но это самое простое решение с минимальной модификацией уже написанного кода.
из предложенных вариантов, я бы рассмотрела токены и комбинацию scanf("%d"), scanf("%c").
с шаблонами можно сделать прикольное решение через рекурсию, но придется заморачиваться со строками, и, приняв во внимание весь оверхед, это уже не выглядит так уж круто.
...
Рейтинг: 0 / 0
динамический #define
    #39987779
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,
я не углублялась в изучение польской записи, поэтому про классический пример ничего сказать не могу.
просто вместо того, чтобы делать костыли, лучше объявить, что наш калькулятор с отрицательными числами работает так
-10 = 0 10 -
:)
...
Рейтинг: 0 / 0
динамический #define
    #39987780
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,

Короче можно закрывать. Решено хоть от главного вопроса отошли - такие костыли не потребовались.
...
Рейтинг: 0 / 0
динамический #define
    #39987781
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

в любом случае, в постфикс польской записи, шаблон будет один, и это (число число оператор)
(число может быть отрицательным и положительным)
...
Рейтинг: 0 / 0
динамический #define
    #39987783
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
поясню:
mini.weblab

-10 = 0 10 -

имеется ввиду, что при начальном вводе данных можно записывать математическое выражение из целых неотрицательных чисел,
дальше, уже в числовом стеке, 0 10 - будет записано как -10
мотивация: если используется польский постфикс (machine oriented approach), то почему бы не записать отрицательное число в удобной нам форме?
...
Рейтинг: 0 / 0
динамический #define
    #39987786
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab
andron81,

в любом случае, в постфикс польской записи, шаблон будет один, и это (число число оператор)
(число может быть отрицательным и положительным)


Я к тому, что классический пример польской записи(а надо немного углубиться :)) с вашим шаблоном не дружит. Здесь 2 раза выйдет применить ваш шаблон, а потм уткнемся в *

1 2 + 3 4 - *

С отрицательными числами вас думаю все пончли. Но не велика проблема. Решается легко. Либо дейсвительно вашим способом, либо немного усовершенствовав код.
Разве моя реализация с шаблонами уж очень сложна?и рекурсия как вы любите:)
...
Рейтинг: 0 / 0
динамический #define
    #39987789
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,
а давайте я все-таки попробую:
1 2 + 3 4 - * = 3 3 4 - * = 3 -1 * = -3

вот работа постфикса ( в данном случае не обсуждаем, как это запрограммировать на С :) ):
поиск шаблона -> нашли -> посчитали -> записали результат: повторяем пока не останется одно единственное число
...
Рейтинг: 0 / 0
динамический #define
    #39987791
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab,
Я понял. У вас подход другой.
Но такие страсти не требуются. Калькулятор реализованный в k&r работает иначе чем вы думаете. В результате все проще.

P. S. Вы таким образом описали реализацию самого калькулятора работающего по другому алгоритму отличного от того что у k&r :))
...
Рейтинг: 0 / 0
динамический #define
    #39987873
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вот что в итоге получилось, правда, со стэком я немного схалтурила :-)
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int sscanf_result;
    float num, v1 = 0, v2 = 0;
    char op;
    float stack[100] = {0};

    int stack_counter = 0;
    char expression[100] = {'\0'};

    printf("Enter an expression: ");
    fgets(expression, 100, stdin);

    char *token = strtok(expression, " ");
    while(token) {
        printf("%s\n", token);
        sscanf_result = sscanf(token, "%f", &num);
        if (sscanf_result == 1) {
        	stack[stack_counter] = num;
        	stack_counter++;
        } else {
        	sscanf_result = sscanf(token, "%c", &op);
        	v2 = stack[stack_counter-1];
        	v1 = stack[stack_counter-2];
        	stack_counter = stack_counter - 2;
        	switch(op) {
				case '+':
					stack[stack_counter] = v1 + v2;
					break;
				case '-':
					stack[stack_counter] = v1 - v2;
					break;
				case '*':
					stack[stack_counter] = v1 * v2;
					break;
				case '/':
					stack[stack_counter] = v1 / v2;
					break;
				default:
					printf("Invalid operator: %c.\n", op);
					exit(1);
        	}
        	stack_counter++;
        }
        token = strtok(NULL, " ");
    }
    if (stack_counter == 1)
        printf("\nResult: %.4f\n", stack[stack_counter - 1]);
    else {
    	printf("Expression Error: numbers and operators are not balanced.\n");
    	exit(2);
    }
    return 0;
}


...
Рейтинг: 0 / 0
динамический #define
    #39987894
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
mini.weblab,
Я понял. У вас подход другой.
Но такие страсти не требуются. Калькулятор реализованный в k&r работает иначе чем вы думаете. В результате все проще.

P. S. Вы таким образом описали реализацию самого калькулятора работающего по другому алгоритму отличного от того что у k&r :))

Ага щас.
Вот алгоритм приведенный в этой книге, ссылку на которую вы выше давали.
Это ровно то что реализовано в коде у mini.weblab .
Никаких множества паттернов для чтений нескольких чисел за один проход в нем нет, это ваша отсебятина ))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
while(следующий элемент не конец-файла)
  if(число)
    послать его в стек
  elseif(оператор)
    взять из стека операнды
    выполнить операцию
    результат послать в стек
  elseif(новая-строка)
    взять с вершины стека число и напечатать
  else
    ошибка
...
Рейтинг: 0 / 0
динамический #define
    #39987896
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
andron81
mini.weblab,
Я понял. У вас подход другой.
Но такие страсти не требуются. Калькулятор реализованный в k&r работает иначе чем вы думаете. В результате все проще.

P. S. Вы таким образом описали реализацию самого калькулятора работающего по другому алгоритму отличного от того что у k&r :))

Ага щас.
Вот алгоритм приведенный в этой книге, ссылку на которую вы выше давали.
Это ровно то что реализовано в коде у mini.weblab .
Никаких множества паттернов для чтений нескольких чисел за один проход в нем нет, это ваша отсебятина ))
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
while(следующий элемент не конец-файла)
  if(число)
    послать его в стек
  elseif(оператор)
    взять из стека операнды
    выполнить операцию
    результат послать в стек
  elseif(новая-строка)
    взять с вершины стека число и напечатать
  else
    ошибка



Да, только она сначала говорила про рекурсивную реализацию и про паттерн %d %d %c. А потом реалищовала примерно так как в книге. Читайте все, а не последние 2 сообщения раз хотите поумничать
...
Рейтинг: 0 / 0
динамический #define
    #39987900
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky,
И у нее 2 паттерна между прочим, если уж на то пошло 😂😂
...
Рейтинг: 0 / 0
динамический #define
    #39987902
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81
Читайте все, а не последние 2 сообщения раз хотите поумничать

ОК. Читаю все:

andron81
2. нужно сформировать все различные паттерны исходя из N , скажем для примера это шаблон :
"%d %d %c %d %d %c %c"
и другие ...


mini.weblab
1)
2)
в польской постфикс записи используется один единственный шаблон: число число оператор


Таким образом вы не только не помните что сами писали так еще и другим так какие-то претензии предъявляете
...
Рейтинг: 0 / 0
динамический #define
    #39987905
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вам что платят за троллинг не пойму?

andron81
2. нужно сформировать все различные паттерны исходя из N , скажем для примера это шаблон :
"%d %d %c %d %d %c %c"
и другие ...


вот эта первоначальная моя идея давно уже потерпела фиаско .
Потом Сибиряков подкинул другую с различными паттернами (раз уж я хотел завязать различные паттерны и более менее полноценно использовать возможности scanf/sscanf, а не просто sscanf("%c", &c ) и sscanf("%d", &d ) - такая реализация ежу ясна ) , что успешно и было мной реализовано

mini.weblab
1)
2)
в польской постфикс записи используется один единственный шаблон: число число оператор

вот это подрузамевает шаблон "%d %d %c" . и где-то рядом она упоминала рекурсию.
а потом она реализует примерно так как в книге. где в её реализации этот шаблон и рекурсия?
к ней вопросы и адресуйте.
...
Рейтинг: 0 / 0
динамический #define
    #39987906
kolobok0
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81,

скажу совсем в другом русле...

дефайн история то не для си плас плас... в умных рекомендациях утверждают что получше будет типизация того, что мы задаём. ну типо статик каста. Оно как бы задаёт типизацию, и подлежит контролю со стороны компилятора.


(круглый)
...
Рейтинг: 0 / 0
динамический #define
    #39987909
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky

Никаких множества паттернов для чтений нескольких чисел за один проход в нем нет, это ваша отсебятина ))


и где я говорил, что в её коде множество паттернов или один проход ? я её код ваще не комментировал.
...
Рейтинг: 0 / 0
динамический #define
    #39987915
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky

Никаких множества паттернов для чтений нескольких чисел за один проход в нем нет, это ваша отсебятина ))


И я не говорил, что в коде у K&R есть какие-то паттерны в калькуляторе. там даже scanf не используется. имелось ввиду, что принцип работы тот же , я его и использую (принцип : занес в стек, посчитал , нарисовал результат) - всё так кроме того как данные из строки вырезаются(это и есть суть всего этого топика). И сложилось впечатление, что человек стал описывать мне алгоритм работы калькулятора(причем алгоритм рекурсивный заявил, а строку хотел резать шаблоном "%d %d %c"), а потом реализовал зачем-то полностью причем реализация совпала с книжной (и нет ни рекурсии , ни заявленного шаблона). а теперь вы меня тролите вопросами за чужой код зачем-то.
...
Рейтинг: 0 / 0
динамический #define
    #39987981
mini.weblab
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andron81

И я не говорил, что в коде у K&R есть какие-то паттерны в калькуляторе. там даже scanf не используется. имелось ввиду, что принцип работы тот же , я его и использую (принцип : занес в стек, посчитал , нарисовал результат) - всё так кроме того как данные из строки вырезаются(это и есть суть всего этого топика). И сложилось впечатление, что человек стал описывать мне алгоритм работы калькулятора(причем алгоритм рекурсивный заявил, а строку хотел резать шаблоном "%d %d %c"), а потом реализовал зачем-то полностью причем реализация совпала с книжной (и нет ни рекурсии , ни заявленного шаблона). а теперь вы меня тролите вопросами за чужой код зачем-то.

Просто вы не разделяете польскую постфикс запись и алгоритм для калькулятора, работающего по польской постфикс записи.
Перед тем как писать алгоритм работы калькулятора, основанного на польской постфикс записи, нужно разобраться, как эта самая запись работает. Как я уже говорила, в основе польской постфикс записи лежит один единственный шаблон (число, число, оператор). После того как мы разобрались, как работает постфикс можно начать писать код. И естественно, первое, что приходит в голову, это решить задачу в лоб, т.е. использовать шаблоны и работать со строкой, что жутко неудобно, дальше мы думаем, что гораздо удобнее было бы работать с числами (а не заморачиваться со строками), и думаем как же это сделать? И тогда мы приходим к решению КР, т.е. мы записываем числа в стек и дальше для подсчетов используем наш шаблон (число число оператор).

По поводу вырезать данные, я вам сразу сказала, что мне больше всего нравится вариант с токенами и scanf("%d"), scanf("%c").
...
Рейтинг: 0 / 0
динамический #define
    #39987982
Leonid Kudryavtsev
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab

По поводу вырезать данные, я вам сразу сказала, что мне больше всего нравится вариант с токенами и scanf("%d"), scanf("%c").

IMHO Он не "больше нравится", это единственный более менее вменяемый алгоритм.
...
Рейтинг: 0 / 0
динамический #define
    #39987987
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mini.weblab

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

у меня с этим проблем нету. потому что алгоритм разжован в книге. b более того калькулятор реализован там же хоть и по средством getchar()


mini.weblab

Как я уже говорила, в основе польской постфикс записи лежит один единственный шаблон (число, число, оператор).

в случае двухместных операций - да ! у нас все двухместные.


mini.weblab

И естественно, первое, что приходит в голову, это решить задачу в лоб, т.е. использовать шаблоны и работать со строкой, что жутко неудобно, дальше мы думаем, что гораздо удобнее было бы работать с числами (а не заморачиваться со строками), и думаем как же это сделать? И тогда мы приходим к решению КР, т.е. мы записываем числа в стек и дальше для подсчетов используем наш шаблон (число число оператор).
По поводу вырезать данные, я вам сразу сказала, что мне больше всего нравится вариант с токенами и scanf("%d"), scanf("%c").

да, возможно , но вы написали вот это, а это похоже на рекурсивный алгоритм с использованием шаблона %d %d %c :
mini.weblab

а давайте я все-таки попробую:
1 2 + 3 4 - * = 3 3 4 - * = 3 -1 * = -3

а потом вы все же реализовали идей scanf("%d") и scanf("%c").
поэтому при общении с московским мне пришлось раскритиковать ваши комменты - не код (мне показалось, что вы проговорили один алгоритм , а реализовали при помощи scanf("%d") и scanf("%c"))
но я был без претензий вообще пока меня не подтролили .
я уже давно все выяснил и уже бы давно прикрыл бы тему, но нет же...
...
Рейтинг: 0 / 0
динамический #define
    #39987988
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Leonid Kudryavtsev
mini.weblab

По поводу вырезать данные, я вам сразу сказала, что мне больше всего нравится вариант с токенами и scanf("%d"), scanf("%c").

IMHO Он не "больше нравится", это единственный более менее вменяемый алгоритм.


у меня первично основная тема была это использование scanf и sscanf , а не постфиксный калькулятор. если бы второй вариант, то да вы правы. а с несколькими шаблонами лучше иллюстрирует тему scanf и sscanf. поэтому для меня моя реализация прикольней :)
Вот в чем мои мотивы .
...
Рейтинг: 0 / 0
динамический #define
    #39988868
andron81
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
можно закрывать тему
...
Рейтинг: 0 / 0
88 сообщений из 88, показаны все 4 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / динамический #define
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]