Thread: converting string into char*

  1. #1
    Registered User
    Join Date
    Jan 2011
    Posts
    222

    converting string into char*

    Hi,

    I am having some problems. I started with c++ and so far am finding it a bit confusing. (But i'll get there). the problem i am having right now is, how to convert string to char* . I was told the memcpy is the fastest way but i cannot figure out why it is not working. Oh and is there some tutorial regarding string manipulations in c++.


    Code:
    #include <cstring>
    #include <vector>
    #include <fstream>
    #include <iostream>
    
    
    // Read a file into a vector
    
    void help(char *program) {
      std::cout << program; 
      std::cout << ": Need a filename for a parameter.\n";
    }
    
    int main(int argc, char* argv[])
    {
      if (argc < 2){ 
    	help(argv[0]);
    	return 1;
      }
      
      std::vector<std::string> file;
      std::string line;
      
      file.clear();
      std::ifstream infile (argv[1], std::ios_base::in);
    
      int size = 0;
      while (getline(infile, line, '\n')){
        file.push_back (line);
        size += line.length();
      }
    
      char *a;
      a = new char[size];
      for (int i = 0; i<file.size();i++){
    	  memcpy(a[i+file[i].length()],file[i],file[i].length());
      }
    
      return 0;
    }
    so i need the lines i read from file to be in a char array since some other c function require it like that. Is there any better way to do this ??

    thank you


    P.S.
    Here is the error:

    Code:
     cannot convert ‘std::basic_string<char, std::char_traits<char>, std::allocator<char> >’ to ‘const void*’ for argument ‘2’ to ‘void* memcpy(void*, const void*, size_t)’
    baxy
    Last edited by baxy; 11-28-2012 at 08:36 AM. Reason: error

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    std::string has a c_str() member which returns a const char *. So the second parameter to your memcpy function should probably be file[i].c_str();.

    I would question the need to convert the thing to a char *. And I would also suggest something this as an alternative to what you have above:
    Code:
    std::string line, file; 
    while ( getline( inFile, line ) )
      file += line + "\n"; 
    
    std::cout<< file.length() << ": " << file;
    If you need a char * representation, simply do a file.c_str() and you have it with no extra memory allocation. Though this will be a const char *.

    I'll give you a simple rule of thumb for your future C++ing: stick with std::string unless there's a very good reason not to.

    Here's a reference for all std::string's member functions: http://www.cplusplus.com/reference/string/string/ It's a pretty light reference to the class, so you shoudn't have too much of a problem working with it. Most of the methods do what they sound like they should do.
    Last edited by twomers; 11-28-2012 at 08:48 AM. Reason: Reference link

  3. #3
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    That code makes a shiver run up and down my spine. You've picked the wrong tool for the job, and are hacking in the hope it will someone do what you want. You can thank your lucky stars that any self respecting compiler will reject that memcpy() call.

    Look up std::string's c_str() member function. And don't use memcpy() in any context related to C++ classes and member functions. Use the std::copy() instead.

    I fail to see why you're insisting on reading an array of std::strings, if your intent is to append all the strings into one.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  4. #4
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Code:
    #include <cstring>
    #include <string>
    
    int main()
    {
         char* cstr = NULL;
         std::string str("I want to copy this string!");
         cstr = new char [str.size()+1];
         strcpy (cstr, str.c_str());
         return 0;
    }
    Using memcpy() is vastly overcomplicating this problem (And also wrong in this context, as grumpy points out).

    This solution uses strcpy() which is a C-function. It's very simple but i'm sure there is a fancy STL-way of doing this. Also, why exactly do you want this string to be a char*? You can do pretty much everything related to strings using std::string, in a much safer and easier (and less error-prone) fashion, compared to using raw char arrays.

    Edit:

    I was right, this would be the proper function for copying characters from a std::string to a char buffer using C++:
    string::copy - C++ Reference
    Last edited by Neo1; 11-28-2012 at 09:07 AM.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    222
    ok , so why do i want to do this. I have a file classical txt. i want to read the file and sort all the string suffixes. in c i would do something like this

    Code:
    //function that i call
    fsort(char *, int)  // so my string + its length
    
    
    int cmpr(const void *a, const void *b) { 
     return strcmp(*(char **)a, *(char **)b);
    }
    
    void fsort(void *array, unsigned n) { 
     qsort(array, n, sizeof(char *), cmpr);
    }
    so i am confuced on how to do this with vectors of strings


    thank you

    P.S.


    Is there any way to read a file of undef size directly in a string and then sort it out. because as far as i got it you cannot reallocate memory in c++. and i need to read a file and the sort its suffxes.
    Last edited by baxy; 11-28-2012 at 09:31 AM. Reason: PS

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That sounds quite simple, since you are just using strcmp in your C version. Hence, just #include <algorithm> and write:
    Code:
    std::sort(file.begin(), file.end());
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Look into the STL sorting functions:

    sort - C++ Reference

    You can then use strcmp() as your comparison function. The types of the comparison function and the type of the data in the vector must match so you will have to write a wrapper function, something like this:

    Code:
    int cmpr(const std::string &a, const std::string &b)
    {
         return strcmp(a.c_str(), b.c_str());
    }
    Edit:

    Looks like Laserlights approach is superior, i suggest trying that instead.
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    That wrapper function is not correct. It should be:
    Code:
    bool cmpr(const std::string &a, const std::string &b)
    {
        return strcmp(a.c_str(), b.c_str()) < 0;
    }
    But as this will have the same effect as just doing a < b, you don't need the wrapper function at all.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Internet Superhero
    Join Date
    Sep 2006
    Location
    Denmark
    Posts
    964
    Ah ofcourse, the comparison returns a boolean. But why would it be the same as a < b?
    How I need a drink, alcoholic in nature, after the heavy lectures involving quantum mechanics.

  10. #10
    Registered User
    Join Date
    Jan 2011
    Posts
    222
    jeeea... but i have been testing some the c++ sorting functions and compared them with for example ds_sort (c implementation) and it turn out that they are 5 times slower and use more memory (to me this is a big issue since the text files that i am using are big) so i want to explicitly use ds_sort c function. the reason why i am struggling with c++ is the c doesn't seam to have watr_array implementation and c++ does and i need to combine these two things. so i need to have a char * to supply my c library... i don't see any way out of this ...

  11. #11
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Neo1
    But why would it be the same as a < b?
    Because the C version just forwards the job to strcmp, doing nothing special. Therefore, the comparison is the default. By default, std::sort uses operator<, and of course if you do strcmp(a.c_str(), b.c_str()) < 0, then you are also doing a less than comparison of the strings.

    If we keep to just using strcmp(a.c_str(), b.c_str()), then we are saying that "abc" is "less than" "cba" since strcmp("abc", "cba") != 0. We are also saying that "cba" is "less than" "abc" since strcmp("cba", "abc") != 0. Hence, we would be passing a comparison function to std::sort that does not result in a strict weak ordering, thus the behaviour is undefined.

    Quote Originally Posted by baxy
    i have been testing some the c++ sorting functions and compared them with for example ds_sort (c implementation) and it turn out that they are 5 times slower and use more memory
    What compiler and standard library implementation are you using?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  12. #12
    Registered User
    Join Date
    Jan 2011
    Posts
    222
    so i am using gcc 4.4.3, and i have been testing sorting functions from SeqAn library. they have a mirage of string sorting tools there but when i compared it with my deep_shallow re-implementation they turned out to be slow (for the things i am working on).
    Last edited by baxy; 11-28-2012 at 10:28 AM.

  13. #13
    Registered User
    Join Date
    Jan 2011
    Posts
    222
    ok so here is what i got. what is considered a bad practice here ??

    Code:
    #include <string>
    #include <vector>
    #include <fstream>
    #include <iostream>
    #include "read.h"
    
    
    
    // Read a file into a vector
    
    void help(char *program) {
      std::cout << program; 
      std::cout << ": Need a filename for a parameter.\n";
    }
    
    
    
    int main(int argc, char* argv[])
    {
      if (argc < 2){ 
    	help(argv[0]);
    	return 1;
      }
      
      strings Str;
      std::string line;
      
      Str.str.clear();
      std::ifstream infile (argv[1], std::ios_base::in);
      long size = 0;
      while (getline(infile, line, '\n')){
    		  Str.str.push_back(line);
    		  size += line.length();
    	  }
      }
     
      Str.strAlloc(size+1);
      
    
      for (int i = 0; i<Str.str.size();i++){
    	  strncat(Str.concstr,Str.str[i].c_str(),Str.str[i].length());
      }
    
      std::cout << "Str :\n" << Str.concstr <<"\n";
    
      return 0;
    }
    read.h

    Code:
    struct strings{
    
    	std::vector<std::string> str;
    	char *concstr;
    
    	void strAlloc(long int x){
    		concstr = new char[x];
    		concstr[0] = '\0';
    	}
    	
    	~strings(){
    		delete [] concstr;
    	}
    };
    thank you!

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by baxy
    so i am using gcc 4.4.3, and i have been testing sorting functions from SeqAn library.
    Ah, then what I had in mind does not apply. On recent Microsoft compilers/standard library implementations, checked iterators are turned on by default, even in the default release configuration. This is great for debugging, but not so good when you want optimised code, e.g., when using std::sort. However, since you are using gcc and a third party library, this concern does not apply.

    Quote Originally Posted by baxy
    they have a mirage of string sorting tools there but when i compared it with my deep_shallow re-implementation they turned out to be slow (for the things i am working on).
    ds_sort and deep_shallow are the same thing? What is ds_sort and deep_shallow anyway? I'm afraid that you need to explain what you are dealing with here.

    If you have a custom sort algorithm that works better for your data than std::sort and this SeqAn library that you tried, then by all means use it. Since you are capable of re-implementing it, I don't understand what is the problem that you are facing. Just re-implement in C++ with std::string, use it and profit.

    EDIT:
    Quote Originally Posted by baxy
    what is considered a bad practice here ??
    I suggest that you stick to std::string. You should only use null terminated C-style strings to interface with library functions that require them, or if you have some other very special reason to do so.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  15. #15
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    Well, what is bad practise? Here, it's doing thing that you don't need to do. Adding irrelevant redundency, swapping between std::string and char* unnecessarily. You can use the STL and perform this in very few lines of code.

    Your entire code code be performed via:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <algorithm>
    int main( void ) {
      std::string line; 
      std::vector<std::string> file; 
      std::ifstream inFile( __FILE__ ); 
      while ( std::getline( inFile, line ) )
        file.push_back( line ); 
      std::cout<< "Non-sorted...\n"; 
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
        std::cout<< *iter << "\n"; 
      std::cout<< "\n\nSorted...\n"; 
      std::sort( file.begin(), file.end() );
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
        std::cout<< *iter << "\n"; 
      return 0; 
    }
    There is absolutely no need to do any extra memory allocation.

    My output:
    Code:
    Non-sorted...
    #include <iostream>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <algorithm>
    int main( void ) {
      std::string line;
      std::vector<std::string> file;
      std::ifstream inFile( __FILE__ );
      while ( std::getline( inFile, line ) )
        file.push_back( line );
      std::cout<< "Non-sorted...\n";
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
        std::cout<< *iter << "\n";
      std::cout<< "\n\nSorted...\n";
      std::sort( file.begin(), file.end() );
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
        std::cout<< *iter << "\n";
      return 0;
    }
    
    
    Sorted...
        file.push_back( line );
        std::cout<< *iter << "\n";
        std::cout<< *iter << "\n";
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
      for ( std::vector<std::string>::iterator iter = file.begin(); iter!=file.end(); iter++ )
      return 0;
      std::cout<< "Non-sorted...\n";
      std::cout<< "\n\nSorted...\n";
      std::ifstream inFile( __FILE__ );
      std::sort( file.begin(), file.end() );
      std::string line;
      std::vector<std::string> file;
      while ( std::getline( inFile, line ) )
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    #include <string>
    #include <vector>
    int main( void ) {
    }
    Last edited by twomers; 11-28-2012 at 11:07 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Converting string to char array
    By frankchester in forum C Programming
    Replies: 13
    Last Post: 12-01-2010, 01:33 AM
  2. Converting string to char
    By aama100 in forum C++ Programming
    Replies: 10
    Last Post: 02-21-2008, 06:23 AM
  3. string to char converting problem
    By bergziege in forum C++ Programming
    Replies: 2
    Last Post: 08-07-2007, 03:37 PM
  4. converting char to string
    By deleeuw in forum C++ Programming
    Replies: 7
    Last Post: 09-24-2003, 08:01 PM
  5. problems converting string to char[]
    By Jan79 in forum C++ Programming
    Replies: 4
    Last Post: 07-06-2003, 03:28 AM