2

I'm tinkering with C++ (I have a COBOL, Perl and PHP background) and I'm having trouble splitting a string so that I can act on each parsed field. I believe the trouble is to do with my lack of understanding of how C++ handles variables.

I've slurped a file's contents into an array successfully and I can act on each complete line (e.g. search/replace text). I also found some great examples of how to parse strings. The problem occurs when I try to apply the parse examples to the strings in my array.

The strings are created via:

    std::vector<std::string> File_Lines;
    ifstream file(filename.c_str());
    while ( file.good() ) {
      getline ( file, line, '\n' );
      string InputLine = string( line );
      File_Lines.push_back(line);
    }

One working example of parsing strings (that I found on this site) is:

char myString[] = "The quick brown fox";
char *p = strtok(myString, " ");
while (p) {
  printf ("Token: %s\n", p);
  p = strtok(NULL, " ");
}

The problem starts when I try to feed my string to the code that does the parsing. Feeding it directly:

char myString[] = File_Lines[array_counter];

gives "error: initializer fails to determine size of ‘myString’"

If I try converting using "std::string" (as suggested in other answers on this site):

std::string File_Line;
File_Line = File_Lines[array_counter];
char myString[] = File_Line;

...I get the same error.

Other answers suggested adjusting the code to:

char *myString = File_Line;

but that just gives me "error: cannot convert ‘std::string {aka std::basic_string}’ to ‘char*’ in initialization"

I'm aware that the problem is due to my own ignorance, but I'd really appreciate any help on how to feed a string into a parser.

Also, if anyone has any simple explanation of how to convert between the data types, that would be great.

Simon Roberts
  • 617
  • 1
  • 7
  • 14
  • `char *myString = FileLines[array_counter].c_str();` will compile. But you should be aware that the memory for the string contents will be freed when FileLines is destroyed (goes out of scope). – nullptr Jan 10 '15 at 22:10
  • Just stick with the C++ way of using `std::vector` and `std::string` instead of C-style `char *` pointers and arrays. It will make your life much easier. If you really want to have a `char * lines[]` out of a `std::vector lines`, you'll need to construct it yourself (copy each buffer). There is no automatic conversion. – 5gon12eder Jan 10 '15 at 22:11
  • Call [std::string::c_str](http://www.cplusplus.com/reference/string/string/c_str/) to get a `const char*` from a `std::string`. Use the string ctor to do the contrary. – tux3 Jan 10 '15 at 22:12

2 Answers2

3

This should be fine:

std::string ThisLine = File_Lines[array_counter]; // make a copy for strtok to mess up
char *p = strtok(&ThisLine[0], " "); // strtok needs a pointer to the first character
while (p) {
    printf ("Token: %s\n", p);
    p = strtok(NULL, " ");
}

But C++ has nicer ways to tokenize than strtok. For example, std::strstream with operator>> (for whitespace delimiters) or getline (for delimiter you specify).

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
1

use the following:

const char * myString1 = File_Lines[array_counter].c_str();
char * myString=const_cast<char*>myString1;
Anas
  • 263
  • 3
  • 11
  • 1
    const char* not char* – tux3 Jan 10 '15 at 22:17
  • I think he wants to pass the pointer to `strtok`, which will attempt to write to it. This will explode in that case. – Wintermute Jan 10 '15 at 22:18
  • "A program shall not alter any of the characters in this sequence.". Then he'll have to copy it. – tux3 Jan 10 '15 at 22:18
  • To write to it, you can use `char* myString = &some_std_string[0]` – Ben Voigt Jan 10 '15 at 22:22
  • This gives the error: "invalid conversion from ‘const char*’ to ‘char*’ [-fpermissive]" – Simon Roberts Jan 10 '15 at 22:23
  • you can still use 'const_cast' to remove the const-ness from your variable. – Anas Jan 10 '15 at 22:24
  • @Anas: No... See Wintermute and tux's comments. – Ben Voigt Jan 10 '15 at 22:25
  • @SimonRoberts: see this http://stackoverflow.com/questions/833034/how-to-convert-const-char-to-char – Anas Jan 10 '15 at 22:25
  • 1
    That you can cast away the cv qualifier is beside the point. The standard explicitly forbids you from writing to the return value of `c_str()` (in 21.4.7.1 [string.accessors]). If you take the result of `c_str()`, cast it to `char*` and write to that `char*`, you have to be prepared for segfaults or other nastiness. – Wintermute Jan 10 '15 at 22:36