This question already has answers here:
How to read and write a STL C++ string?
(3 answers)
Closed 4 years ago.
I've recently learnt about std::substr() by searching on Google. I saw a code something like this:
std::string s = "This is an example string";
std::string s1 = s.substr(11, 7);
std::cout << s1 << std::endl;
Now if I try to take input using scanf() function (instead of using std::cin), the program crashes during runtime. Doesn't std::string support using scanf() function?
scanf() belongs to a family of C functions that, being part of the C language rather than C++, offers no direct support for std::string and works instead with null terminated character strings.
If you are using C++, you should generally prefer std::string over null terminated terminated character strings and the input/output library over printf()/scanf() library functions.
Related
This question already has answers here:
printf with std::string?
(9 answers)
Closed 7 months ago.
std::string sszModName = "kernel32.dll";
std::string WinVersion = "WIN81";
std::string MachineGUID= "ce9e95db-5fda-436a-b29a-f5537702c77d";
char buf[1024];
sprintf(buf, "https://nulln.nullnu-ll.nul/nullnulln/api/ireport.php?module=%s&publisher=%s&win=%s&machineguid=%s", sszModName, "ERROR_HASH_VERIFY", WinVersion, MachineGUID);
This code causes program lag, could you help me figure out why?
Try
sprintf(buf,
"https://nulln.nullnu-ll.nul/nullnulln/api/ireport.php?module=%s&publisher=%s&win=%s&machineguid=%s",
sszModName.c_str(),
"ERROR_HASH_VERIFY",
WinVersion.c_str(),
MachineGUID.c_str());
C strings are not the same as C++ strings. spprintf only uses C strings so you must use .c_str() to turn your C++ strings into C strings.
This question already has answers here:
Variable number of arguments in C++?
(17 answers)
Closed 4 years ago.
I am kind of stuck in pre C++ 11 land. How can I write a function that takes n strings and appends them to an ostreamstream?
void Foo(std::string first_part, ...){
std::ostringstream oss;
oss << first_part << ...; // cant do it
for(int i = 0; i < ....length(); i++){ // :|
}
}
If I lived in a perfect world I could do the above. Is there any other way pre C++ 11 to loop through the ... arguments?
Sorry, but it can't be done directly (at least not in portable code).
Attempting to pass a non-trivial type (including std::string) as a variadic argument gives undefined behavior.
If you want to do something similar, you could (for one example) pass the addresses of a number of strings rather than attempting to pass the strings themselves.
If you do that, you'll still have to contend with one other detail: you'll need to tell the receiving function the number of (addresses of) strings to expect.
From there, the receiving function would use va_start, va_arg and va_end to retrieve the data and do it's thing with them.
This question already has answers here:
How to construct a std::string with embedded values, i.e. "string interpolation"?
(8 answers)
Closed 2 years ago.
I am currently learning C++ and I cannot find how to create a string with a formatter to take multiple parameters such as using sprintf but for an unknown string length.
What I want do is something like
string myString = string.format("Hello, here is %s %s and another %s", par1, par2, par3);
I know in C there is the asprintf function where it works out how long the string will be and it malloc's the memory and you need to free it when finished, however, this doesn't seem to be available for C++, although sprintf is. Everything I've seen on google about asprintf seems to mostly focus on Linux, whereas I need cross platform.
Everything I've seen about C++ and string formatting you need to define a char array of fixed length and use sprintf, but I am not going to know the length of the string so I can't do this.
In addition to the existing excellent answer, you may consider the Boost Format library.
Example:
std::string myString = str(boost::format("Hello, here is %s %s an another %s") % par1 % par2 % par3);
Get the book The Standard C++ Library by Josuttis. It will give you the complete string interface and much, much more. You appear to be thinking C, not C++. You could of course use a C interface like sprintf() to load a
char[] and then copy that to a C++ string. That is usually a bad idea.
Two ways to do what you ask:
string myString("Hello, here is ");
myString += par1;
myString += " ";
myString += par2;
myString += " and another ";
myString += par3;
stringstream foo;
foo << "Hello, here is " << par1 << " " << par2 << " and another " << par3;
string myString(foo.str());
There are lots of answers.
As C++ strings get very long, you want to use the std::stringstream to build them. This allows you to write to a string as though it were a file in memory, and it is written to handle very large strings efficiently. The C function snprintf() returns the number of characters it would have written if passed a null pointer. So you need to call it twice, once to get the size, then allocate the buffer and call again to format. It's a good solution for strings which are expected to be quite short and with a defined format, but might get arbitrarily long, like a string containing someone's name.
Note that printf() formats are convenient and easy to use for basic output of integers, string, and reals, but they don't scale up to user-defined objects because there's no accepted way of writing a toString() method and destroying the string after the call. They also can't handle arrays of objects. There is an accepted convention that overloading << writes a text representation of an object to a stream.
This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Why can't I write to a string literal while I *can* write to a string object?
(4 answers)
Is it possible to modify a string of char in C?
(9 answers)
Closed 8 years ago.
Basically, I am trying to increment the int value of port. This should be easy but I am a little stuck.
It compile fine, but I got this error when I run it:
Access violation writing location 0x001f5834
#include "stdafx.h"
#include "iostream"
using namespace std;
#define TESTING "5002"
int main()
{
char* port = TESTING;
int portint;
sscanf ( port, "%d", &portint );
portint++;
cout << portint << endl; // it works fine up to here, it prints 5003
sprintf ( port, "%d", portint);
return 0;
}
By default, compiler treats string literals as immutable, and an attempt to modify the contents of one results in an access violation error at run time because these strings are put into code segment, and it's read only. In your case, TESTING is a string literal, you can't not change its values. Try:
char port[] = "5002";
Meanwhile, the compiler should have warning on this: when you assign a const char* type to a char* type.
MS C++ compiler has a compiler option regards this: Zc:strictStrings.
You are trying to write "5003" back into "5002". "5002" is a string literal and cannot be written to.
I'll try to find a good duplicate for this question, because it has been asked in many ways, many times.
In your usage, "5002" becomes a static array of characters and as such can not be modified. I believe K&R address this, but I don't have the book in front of me right now. Behavior would be different if you had declared an array.
This question already has answers here:
printf with std::string?
(9 answers)
Closed 9 years ago.
So this is my code
string name;
cout <<"\n Enter Your name : \n";
cin >> name;
printf("%s" , name);
and for some weird reasons codeblocks crashes at this
why ?
also how could I fix it ?
thanks
You should compile with all warnings (e.g. g++ -Wall). You'll get a useful warning. You want to use c_str like this
printf("%s", name.c_str());
BTW, why use printfand why do you forget a \n at the end of the printf format string? (or use fflush)
Better code:
cout << name << endl;
If you need to pass your std::string to a function that accepts / uses C-style strings (const char *) for input, use .c_str(). It returns a const char *.
This is what you should do when needing to work with existing libraries, system calls, etc. For your own code, it is usually better to find a more C++ way of doing it.
In this case:
std::cout << name << std::endl;