2010-05-21 8 views
8

Bearbeiten: Nach der Implementierung von James Hopkin 's Vorschlag, bekomme ich immer noch die Warnungen von "ungültigen Namen' null '", die viel besser ist als diese seltsamen Zeichen. Dann ging ich zurück und las das Bibliotheksdokument erneut, und es stellte sich heraus, dass für diese spezielle Funktion das Argument ein weiteres Element einer Nicht-NULL-Zeichenkette als die Größe von aNames haben sollte. Diese zusätzliche Zeichenfolge hat einen anderen Zweck. Nach dem Hinzufügen einer weiteren Zeichenfolge wird der Code ordnungsgemäß ausgeführt. Es ist alles meine Schuld, und es tut mir so leid.Wie übergeben Sie den Vektor der Zeichenkette an foo (char const * const * const)?

Original-Beitrag:

Hallo,

Dies ist mein erster Beitrag so bitte schön. Ich habe in diesem Forum gesucht und gegoogelt, kann aber immer noch keine Antwort finden. Dieses Problem hat mich für mehr als einen Tag gestört, also bitte geben Sie mir Hilfe. Vielen Dank.

Ich muss einen Vektor der Zeichenfolge an eine Bibliotheksfunktion foo übergeben (char const * const * const). Ich kann die & Vec [0] nicht übergeben, da es ein Zeiger auf eine Zeichenfolge ist. Deshalb habe ich ein Array und übergebe das c_str() an dieses Array. Im Folgenden ist mein Code (aNames ist der Vektor der Zeichenfolge):

const char* aR[aNames.size()]; 

std::transform(aNames.begin(), aNames.end(), aR, 
       boost::bind(&std::string::c_str, _1)); 
foo(aR); 

Es scheint jedoch, es etwas undefiniertes Verhalten verursacht:

Wenn ich den obigen Code ausführen, dann wird die Funktion foo einige Warnungen verstreuen illegale Charaktere ('èI' blablabla) in aR.

Wenn ich aR vor Funktion foo wie folgt drucken:

std::copy(aR, aR+rowNames.size(), 
      std::ostream_iterator<const char*>(std::cout, "\n")); 
foo(aR); 

Dann ist alles in Ordnung. Meine Fragen sind:

  1. Hat die Umstellung nicht definiertes Verhalten verursacht? Wenn ja warum?

  2. Was ist der richtige Weg, Vektor der Zeichenfolge an foo übergeben (char const * const * const)?

Antwort

1

Nun, es scheint mir richtig zu sein. c_str erzeugt ein Null-terminiertes Array von char, das bis zur nächsten nicht-konstanten String-Operation konstant ist. Sie speichern die c_str-Zeiger in einem const char * -Array.

Ich bin kein Boost-Spezialist, so dass das Problem da sein könnte, aber meine Vermutung ist, dass Ihre Zeichenfolgen im Vektor in einer Codierung sind, die mit der in Funktion foo erwartet unvereinbar ist.

Überprüfen Sie Ihren Code aus der Sicht der Codierung.

MY2C

5

Da foo dauert nur einen Zeiger, ist meine wilde Vermutung, dass es einen NULL-terminierte Array erfordert. Weisen Sie ein zusätzliches Element für aR zu und weisen Sie ihm NULL zu.

Mein Vorschlag wäre:

std::vector<const char*> c_strings; 
c_strings.reserve(aNames.size() + 1); 

std::transform(
    aNames.begin(), aNames.end(), 
    std::back_inserter(c_strings), 
    boost::bind(&std::string::c_str, _1) 
    ); 

c_strings.push_back(0); 
foo(&c_strings[0]); 
+0

+1 Gut geraten. In der Tat ist die einzige Möglichkeit, eine Array-Größe für die 'foo'-Funktion zu finden, den NULL-Zeiger zu finden. –

+0

Ja, gut geraten! Es sei denn, die Signatur der foo-Funktion ist nicht die echte. @ user347208: Ist das die genaue Funktionssignatur? – neuro

+0

Vielen Dank für Ihre Hilfe! @neuro: Die exakte Funktionssignatur ist int foo (const char * Dateiname, char const * const * const rowNames, char const * const * const columnNames). Was ich jedoch in meiner Ausgabe gesagt habe, tut mir so leid, dass ich die Dokumente nicht sorgfältig gelesen und Zeit verschwendet habe. Wie auch immer, vielen Dank für Ihre Hilfe! – EXP0

1

Try this:

std::vector<char*> arr(aNames.size()+1); 
for(size_t i = 0; i < aNames.size(); ++i) 
    arr[i] = aNames[i].c_str(); 
arr[arr.size()-1] = NULL; // just in case 
foo(&arr[0]); 
+1

Kompiliert nicht - 'c_str' liefert ein' const char * ' –

+0

Ok. Ändern des Vektors, um "const char *" Elemente zu halten, kompiliert für mich jetzt. –