#include<iostream>
using namespace std;
int main() {
string str;
gets_s(str);
cout << str << endl;
return 0;
}
When I tried to run the above code it threw an error that no instance of gets_s() matched the argument list.
How can I pass an std::string instead of a char[] to gets_s() function if is possible?
The C function get_s takes a char* and a length argument, not a std::string.
Your best options are:
Formatted input:
std::cin >> str;
Read a line:
std::getline(std::cin, str);
Don't do that. Use the stream in a normal way:
#include<iostream>
using namespace std;
int main()
{
string str;
cin >> str;
cout << str << endl;
return 0;
}
gets_s has a significant limitation in that you must provide an upper limit on the number of characters you want to read.
Since you are using string the superior alternative is to use getline
#include <iostream>
#include <string>
using namespace std;
string str;
getline(cin, str);
This will expand the string to hold as many characters as are entered by the user.
gets_s() takes two arguments: pointer to char array and maximal size (your call is missing it). You cannot pass std::string - only C style strings.
Instead of C functions, why not use C++ way std::cin >> str or getline(std::cin, str)?
In C also don't use gets_s() (it's optional in C11) or gets() - use fgets() instead.
Well, there are a lot of answers about std::getline, but in case if you really need to use get_s, you may write such code:
size_t length = 10; // Just for example
std::string my_string(length, 0);
get_s(&my_string[0], length); // C++14 and older
get_s(my_string.data(), length); // C++17 and newer
Related
How do I use a c-string and avoid overflow? For example if I had the code:
#include <iostream>
using namespace std;
int main()
{
int size = 1000;
char * name = new char[size];
getline(cin, name);
}
I don't know how long that persons name is going to be, so how do you avoid an overflow? If I allocated 1000 as a precaution, they could just as easily input 1001 characters. What can I do to stop this from happening?
edit: I have to be able to do this without the string class
There is a version of std::getline() which accepts std::string as target buffer. It is designed to take advantage of std::string's auto-resize capability and prevent overflows. Example from std::getline manpage:
#include <string>
#include <iostream>
int main()
{
// greet the user
std::string name;
std::cout << "What is your name? ";
std::getline(std::cin, name);
std::cout << "Hello " << name << ", nice to meet you.\n";
}
In addition to the safety you asked about, std::string gives you also automatic memory management - so you don't need to remember to delete anything, which would be necessary in your example.
If you are not allowed to use std::string, you can use std::basic_istream::getline, which comes in two forms:
basic_istream& getline( char_type* s, std::streamsize count );
basic_istream& getline( char_type* s, std::streamsize count, char_type delim );
It allows you to specify max number of characters to read and an optional delimiter. std::basic_istream is the base class for std::istream. A very popular instance of this class is std::cin.
So basically, you can do:
char target[64];
std::cin.getline(target, 64);
I am trying this code to perform the following function : given an input file and a word(string) output should be the lines in the file containing the given word along with the line number. But I am getting an error saying "no matching function for call to ..." in the line where I am performing string operation (strstr). Here is my code. Please help me solve this. I am facing the same error in other programs also where ever I perform operations involving strings.
#include<iostream>
#include<fstream>
#include<string.h>
#include<stdio.h>
using namespace std;
int main()
{
int x;
char c;
ifstream iFile1, iFile2;
ofstream oFile;
char file1[50], file[50];
char word[50];
cout << "First file?\n";
gets(file1);
std::string str;
cout << "Word?\n";
gets(word);
iFile1.open(file1);
while (std::getline(iFile1, str)) {
x++;
if (strstr(str, word)) {
cout << "%d\t,x";
cout << str;
}
}
}
error: no matching function for call to 'strstr(std::string&,char[50])'
if(strstr(str,word))
^
char * strstr (char * str1, const char * str2 );
This is the signature of the strstr function, which requires both elements to be char*, but you are passing as first element a std::string&.
To fix this, try:
if (strstr(str.c_str(), word))
The c_str() method returns a char * to an array that contains the elements of the string
Also please note that the gets function is deprecated
Not the right answer, but still important to point out:
<string.h> is not <string>
<string.h>, and <cstring>, are header files defining several functions to manipulate C Strings and arrays (Source)
<string> defines std::string, which has the handy member function .c_str() allowing you to use functions which want a parameter of char*
Initializing a string in C# is as easy as this:
string str = Console.Read();
with this method, I don't need to know the size of the string which the user enters. But I cannot find a way like this in C++. I want my string to be defined as char *input, and I don't want to know the size of the string.
How can I achieve what I want?
Why not use C++'s string type?
#include <iostream>
#include <string>
int main() {
std::string foo;
std::cin >> foo;
std::cout << foo << "\n";
}
C++ has a string class which works much like C#'s string. So use it. :)
char* is not a string. It's just the closest you get if you're working in C.
So, #include <string>, and then use std::string instead of char*.
Use std::string and std::cin:
std::string str;
std::cin >> str;
While trying my code to answer another question I found out that the following didn't compile
#include <iostream>
#include <cstring>
#include <sstream>
#include <string>
using namespace std;
// (main omitted)
const char * coin = "3D";
istringstream ss(string(s));
int i;
ss >> hex >> i; <--- error here
cout << (char) i << endl;
It failed with the following error:
test.cpp:15:11: error: invalid operands of types ‘std::istringstream(std::string) {aka std::basic_istringstream<char>(std::basic_string<char>)}’ and ‘std::ios_base&(std::ios_base&)’ to binary ‘operator>>’
While the following compiled and ran properly :
const char* coin = "3D";
string s(coin);
istringstream ss(s); // or directly istringstream ss("3D")
int i;
ss >> hex >> i;
cout << (char) i << endl;
If I look at the definition of the constructor of istringstream, it accepts const std::string& (actually the basic_string<char> equivalent), and that compiles. So I guess the template argument deduction has a behaviour I don't understand and create a not so conform istringstream, but why ?
I am using GCC 4.6.1 (Ubuntu flavor).
EDIT : since istringstream is a typedef, I doubt there's any problem with templates in the end.
istringstream ss(string(s));
Your compiler thinks that's a declaration of a function taking a string (named s) and returning an istringstream. Surround the argument in parentheses in order to disambiguate it. By the way, what is s? Did you mean coin there?
istringstream ss( (string(coin)) );
Read this if you are confused.
In this particular case, you could of course have just done this:
istringstream ss(coin);
If your compiler supports it, you can also avoid the MVP using uniform initialization syntax:
istringstream ss{string{coin}};
That probably looks a bit odd to most people, I know it looks odd to me, but that's just because I'm so used to the old syntax.
#include<string>
...
string in;
//How do I store a string from stdin to in?
//
//gets(in) - 16 cannot convert `std::string' to `char*' for argument `1' to
//char* gets (char*)'
//
//scanf("%s",in) also gives some weird error
Similarly, how do I write out in to stdout or to a file??
You are trying to mix C style I/O with C++ types. When using C++ you should use the std::cin and std::cout streams for console input and output.
#include <string>
#include <iostream>
...
std::string in;
std::string out("hello world");
std::cin >> in;
std::cout << out;
But when reading a string std::cin stops reading as soon as it encounters a space or new line. You may want to use std::getline to get a entire line of input from the console.
std::getline(std::cin, in);
You use the same methods with a file (when dealing with non binary data).
std::ofstream ofs("myfile.txt");
ofs << myString;
There are many way to read text from stdin into a std::string. The thing about std::strings though is that they grow as needed, which in turn means they reallocate. Internally a std::string has a pointer to a fixed-length buffer. When the buffer is full and you request to add one or more character onto it, the std::string object will create a new, larger buffer instead of the old one and move all the text to the new buffer.
All this to say that if you know the length of text you are about to read beforehand then you can improve performance by avoiding these reallocations.
#include <iostream>
#include <string>
#include <streambuf>
using namespace std;
// ...
// if you don't know the length of string ahead of time:
string in(istreambuf_iterator<char>(cin), istreambuf_iterator<char>());
// if you do know the length of string:
in.reserve(TEXT_LENGTH);
in.assign(istreambuf_iterator<char>(cin), istreambuf_iterator<char>());
// alternatively (include <algorithm> for this):
copy(istreambuf_iterator<char>(cin), istreambuf_iterator<char>(),
back_inserter(in));
All of the above will copy all text found in stdin, untill end-of-file. If you only want a single line, use std::getline():
#include <string>
#include <iostream>
// ...
string in;
while( getline(cin, in) ) {
// ...
}
If you want a single character, use std::istream::get():
#include <iostream>
// ...
char ch;
while( cin.get(ch) ) {
// ...
}
C++ strings must be read and written using >> and << operators and other C++ equivalents. However, if you want to use scanf as in C, you can always read a string the C++ way and use sscanf with it:
std::string s;
std::getline(cin, s);
sscanf(s.c_str(), "%i%i%c", ...);
The easiest way to output a string is with:
s = "string...";
cout << s;
But printf will work too:
[fixed printf]
printf("%s", s.c_str());
The method c_str() returns a pointer to a null-terminated ASCII string, which can be used by all standard C functions.