Format string in C++ when calling function [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
In c# we can use:
function_name("This is test number: " + i);
How can I do it in c++?
Thank you guys

Assuming that function_name takes an std::string argument, and you have C++11 support, you can use
function_name("This is test number: " + std::to_string(i));

Let;s at first consider the expression
"This is test number: " + i
You want to get some new string that will contain the both operands of the operator +. So this string has to be allocated dynamically in memory. The only standard C++ class that allocates a memory dynamically for strings is std::string. However it has no operator + where one of operands has an integral type. So object i has to be converted to an object of type std::string explicitly. It can be done using standard function std::to_string In this case the call would look as
function_name("This is test number: " + std::to_string( i ) );
However if the function accepts only arguments of type char * then you can not use class std::string.
So what do you need?
As I mentioned you have to allocate the character array itself before calling the function. Let assume that you defined such an array that can accomodate the string literal and the number stored in i.
char s[SOME_ENOUGH_SIZE];
When you could write
std::sprintf( s, "&s %i", "This is test number: ", i );
function_name( s );
You could also allocate the array dynamically. For example
char *s = new char[SOME_ENOUGH_SIZE];
and call the function the same way as shown above.

Actually, if i were an integer, then string + i would yield a array shifted by that many elements(assuming this keeps base address in bounds, else garbage data is produced).
So, in your case if i=4, then your string is passed as " is test number: ", removing "This".
So, if want to concatenate strings you can use above solution using std::string:
function_name("This is test number: " + std::to_string(i));
EDIT: Since you have commented that i is not int so this might no more remain valid.

Related

Using std::string_view in embedded [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 10 days ago.
Improve this question
C++17 string_view has this better syntax where we don't have to use this ugly long const std::string & when passing our text to function. But I don't really understand if this function can be used in code that is mixed with C, like printf function. My concern it that member function data() does not guarantee we have null terminating character.
The code I'm talking about is not performance critical, but has to be robust.
So my question is, is there any advantage from using it, or is it even worse than simple const std::string &? I see that it is recommended to use everywhere, but in case like mine it adds this layer of uncertainty that it could crash a program.
In general std::string_view::data() does not guarantee zero termination of the data refered to by the std::string_view.
From the documentation Notes section:
Unlike std::basic_string::data() and string literals,
std::basic_string_view::data() returns a pointer to a buffer that is
not necessarily null-terminated, for example a substring view (e.g.
from remove_suffix). Therefore, it is typically a mistake to pass
data() to a routine that takes just a const CharT* and expects a
null-terminated string.
(emphasis is mine)
The following short program demostrates it:
#include <string_view>
#include <iostream>
int main() {
char str[] = "abcdefghij";
std::string_view sv{ str, 2 };
std::cout << sv << std::endl;
std::cout << sv.data() << std::endl;
}
Possible output:
ab
abcdefghij
Live demo
Note that sv is only 2 characters (and std::cout prints it well), but when you access data() and attemtping to print it there is no zero termination where it is supposed to be. In this specific case (which is by no means a general rule) the zero termination comes eventually along the buffer from the char array str.
However - If your std::string_view is initialized to a whole (complete) zero terminated string (like a char array or std::string), then the data() pointer will probably "inherit" the zero termination from it. I am not sure if it is implementation depenedent.

Why does string concatenation fail when resize is used in cpp? [duplicate]

This question already has answers here:
What is an off-by-one error and how do I fix it?
(6 answers)
Closed 1 year ago.
I came across a scenario where string concatenation is failing in C++. But I don't see a reason for it to fail.
Code sample is as below:
int main()
{
std::string a;
std::string b = "bbbbbbb";
a.resize(10);
for (int i = 0; i <= 5; i++) {
a[i] = 'a';
}
a = a+b;
printf("\n%s\n", a.c_str());
}
It is outputting aaaaaa.
I was expecting it to output aaaaaabbbbb. If I change a.resize(10); to a.resize(5); I am getting the expected output.
Would be helpful if someone could help me in understanding the behaviour?
In addition to the off-by-one error, after concatenation, the contents of a in main are:
aaaaa\0\0\0\0\0bbbbb
So: five 'a' bytes, then five zero bytes, then five 'b' bytes. The string is fifteen bytes long.
printf, like other C functions, doesn't know about this size, and instead takes the length of the string to be until the first zero byte. In your case, that is "aaaaa".
To print the entire string, use something like std::cout. If you're certain you want printf, it is also possible to pass a length to that with the %.*s specifier.
std::string a;
a.resize(10);
gives you a string of size 10 but whose content is undefined.
You set the first 5 character to something specific and append some more characters to the end. But characters 5-10 never get set to something.
In the execution you are seeing, these characters happen to be zero, but printf – as a C style function — considers the appearance of a null character the end of the string. Therefore it stops printing.

Formatting a string of unknown length in C++ [duplicate]

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.

How to concatenate const char* strings in c++ with no function calls?

Ps: This is more of a conceptual question.
I know this makes things more complicated for no good reason, but here is what I'm wondering. If I'm not mistaken, a const char* "like this" in c++ is pointing to l and will be automatically zero terminated on compile time. I believe it is creating a temporary variable const char* to hold it, unless it is keeping track of the offset using a byte variable (I didn't check the disassembly). My question is, how would you if even possible, add characters to this string without having to call functions or instantiating strings?
Example (This is wrong, just so you can visualize what I meant):
"Like thi" + 's';
The closest thing I came up with was to store it to a const char* with enough spaces and change the other characters.
Example:
char str[9];
strcpy(str, "Like thi")
str[8] = 's';
Clarification:
Down vote: This question does not show any research effort; it is unclear or not useful
Ok, so the question has been highly down voted. There wasn't much reasoning on which of these my question was lacking on, so I'll try to improve all of those qualities.
My question was more so I could have a better understanding of what goes on when you simply create a string "like this" without storing the address of that string in a const char* I also wanted to know if it was possible to concatenate/change the content of that string without using functions like strcat() and without using the overloaded operator + from the class string. I'm aware this is not exactly useful for dealing with strings in C++, but I was curious whether or not there was a way besides the standard ways for doing so.
string example = "Like thi" + "s"; //I'm aware of the string class and its member functions
const char* example2 = "Like this"; //I'm also aware of C-type Strings (CString as well)
It is also possible that not having English as my native language made things even worst, I apologize for the confusion.
Instead of using a plain char string, you should use the string library provided by the C++ library:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string str = "Like thi";
cout << str << endl;
str = str + "s";
cout << str << endl;
return 0;
}
Normally, it's not possible to simply concatenate plain char * strings in C or C++, because they are merely pointers to arrays of characters. There's almost no reason you should be using a bare character array in C++ if you intend on doing any string manipulations within your own code.
Even if you need access to the C representation (e.g. for an external library) you can use string::c_str().
First, there is nothing null terminated, but the zero terminated. All char* strings in C end with '\0'.
When you in code do something like this:
char *name="Daniel";
compiler will generate a string that has a contents:
Daniel\0
and will initialize name pointer to point at it at a certain time during program execution depending on the variable context (member, static, ...).
Appending ANYTHING to the name won't work as you expect, since memory pointed to by name isn't changeable, and you'll probably get either access violation error or will overwrite something else.
Having
const char* copyOfTheName = name;
won't create a copy of the string in question, it will only have copyOfTheName point to the original string, so having
copyOfTheName[6]='A';
will be exactly as
name[6]='A';
and will only cause problems to you.
Use std::strcat instead. And please, do some investigating how the basic string operations work in C.

Char to Int in C++? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
How to convert a single char into an int
Well, I'm doing a basic program, wich handles some input like:
2+2
So, I need to add 2 + 2.
I did something like:
string mys "2+2";
fir = mys[0];
sec = mys[2];
But now I want to add "fir" to "sec", so I need to convert them to Int.
I tried "int(fir)" but didn't worked.
There are mulitple ways of converting a string to an int.
Solution 1: Using Legacy C functionality
int main()
{
//char hello[5];
//hello = "12345"; --->This wont compile
char hello[] = "12345";
Printf("My number is: %d", atoi(hello));
return 0;
}
Solution 2: Using lexical_cast(Most Appropriate & simplest)
int x = boost::lexical_cast<int>("12345");
Solution 3: Using C++ Streams
std::string hello("123");
std::stringstream str(hello);
int x;
str >> x;
if (!str)
{
// The conversion failed.
}
Alright so first a little backround on why what you attempted didn't work. In your example, fir is declared as a string. When you attempted to do int(fir), which is the same as (int)fir, you attempted a c-style cast from a string to an integer. Essentially you will get garbage because a c-style cast in c++ will run through all of the available casts and take the first one that works. At best your going to get the memory value that represents the character 2, which is dependent upon the character encoding your using (UTF-8, ascii etc...). For instance, if fir contained "2", then you might possibly get 0x32 as your integer value (assuming ascii). You should really never use c-style casts, and the only place where it's really safe to use them are conversions between numeric types.
If your given a string like the one in your example, first you should separate the string into the relevant sequences of characters (tokens) using a function like strtok. In this simple example that would be "2", "+" and "2". Once you've done that you can simple call a function such as atoi on the strings you want converted to integers.
Example:
string str = "2";
int i = atoi(str.c_str()); //value of 2
However, this will get slightly more complicated if you want to be able to handle non-integer numbers as well. In that case, your best bet is to separate on the operand (+ - / * etc), and then do a find on the numeric strings for a decimal point. If you find one you can treat it as a double and use the function atof instead of atoi, and if you don't, just stick with atoi.
Have you tried atoi or boost lexical cast?