Как создать строковый литерал из определенной переменной компилятора -D пути Windows

Под Windows у меня есть переменная среды, которая содержит путь в стиле Windows. Я хотел бы встроить этот путь в мою программу и распечатать его. Поэтому, если мой путь — c: \ top, я передаю его в компилятор, используя -DTOP = $ (TOP). Примечание. Я не могу преобразовать его в c: \\ top, прежде чем передать его в компилятор.

Прямо сейчас у меня есть эквивалент:

#define TOP=c:\top

Я хочу эквивалент:

char path[]="c:\\top";

Я не могу просто использовать оператор stringafication:

#define WRAP1(X) #X
#define WRAP(X) WRAP1(X)
char path[] = WRAP(TOP);

В результате получается строка «c: \ top», которую компилятор рассматривает как escape-последовательность (т.е. \ t).

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

char path[] = R"foo(c:\top)foo";

Пока что все мои попытки потерпели неудачу по причинам, связанным с вариациями «или () или \.

Благодарю.

5

Решение

Вы можете преобразовать определенный вами путь в строку, добавив к нему префикс #. Однако это работает только в макросах. На самом деле вам нужен двойной макрос для правильной работы, в противном случае он просто печатает TOP. Также размещение пути в кавычках это важно — о примере есть путь, сохраненный в env PathDirName

Определение пути для компилятора —

/DTOP="\"$(PathDirName)\\""

Использование в коде

#define STRINGIZE2(x) #x
#define STRINGIZE(x) STRINGIZE2(x)

char path[] = STRINGIZE(TOP);

Это сработало для меня. У вас почти получилось, так что надеюсь, это поможет.

[РЕДАКТИРОВАТЬ] Я вижу проблему сейчас — в C: \ top — она ​​принимает ‘обратный слеш t’ в качестве управляющего кода — ‘\ t’. Этот appoarch становится чем-то вроде ночного кошмара, так как вам действительно нужно создать имя файла с двумя косыми чертами или использовать прямую косую черту. Я чувствую, что перепутал вопросы здесь, отвечая, прежде чем полностью рассмотреть то, что произошло.
Я перепробовал несколько методов — но не смог изменить переданный в define — я могу только предложить использовать библиотеку регулярных выражений или ручное сканирование строки — заменив контрольные символы правильной буквой ‘\’.

Я набрал пример, показывающий это, просто с помощью ‘\ t’ в вашем примере — это не очень хороший код, он написан для объяснения того, что делается, надеюсь, он дает наглядный пример и делает это (не очень хороший способ Разберитесь с ОДНОЙ проблемой, которую вы испытываете, с помощью C: \ top … как я уже сказал — если вы используете этот метод кашля, вам нужно будет обработать все контрольные коды. 🙂

char stringName[256];
char* pRefStr = STRING(TOP);
char* pDestStr = stringName;
int nStrLen = strlen( pRefStr );

for( int nIndex = 0; nIndex < nStrLen; nIndex++ )
{
if ( *pRefStr == '\t' )
{
*pDestStr++ = '\\';
*pDestStr++ = 't';
pRefStr++;
}
else
{
*pDestStr++ = *pRefStr++;
}
}
*pDestStr = '\0';

Еще раз — извините за путаницу — я оставил здесь свой ответ как ссылку для вас — и, надеюсь, кто-то придумает способ обработки определяющей строки (с помощью управляющих символов).

спасибо Нил

1

Другие решения

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

set DIR=C:\WINDOWS получает набор env var, а затем у нас есть тестовая программа:

#include <stdio.h>

#define STR(x)    #x
#define STRING(x) STR(x)

int main( int argc, char* argv[] )
{
printf( "DIR: %s\n", STRING(DIR) );
return 0;
}

Так как вы не можете заключить в кавычки в оболочке, вы можете здесь зачеркнуть, но вы все равно должны сделать замену подстроки переменной.

Передайте переменную env через cmd.exe:

gcc -Wall -DDIR=%DIR:\=\\% main.c

См. Ссылку выше для получения дополнительной информации или замены подстроки Google. Я не могу найти ссылку на какую-либо информацию Microsoft о функции (какой сюрприз!)

0

По вопросам рекламы [email protected]