2

I want to use the gets() function for std::string str. But I get an error:

invalid conversion from 'const char*' to 'char*'

The strlen() function on the other hand doesn't give any error when I write

int len = strlen(str.c_str())

but gets(NUM.c_str()) gives the error.

Any suggestions? I need to use std::string and gets() as my character size is unknown.

9
  • 4
    @KerrekSB That's three, arguably four words. Commented Aug 22, 2013 at 18:13
  • 8
    Make the world a better place - don't use gets. Commented Aug 22, 2013 at 18:14
  • 3
    gets is about the most dangerous function ever invented. Use the C++ getline(). Commented Aug 22, 2013 at 18:14
  • 1
    @nightcracker: You haven't heard me say it yet! :-) Commented Aug 22, 2013 at 18:14
  • 1
    #define HACK_ME_NOW(s) gets(s) Commented Aug 22, 2013 at 18:15

4 Answers 4

9

c_str() returns a const pointer to the string contents, so you cannot use that to modify the string.

Even if you did circumvent that (which you really shouldn't), it would be impossible to change the size of the string (as you're trying to do), since that's managed by the string object. The best you could do is write over memory that may not be owned by the string, causing crashes or other undefined behaviour.

Even if you did have a suitable array to write to, don't use gets. There is no way to prevent it from overflowing the buffer, if the input line is too long. It's been deprecated in C since at least 1999.

Any suggestions?

std::getline(std::cin, NUM);
Sign up to request clarification or add additional context in comments.

Comments

5

Where to begin...

(1) Firstly, gets expects a char*, but std::string::c_str() returns const char*. The purpose of std::string::c_str() is merely to provide a C-string representation of the string data - it is NOT meant to provide a writable buffer. The function gets needs a writable character buffer.

(2) Secondly, you can use std::string as a writable character buffer using the [] operator, by saying:

std::string s(100); // create a buffer of size 100
char* buf = &s[0];

This is guaranteed to work properly in C++11, however in earlier versions of C++, it is not necessarily guaranteed that std::string provide a contiguous memory buffer. (Although, in practice, it almost always does.) Still, if you want a buffer, it's better to use std::vector<char>.

(3) Finally, don't use gets, EVER. It's ridiculously dangerous and makes your program prone to buffer overflow and shellcode injection attacks. The problem is that gets doesn't include a size parameter, so in practice the program will read any arbitrary amount of bytes into the buffer, potentially overflowing the buffer and resulting in undefined behavior. This has historically been an attack vector for many hackers, especially when gets is used with a stack array. The function fgets should be used instead in C, because it lets you specify a maximum read size parameter. In C++, it's better to use std::getline, because it works directly with an std::string object and therefore you don't need to worry about the size of the buffer.

Comments

0

I want to use gets() function

gets() is C. When possible it is better using C++ features

Instead try getline like this:-

std::getline(std::cin, NUM);

And as Jrok mentioned in the comments:-

Make the world a better place - don't use gets

1 Comment

Don't use gets in C either. It's deprecated, for goo reason.
0

In addition to the problems with trying to use gets in the first place, you cannot use it on a buffer returned from c_str() as the buffer is a const char* (which points to the string buffer held by the std::string object. If you insist on using gets(), you would need to create your own buffer to read into:

char buffer[1024] = {0}; // temporary buffer
gets(buffer); // read from stdin into the buffer
std::string s(buffer); // store the contents of the buffer in a std::string

For an explanation and example of why you should never use gets: http://www.gidnetwork.com/b-56.html

A much better approach is to

std::string s; // the std::string you are using
std::getline(std::cin, s); // read the line

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.