0

i tryed to use this algorithm to convert a string to an array. the problem is this: strcpy don't work.

i tried also: strcpy_s strncpy memcpy --> with this function my array can print only the 1st word ( dunno why )...

string tmp;
getline(cin, tmp);
char* messaggio = new char[tmp.size()];
ZeroMemory(messaggio, tmp.size());
strcpy(messaggio, tmp.c_str());

tmp.resize(NULL);

i use Visual Studio 2013... when i try to use strcpy i have a strange error: C4996 may be unsafe. if i try with strcpy_s is the same, same with strncpy...

  • you have mentioned about print only 1st word and 2nd is C4996 compilation error. Are you getting compilation error or you are getting unexpected run time output. Both are different problem. – Mantosh Kumar Apr 01 '14 at 16:45
  • For compilation error(C4496) you read from here about how to disable it. http://msdn.microsoft.com/en-us/library/ttcz0bys.aspx – Mantosh Kumar Apr 01 '14 at 16:47
  • @tmp Is it an error, or just a warning? – James Kanze Apr 01 '14 at 16:47
  • in compile time i see this error. in another part of my algorithm i had the same error with "itoa" and "itoa_s" funcion, but i solved him changing the parameters... the 1st word print was only for "memcpy" for the others function i found only the error C4996. – user3464250 Apr 01 '14 at 16:52
  • Can you use std::string? It has a lot more functionality and would make this much easier. – lancegerday Apr 01 '14 at 16:55
  • tryed with "std::string" ( declared: {std::string tmp}) same error :/ – user3464250 Apr 01 '14 at 16:58

3 Answers3

2

One problem in your code, is that string::size gives you the number of characters excluding the null termination. So messagio does not have enough room for a nul-terminated string, and strcpy will try to write beyond its bounds.

As for the warning, it is because strcpy makes it very easy to go out of bounds. If the length of the source string is greater than that of the destination buffer, you get undefined behaviour. The suggested alternatives give you means to protect yourself from that (but are not 100% fool-proof).

If what you want is an array-like object containing the characters of the string, then the idiomatic way to do this is to use a vector:

std::vector<char> messagio(tmp.begin(), tmp.end());

If you really want a character string, then just use std::string.

juanchopanza
  • 223,364
  • 34
  • 402
  • 480
  • Another is that the code will inevitably leak memory. He should be using `std::vector` for his C style string. – James Kanze Apr 01 '14 at 16:46
  • thx for ur help, but my prob is not the string but the array... infact i need to put string,vector,list... into an array, not the reverse... – user3464250 Apr 01 '14 at 17:15
  • @user3464250 But why do you have to do that? It isn't clear from your question, so it could be that you don't actually need it. – juanchopanza Apr 01 '14 at 17:46
  • i need it... i pref to use string and dynamic functions but this program is using winsocket2 functions... infact i will use this function after this conversion: ""send(ConnectSocket, messaggio, tmp.size(), NULL);"" send need a char pointer but i need to send a message so i need a pointer to an array... also i need to send a message with "space"... for example now i send this "Hi There!"... with only an array my cout is: "Hi" and "There!" not "Hi There!" – user3464250 Apr 01 '14 at 17:57
  • @user3464250 What about `send(ConnectSocket, tmp.c_str(), tmp.size(), NULL);`? – juanchopanza Apr 01 '14 at 18:00
  • i need to use "send" func to send the message (messaggio) at the server... the problem is that send need a pointer to a char and i can't use string or vector... but i want a good message in cout like Hi there! and not Hi /0 There! – user3464250 Apr 01 '14 at 18:09
  • @user3464250 Try the line I posted above. – juanchopanza Apr 01 '14 at 18:20
  • thx! i tryed ur lane and print the 1st word "Hi There" Hi – user3464250 Apr 01 '14 at 18:31
0

The error you got in fact is not an error. It is a warning. Maybe you set on the option of the compiler that forces the compiler to consider all warnings as errors.

Your code has a bug. The size of the allocated array shall be one greater than the size of the string that to accomodate the terminating zero used by function std::strcpy

So you should write

std::string tmp;
std::getline( std::cin, tmp );

char* messaggio = new char[tmp.size() + 1];
std::strcpy( messaggio, tmp.c_str() );

Or you could write

strcpy_s( messaggio, tmp.size() + 1, tmp.c_str() );

though function strcpy_s is not a standard C++ function. It is present only in the C Standard.

I am sure you should ignore this warning.

If your compiler supports class std::dynarray you could use it instead of the raw pointer.

For example

std::dynarray<char> messagio( tmp.size() + 1 );
std::strcpy( messagio.data(), tmp.c_str() ); 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
  • thank you, but problem still is on... dynarray is not supported i think... anyway i need a pointer cause after i will use a fuction that recive a pointer as parameter. for (;;){ std::string tmp; std::getline(std::cin, tmp); char* messaggio = new char[tmp.size()+1]; ZeroMemory(messaggio, tmp.size()+1); std::strcpy(messaggio, tmp.c_str()); send(ConnectSocket, messaggio, tmp.size(), NULL); tmp.resize(NULL); } – user3464250 Apr 01 '14 at 17:36
  • I have not understood what problem you are speaking about> And why are you using ZeroMemory when there is no such call in my example? And what value should be used in function send temp.size() or tmp.size() + 1? – Vlad from Moscow Apr 01 '14 at 17:57
  • tryed with and without ZeroMemory but still nothing... i also took another project (similar at this) and see if options in the menu was the same... it are! when i go back to home i will see with more attention, but i think options are ok..... also i tryed with tmp.size() and tmp.size()+1 and nothing changed :/:/:/:/ – user3464250 Apr 01 '14 at 18:06
  • @user34 I do not understand what "still nothing" means. The code I showed is valid and workable. – Vlad from Moscow Apr 01 '14 at 18:42
  • @user3464250 if you mean that the compiler does not allow to use std::strcpy then use std::strncpy or strcpy_s as it suggest. – Vlad from Moscow Apr 01 '14 at 18:54
0

[SOLVED]

thx at all, expecially to "Vlad from Moscow" :3

std::string tmp;
        tmp.resize(0);
        std::getline(std::cin, tmp);
        char* messaggio = new char[tmp.size()+1];

        strcpy_s(messaggio, tmp.size()+1, tmp.c_str());

        send(ConnectSocket, messaggio, tmp.size()+1, NULL); //Send 2

        tmp.resize(0);
        delete messaggio;