0

i have taken all txt from file and place line by line into array of string. I am trying to split this string so that i can save word by word in separate array. Kindly just tell me how shell i convert the array of string into char.

for example

string line[15];  // line[0] has : was there before
                  // line[1] has : then after

char * pch;
char *c = line.c_str();   // string to char  (i am getting error here. Any body know?)
  pch = strtok (c," ");
  while (pch != NULL)
  {
    printf ("%s\n",pch);
    pch = strtok (NULL, " ");
  }

error: C2228: left of '.c_str' must have class/struct/union

Cœur
  • 37,241
  • 25
  • 195
  • 267
user3440716
  • 639
  • 2
  • 12
  • 23
  • 1
    `line` is not a string. It is an array of strings. You could perhaps do `line[0].c_str()`. You'll also need to use a `const char* pch;` or you'll get another error. – Fred Larson Nov 06 '14 at 18:33
  • 2
    `line` is an array. It isn't a `class/struct/union`. Did you mean (for example) `char* c = line[0].c_str();`? Also, you can write your own token function that works with `std::string` instead of using old c functions. – clcto Nov 06 '14 at 18:33
  • To add onto my last comment I wrote a `tokenize` function a while back that can be found at https://github.com/clcto/utile/blob/master/src/utile.cpp line 235 – clcto Nov 06 '14 at 18:39

2 Answers2

2

string line[15]; is an array of strings. So when you have line.c_str(); line is a pointer to a string and not a string itself. A pointer doesn't have a .c_str() method and that's why the compiler is complaining. (Pointers don't have any methods and hence the compiler tells you that the left hand side of the expression must be a class/struct/union type). To fix this you want to index into the array to get a string. You can do this with something like: line[0].c_str();

Additionally you can't write to anything returned by c_str() as it returns a const pointer. So you'll need to copy the results from c_str first before you then operate on it if you are going to change it in place.

Also it might be worth mentioning that there's c++ ways of doing tokenizing, you might find some examples here Split a string in C++? . The last time I did this I was already using boost so I made use of the boost::tokenizer library.

Community
  • 1
  • 1
shuttle87
  • 15,466
  • 11
  • 77
  • 106
  • ok. by writing char *c = line[0].c_str(); gives me error but when i write in this way char *c = line[0].c_str; not giving me error. (i am using visual studio 2012) so which is correct? – user3440716 Nov 06 '14 at 18:38
  • @user3440716 you will need to use something like `const char *c = line[0].c_str()` since `c_str()` is a method you need to have the parentheses. – shuttle87 Nov 06 '14 at 18:49
  • by placing const it is giving error: 'strtok' : cannot convert parameter 1 from 'const char *' to 'char *' – user3440716 Nov 06 '14 at 18:57
  • @user3440716, that's why I said in the answer that you have to copy the array (use something like `std::strcpy`) before you use it in `strtok` because `strtok` needs to get a `char*` and not a `const char*` however `c_str()` returns a `const char *`. – shuttle87 Nov 06 '14 at 18:59
  • can u suggest me a way because i am getting the variable pch1 is used without initialise. to whom i shd initialise? i have written in this way: const char * c = line[0].c_str(); char * pch,* pch1; strcpy(pch1,c); cout<<"hhhh"< – user3440716 Nov 06 '14 at 19:14
1

There are simpler ways to accomplish this in C++. The strtok function is a C function and cannot be used with std::string directly since there is no way to get writable pointer access to the underlying characters in an std::string. You can use iostreams to get individual words separated by spaces from a file directly in C++.

Unfortunately the standard library lacks a simple, flexible, efficient method to split strings on arbitrary characters. It gets more complicated if you want to use iostreams to accomplish splitting on something other than whitespace. Using boost::split or the boost::tokenizer suggestion from shuttle87 is a good option if you need something more flexible (and it may well be more efficient too).

Here's a code example reading words from standard input, you can use pretty much the same code with an ifstream to read from a file or a stringstream to read from a string: http://ideone.com/fPpU4l

#include <algorithm>
#include <iostream>
#include <iterator>
#include <string>

using namespace std;

int main() {
    vector<string> words;
    copy(istream_iterator<string>{cin}, istream_iterator<string>{}, back_inserter(words));
    copy(begin(words), end(words), ostream_iterator<string>{cout, ", "});
    cout << endl;
}
mattnewport
  • 13,728
  • 2
  • 35
  • 39