2016-07-05 5 views
3

Ich schreibe ein größeres Programm, das Argumente von der Befehlszeile nach der ausführbaren Datei übernimmt. Einige der Argumente werden voraussichtlich nach dem Gleichheitszeichen einer Option übergeben. Zum Beispiel ist die Ausgabe in das Protokoll ein Komma getrennt Vektor standardmäßig, aber wenn der Benutzer den Separator zu einem Punkt oder etwas anderes statt einem Komma ändern möge, könnten sie das Argument als geben:Behandeln Sie Escape-Sequenzen in Zeichenfolgen von argv in C++ ordnungsgemäß

./main --separator="." 

Dies funktioniert gut, aber wenn ein Benutzer sein das Trennzeichen ein Sonderzeichen (zB: tab), könnten sie erwarten, dass die Escape-Sequenz in einer der folgenden Weisen passieren:

./main --separator="\t" 
./main --separator='\t' 
./main --separator=\t 

Es verhält sich nicht die So wie ich es will (um es als Tab zu interpretieren) und stattdessen den String wie geschrieben ausgibt (ohne Anführungszeichen und ohne Anführungszeichen, druckt er nur 't'). Ich habe versucht, doppelte Schrägstriche zu verwenden, aber ich denke, dass ich mich dem Problem vielleicht nur unkorrekt nähern würde und ich bin nicht sicher, wie ich die Frage überhaupt richtig stellen soll (ich habe versucht, zu suchen).

#include <string> 
#include <iostream> 
#include <cstdio> 

// Pull the string value after the equals sign 
std::string get_option(std::string input); 
// Verify that the input is a valid option 
bool is_valid_option(std::string input); 

int main (int argc, char** argv) 
{ 

    if (argc != 2) 
    { 
     std::cerr << "Takes exactly two arguments. You gave " << argc << "." << std::endl; 

     exit(-1); 
    } 

    // Convert from char* to string 

    std::string arg (argv[1]); 

    if (!is_valid_option(arg)) 
    { 
     std::cerr << "Argument " << arg << " is not a valid option of the form --<argument>=<option>." << std::endl; 

     exit(-2); 
    } 

    std::cout << "You entered: " << arg << std::endl; 
    std::cout << "The option you wanted to use is: " << get_option(arg) << "." << std::endl; 

    return 0; 
} 

std::string get_option(std::string input) 
{ 
    int index = input.find('='); 
    std::string opt = input.substr(index + 1); // We want everything after the '=' 
    return opt; 
} 

bool is_valid_option(std::string input) 
{ 
    int equals_index = input.find('='); 

    return (equals_index != std::string::npos && equals_index < input.length() - 1); 
} 

ich so kompilieren:

Ich habe das Problem in einem Dummy Beispiel hier neu erstellt

g++ -std=c++11 dummy.cpp -o dummy 

Mit den folgenden Befehlen es die folgenden Ausgaben erzeugt.

Mit doppelten Anführungszeichen:

/dummy --option="\t" 
You entered: --option=\t 
The option you wanted to use is: \t. 

Mit einfachen Anführungszeichen:

./dummy --option='\t' 
You entered: --option=\t 
The option you wanted to use is: \t. 

Ohne Anführungszeichen:

./dummy --option=\t 
You entered: --option=t 
The option you wanted to use is: t. 

Meine Frage ist: Gibt es eine Möglichkeit, dass es zu spezifizieren sollte den Teilstring \ t eher als Tabulatorzeichen (oder andere Escape-Sequenzen) interpretieren das Zeichenfolgenliteral "\ t"? Ich könnte es manuell analysieren, aber ich versuche zu vermeiden, das Rad neu zu erfinden, wenn ich nur etwas kleines vermisse.

Vielen Dank für Ihre Zeit und Antworten. Das ist so einfach, dass es mich verrückt macht, dass ich nicht sicher bin, wie ich es schnell und einfach beheben kann.

Antwort

3

Die Escape-Sequenzen werden bereits von der verwendeten Shell analysiert und entsprechend an das Befehlszeilenparameter-Array argv übergeben.

Wie Sie festgestellt haben, können nur die zitierten Versionen erkennen, dass eine Zeichenfolge analysiert und an Ihre main() übergeben wurde.
Da die meisten Shells ein echtes TAB-Zeichen als Whitespace einfach überspringen können, werden Sie es nie in Ihren Befehlszeilenargumenten sehen.

Aber wie erwähnt ist es hauptsächlich ein Problem, wie die Shell die Befehlszeile interpretiert und was zu Ihren Programmaufrufargumenten übrig bleibt, als wie man mit C++ oder c umgeht.

Meine Frage ist: Gibt es eine Möglichkeit zu geben, dass es sollte den Teil \ t als Tab-Zeichen (oder andere Escape-Sequenzen), anstatt die Stringliteral „\ t“ zu interpretieren? Ich könnte es manuell analysieren, aber ich versuche zu vermeiden, das Rad neu zu erfinden, wenn ich nur etwas kleines vermisse.

Sie müssen tatsächlich für einen Stringliteral

"\\t" 

innerhalb der C++ Code scannen.

+0

Vielen Dank. Ich fürchtete, dass dies der Fall sein würde, aber da ich weiß, dass dies der Fall ist, kann ich damit arbeiten. – LeapDayWilliam

Verwandte Themen