2015-07-02 16 views
5

In Windows, ho una variabile di ambiente che contiene un percorso in stile Windows. Mi piacerebbe costruire quel percorso nel mio programma e stamparlo. Quindi se il mio percorso è c: \ top, lo passo nel compilatore usando -DTOP = $ (TOP). Nota: non riesco a convertirlo in c: \\ top prima di passarlo nel compilatore.Come creare una stringa letterale da -D variabile definita dal compilatore di un percorso di Windows

In questo momento, ho l'equivalente di:

#define TOP=c:\top 

voglio l'equivalente di:

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

Non posso usare l'operatore stringafication:

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

Questo ha come risultato solo la stringa "c: \ top" che il compilatore visualizza come una sequenza di escape (cioè \ t).

Penso che una possibile soluzione sarebbe quella di costruire una stringa letterale, ma anche altre soluzioni andranno bene. C'è un modo per utilizzare le macro per costruire una stringa letterale che sarebbe resa:.

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

Finora, tutti i miei tentativi sono falliti per ragioni che coinvolgono le variazioni del "o() o il \

Grazie

+1

"Nota Non riesco a convertirlo in c: \\ top prima di passarlo nel compilatore" - Perché? –

+0

Perché non '-DTOP = R" pippo ($ (TOP)) pippo "' invece? Modifica: È possibile che le virgolette debbano essere sfuggite poiché questa è un'opzione della riga di comando, come ad esempio: '-DTOP =" R "" foo ($ (TOP)) foo "" "' – Cameron

+0

Sono in un ambiente di compilazione personalizzato che non può alterare Non posso usare virgolette aggiuntive quando specifico il -D. L'ambiente di compilazione usa anche le virgolette per analizzare ulteriori agevolazioni al compilatore. – shol74

risposta

1

È possibile convertire il percorso definito in una stringa tramite il prefisso con l'operatore di stringing # Tuttavia, questo funziona solo nelle macro. In realtà è necessaria una doppia macro per farlo funzionare correttamente, altrimenti viene stampato solo TOP Anche posizionare il nome del percorso tra virgolette è importante - oh l'esempio ha il percorso immagazzinato sotto l'ENV PathDirName

Definizione del percorso per il compilatore -

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

Utilizzando all'interno del codice

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

char path[] = STRINGIZE(TOP); 

Questo ha funzionato per me. L'hai quasi fatto funzionare, quindi spero che questo aiuti.

[EDIT] Ora riesco a vedere il problema - in C: \ top - sta prendendo il 'backslash t' come un codice di controllo - '\ t'. Questo appoarch sta diventando un incubo da risolvere, poiché è necessario creare il nome del file con due barre o utilizzare le barre. Sento di avere problemi confusi qui rispondendo prima di rivedere completamente ciò che è successo. Ho provato diversi metodi - ma non sono in grado di modificare il passato in define - posso solo suggerire di usare una libreria regex o di eseguire manualmente la scansione della stringa - sostituendo i caratteri di controllo con la lettera '\' corretta.

Ho buttato giù un esempio che mostra questo solo con '\ t' nel tuo esempio: non è un bel codice, è scritto per spiegare cosa si sta facendo, si spera che dia un esempio visivo e lo faccia (in un non è così carino) risolvere il problema UNO che si ha con 'C: \ top' .. come ho detto - se si utilizza questo metodo di tosse, sarà necessario gestire tutti i codici di controllo.:-)

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'; 

Ancora una volta - mi dispiace per la confusione - ho lasciato la mia risposta qui come riferimento per voi - e si spera che qualcuno si presenti con un modo di gestire la stringa define-(con le charactors di controllo).

grazie, Neil

+0

Grazie, ma ancora una volta, non posso cambiare ciò che è passato. Mi chiedevo se potevo usare gli operatori di stringhe concat ## in qualche modo per costruire la stringa letterale. – shol74

+0

Hmmm in quanto è una macro: potresti provare ad aggiungere preventivi prima e dopo TOP. Non posso provarlo mentre sono lontano dalla mia macchina di sviluppo - quindi dovrebbe funzionare. Un modo per usare il formato (..) - Se mi avvicino alla mia macchina, provo a provarlo. – Neil

+0

Ho modificato la mia risposta shol74, non una buona notizia in quanto non sono stato in grado di capire come NON ottenere il carattere '\ t' quando si definisce il TOP. Come ho detto, spero che qualcuno sia in grado di risolverlo. Seriamente proverei a cambiare il define che è passato. – Neil

0

Il alquanto bizzarra sintassi di cerchi esegue on-the-fly sottostringa sostituzione in espansione variabile, così come qualche segno citazione fuga per rendere la definizione di una stringa. Ho trovato le informazioni sulla sostituzione della sottostringa here.

set DIR=C:\WINDOWS ottiene l'env var set, e poi abbiamo un test prog:

#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; 
} 

Come non si può citare nella shell, è possibile stringize qui, ma è comunque necessario fare la sostituzione stringa variabile.

Passare l'env var attraverso cmd.exe:

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

Vedi il link qui sopra per ulteriori informazioni, o google sottostringa sostituzione. Non riesco a trovare un collegamento a qualsiasi informazione Microsoft sulla funzione (che sorpresa!)

+0

Ancora una volta, non posso modificare la stringa prima di passarla a causa di un ambiente di compilazione personalizzato che sta già utilizzando i caratteri di citazione. Quindi, aggiungendo qualsiasi carattere di citazione, termina semplicemente la stringa lì all'inizio. Devo lavorare con #define in alto c: \ top nel file .cpp. – shol74

+0

@ shol74 Ho modificato per rimuovere le virgolette dalla riga di comando di compilazione. Sembra uno strano requisito. Come notato da Neil, puoi semplicemente stringerlo usando l'espansione macro. –

+0

@ shol74 Penso che tu stia chiedendo l'impossibile perché non esiste una codifica sensibile per il preprocessore con cui lavorare, e il preprocessore è l'unico strumento che hai. –