• Advertisement
Sign in to follow this  

Convertion from std::string to char?!

This topic is 4430 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is it possible to convert from std::string to char somehow?! Because casting doesn't work, and I need it to be able to use the recv() function in WinSock. The recv() function takes a buffer parameter that's specified to be a char [or a char array], and there's no way of recieveing the correct amount of data on the server side unless I make about 50 different char arrays with different sizes or redimentionalize the char array buffer all the time, which I don't know how to do. Is there a way to do that? I would prefer to be able to convert from std::string to char somehow, though.

Share this post


Link to post
Share on other sites
Advertisement
[source lang = "cpp"]
std::string mystring = "hello";
const char* mychars = mystring.c_str();

Share this post


Link to post
Share on other sites
Quote:
Original post by Wixner
*** Source Snippet Removed ***


That won't work, he need a non-const array. He might be able to cast the constness away, but I expect that could introduce some problems. The best approach would be to recieve in an actual char array and then construct a std::basic_string from the char array. If there is a way to get the exact size needed you can construct a char buffer at the exact size.

About how to use the char array and resize it, to create a char string which you can give a new length, you do like this:

char* str = new char[strlen("Hello") + 1];
strcpy(str,"Hello");

Then later you can do like this:

delete [] str; // yes, you need this or a memory leak will occur.
str = new char[201]; // We now needs 200 chars

This will completely empty the str so you need to copy it to a temporary string before deleting it if you still need it.

Share this post


Link to post
Share on other sites
ARGH the lag!

Do I really need a non constant array?! Hmm.. I'll investigate. Thanks!

Share this post


Link to post
Share on other sites
Quote:
Original post by Afr0m@n
ARGH the lag!

Do I really need a non constant array?! Hmm.. I'll investigate. Thanks!


I haven't used this function myself, but as far as I can see you can set a max number of bytes to recieve, so if you have:
char InBuffer[50];
You can just set max number of bytes to recieve to 50, then you add InBuffer to a std::string or std::stringstream before calling recv again. Something like this:

char in[100];
std::stringstream SS;
do
{
int ReturnValue = recv(the_socket,in,100,SomeFlags);
if(ReturnValue == SOCKET_ERROR)
return false;
SS << in;
}while( ReturnValue >= 100 ); // If there is no more to recieve less than 100 bytes have been recieved

Share this post


Link to post
Share on other sites
Thanks for your input guys! So far, nothing's worked. I'm really intrigued by your proposition though, RDragon1. How would I use a vector like that? Here's my code so far:

#include "Global.h"

bool AccountLogIn(int id, SOCKET s)
{
JPlayer p;
std::vector<char> vec( str.begin(), str.end());

p.id = id;

recv(s,(char*) vec, 100, MSG_PEEK);
std::cout << vec;
if(vec == "ACCOUNTEXISTS")
{
std::cout << "Recieved message!";
}

return true;
}



This results in these errors:

--------------------Configuration: Server - Win32 Debug--------------------
Compiling...
AccountLogIn.cpp
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(6) : error C2039: 'vector' : is not a member of 'std'
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(6) : error C2065: 'vector' : undeclared identifier
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(6) : error C2062: type 'char' unexpected
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(10) : error C2065: 'vec' : undeclared identifier
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(12) : error C2446: '==' : no conversion from 'char *' to 'int'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
C:\Programs\C++\WinSock\Server\AccountLogIn.cpp(12) : error C2040: '==' : 'int' differs in levels of indirection from 'char [14]'
Error executing cl.exe.

Server.exe - 6 error(s), 0 warning(s)



I've included <string> in another header file, so I don't get most of these errors.

Share this post


Link to post
Share on other sites
use std::vector<char> like this:


std::vector<char> buffer;
buffer.resize(/*whatever size you want the buffer to be*/);

//Now to get a char* of the buffer:
char* buffer_ptr = &buffer[0];

//and to convert to a std::string
std::string asString(buffer.begin(),buffer.end());





You code would then become:

#include <vector>
#include <string>

/* the rest of your code */
bool AccountLogIn(int id, SOCKET s)
{
JPlayer p;
std::vector<char> vec(100);//buffer of size 100

p.id = id;

int bytes_recieved = recv(s,(char*) vec, 100, MSG_PEEK);

std::string recieved_message(&vec[0], &vec[bytes_recieved]);
if(recieved_message == "ACCOUNTEXISTS")
{
std::cout << "Recieved message!";
}
return true;
}

Share this post


Link to post
Share on other sites
#include "Global.h"

// needed for std::vector
#include <vector>

bool AccountLogIn(int id, SOCKET s)
{
JPlayer p;

// create a raw buffer to read into. Decide on an appropriate size
std::vector< char > buffer(100);

p.id = id;

// read into the buffer. Using buffer.size() ensures that we don't accidentally
// put different sizes in when declaring the buffer and reading into it
// and end up with a buffer overflow
// You probably want to check the return value of recv, like CTar showed
recv(s,&buffer[0], buffer.size(), MSG_PEEK);

// I assume that the data is null terminated. If not then you'll want to
// use the iterator range string constructor:
// std::string string(buffer.begin(), buffer.begin() + string_length);
std::string string(&buffer[0]);

// print out the string
std::cout << string;

// operator== works just fine on strings
if(vec == "ACCOUNTEXISTS")
{
std::cout << "Recieved message!";
}

return true;
}


Enigma

Share this post


Link to post
Share on other sites
Woah! Thanks ALOT guys! I tried out a combination of the methods you posted, and here's the final result:

#include "Global.h"

bool AccountLogIn(int id, SOCKET s)
{
JPlayer p;
std::vector<char> buffer(100);

p.id = id;

int bytes_recieved = recv(s,&buffer[0], buffer.size(), MSG_PEEK);
std::string recieved_message(&buffer[0], &buffer[bytes_recieved]);
std::cout << recieved_message;
if(recieved_message == "ACCOUNTEXISTS")
{
std::cout << "Recieved message!";
}

return true;
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement