IMHO.WS

IMHO.WS (https://www.imho.ws/index.php)
-   Программирование (https://www.imho.ws/forumdisplay.php?f=40)
-   -   Помогите с препроцессором в C\c++ (https://www.imho.ws/showthread.php?t=59615)

Crazy_kettle 24.05.2004 10:25

Помогите с препроцессором в C\c++
 
Захотелось мне слепить новый макрос-строку из нескольких макросов, но ни как не получается, может посоверуйте как сделать.

Например:
Есть
#define A1 Bla-h bla-h %
#define A2 30
#define A3 d

Хочу получить с помощью макроподстановки : "Bla-h bla-h %30d"

Вот как это следать? Во-первых как включить символ " в макрос? Пробовал.
#define "
#define \"
#define ""
Ни один вроде не подходит.

Во-вторых, как объединить два макроса, чтобы между ними не возникали лишние символы и происходила макроподстановка (##- объединяет, но макроподстановка, вроде не происходит).

Кстати. Может кто знает, где можно найти исчерпывающуу документацию по препроцессору.

edbond 24.05.2004 18:21

макросы - это зло. отлаживать потом труднее. лучше const char* делать.
по препроцессору начать с - man cpp. :)

Crazy_kettle 25.05.2004 11:11

Цитата:

по препроцессору начать с - man cpp.
У меня не Линус, а Винда стоит.

Цитата:

макросы - это зло. отлаживать потом труднее. лучше const char* делать.
Чуть ли не цитата с книги Страуструпа :))). Вообще-то это, скорее всего, и правда (сам уже сталкивался с трудностями при использовании макросов-функций). НО мне, хотябы исходя из образовательных целей, хочется изучить предпроцессор. Тем более, что не используя макроподстановки помоему нельзя эффективно и элегантно написать гибкую программу, у которой поля для ввода варьируются (хочется создать табличку). Для решения этой проблемы я знаю способы:
1) Объявить const char*, но это не гибко, т.к. при замене значений полей нужно менять цифры покрайней мере в друх местах (с строке и для констант или вообще повсюду в программе)
2) С помощью sprintf ренерировать строку в начале программы, но это не эффективно.
3) Переписать/подправить стандартную функцию scanf. Но это долго/и, кажется, не оправдано сложно
4) Написать свой препроцессор и перед компиляцией пропускать исходники через него. Не гибко, будет сложно для понимания исходников другими людьми.

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

Dimm 25.05.2004 12:32

Crazy_kettle

то что ты хочешь, можно сделать так:
Код:

#include "stdio.h"

#define FILL_BUF(buf, s, num, sys) sprintf(buf,"%s%d%c", s, num, sys)

int _tmain(int argc, _TCHAR* argv[])
{

        char buf[20];
        FILL_BUF(buf, "Bla-h bla-h %", 30, 'd');
            // in this line we have buf filled with desired string
        return 0;
}

Хотя я не стал бы использовать макросы для таких целей.

Crazy_kettle 25.05.2004 13:29

to programmer
Вы меня не поняли.

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

Что я хочу, это автоматизировать процес создания строки, чтобы достаточно было изменить значение одной константы и перекомпилировать программу, для изменения ширины полей таблицы и ширины, занимаемой целым. Думаю, что это можно слелать с помощью макросов.
Если бы я знал, как включить символ " в макрос и как объединить два макроса, чтобы между ними не возникали лишние символы и происходила макроподстановка, реализация не составила бы труда:

Объявляем BEGSTRING как "Blah-blah %
#define INTSIZE 30
Объявляем ENDSTRING как d"

А дальше объединяем BEGSTRING,INTSIZE и ENDSTRING.

Надеюсь понятно изложил то, что хочу получить и сейчас жду советов.

Кстати, может кто знает ответ на ранее поставленный вопрос:
Может кто знает, где найти исчерпывающую документацию по препроцессору или хотябы где её можно поискать
Был совет почитать man cpp. Ну что ж пойду к другу, почитаю. Хотя я не уверен, что там найду то, что мне нужно. (Я смотрел книги Керниган и Ричи, и Страуструпа, но там только базовая информация и ничего не помогло мне решить мою проблему).

Dimm 25.05.2004 20:15

Crazy_kettle

Мне кажется, что сделать точно так как ты хочешь - нельзя.
Хотя попробуй поищи инфу здесь

Crazy_kettle 29.05.2004 01:48

to Programmer
Большое спасибо. Не думал в MSDN глянуть, а зря ... (как выяснилось)
После беглого обзора написанной информации, я было уже обрадовался. Но, оказалось, что не всё так просто. Думал, есть даже два варианта, но прогадал. (Может, кому-нибудь будет интересно. Поэтому я приведу их)
Цитата:

#define BEGSTR "Blah-Blah-Blah %"
#define MYINTSIZE "30"
#define ENDSTR "d\n"

#define FORMATSTR BEGSTR MYINTSIZE ENDSTR

printf(FORMATSTR,i);
Здесь переменная i типа int;

или

Цитата:

#define FORMATOUT(Format,Par) printf("Blah-Blah-Blah %" #Format "d\n",Par)
FORMATOUT(10,i);
Но как видно, что варианты не то решение, которое я хотел, т.к. в первом случае MYINTSIZE это макрос-СТРОКА, и я не знаю как использовать этот макрос, как целочисленную константу (т.е. i=MYINTSIZE не пройдёт, пойдёт i=atoi(MYINTSIZE), но это тоже нехорошо, т.к тратятся такты проца на этапе выполнения). Но всё равно этот вариант довольно таки хорош, т.к. можно объявить #define MYINTSIZE 30 и #define S_MYINTSIZE 30. И незабыть их менять одновременно (особенно при большом количестве таких констант) будет удобнее, чем в ранее предложенном варианте 2).

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

Вот и сталкнулся я с несовместимостью строковой константы и числовой константы, хотя поидее для препроцессора (не для компилятора) они отличаются лишь ковычками """, ведь после препроцессора, за обработку вступает компилятор, а значит, все числовые константы всё равно должны быть оставлены в символьном виде (т.е. препроцессор либо копирует строки, либо переводит символьные константы в строки). Странно, что нет возможности (хотя может, это я просто не нашёл) перевести числовые константы в строковые константы и наоборот. Так что возникает вопрос "Или это по большому счёту никому не нужно, или что-то я не так понимаю?".

Почитал я man cpp. Но там вообще нет никакой документации о синтаксисе, правилах использования, "фишках", только мануал но исплользованию программы cpp

alexey_ma 29.05.2004 09:55

Цитата:

Crazy_kettle:
Во-первых как включить символ " в макрос? Пробовал.
#define "
#define \"
#define ""
Кавычку можно сделать так:
#define '"'

Crazy_kettle 30.05.2004 22:30

to alexey_ma
Цитата:

Кавычку можно сделать так:
#define '"'
Это не будет просто ковычка - это будет ковычка заключённая в одинарные ковычки ' " ', и поэтому составить с её помощью строку, вроде, невозможно.


Часовой пояс GMT +4, время: 20:24.

Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.