This question already has answers here:
How to concatenate a std::string and an int
(25 answers)
Closed 8 years ago.
Why is this code gives an Debug Assertion Fail?
std::string query;
int ClientID = 666;
query = "select logged from login where id = ";
query.append((char *)ClientID);
The std::string::append() method expects its argument to be a NULL terminated string (char*).
There are several approaches for producing a string containg an int:
std::ostringstream
#include <sstream>
std::ostringstream s;
s << "select logged from login where id = " << ClientID;
std::string query(s.str());
std::to_string (C++11)
std::string query("select logged from login where id = " +
std::to_string(ClientID));
boost::lexical_cast
#include <boost/lexical_cast.hpp>
std::string query("select logged from login where id = " +
boost::lexical_cast<std::string>(ClientID));
You cannot cast an int to a char* to get a string. Try this:
std::ostringstream sstream;
sstream << "select logged from login where id = " << ClientID;
std::string query = sstream.str();
stringstream reference
I have a feeling that your ClientID is not of a string type (zero-terminated char* or std::string) but some integral type (e.g. int) so you need to convert number to the string first:
std::stringstream ss;
ss << ClientID;
query.append(ss.str());
But you can use operator+ as well (instead of append):
query += ss.str();
You are casting ClientID to char* causing the function to assume its a null terinated char array, which it is not.
from cplusplus.com :
string& append ( const char * s ); Appends a copy of the string formed
by the null-terminated character sequence (C string) pointed by s. The
length of this character sequence is determined by the first ocurrence
of a null character (as determined by traits.length(s)).
Related
I want to append a char-variable containing the password to a string saying "Your password is: ". When I use the append function for this I get an error saying I can't use this function with string. (I can only use it with unsigned int and char.)
char pass[64];
std::cout << "Enter a password: "; fgets(pass, 64, stdin);
std::string ssifre = "Your password is: "; ssifre.append(sizeof(pass), pass);
If you know another way to solve this, please comment. I don't need to use this function.
This should work:
ssifre += pass;
It's using the += operator
(note that as #MichaelDoubez mentionned in the comments, ssifre.append(pass) would work, too.)
ssifre.append(sizeof(pass), pass) is trying to call the append(size_type count, CharT ch) overloaded version, which appends ch count times. That does not work since pass[] is not a single char, it is an array of chars.
You need to use the append(const CharT* s) overloaded version instead (especially since fgets() ensures that pass[] will be null-terminated, and append(const CharT* s) expects a null-terminated char* string). A fixed char[] array decays into a char* pointer to the 1st char element:
ssifre.append(pass);
That being said, you really shouldn't be using a char[] array in this situation to begin with. You should be reading in a std::string instead:
std::string pass;
std::cout << "Enter a password: ";
std::getline(std::cin, pass);
std::string ssifre = "Your password is: " + pass;
My problem is that I get an error when trying to add hard-coded text, "334 " before my decoded user input:
received = buf;
if(strncmp(buf, "334 ", 4) == 0){
decoding(received.c_str() + 4, strlen(buf + 4), buf);
received = "334 " + buf;
}
Here is the error I get:
invalid operands of types 'const char[5] and 'char[300] to binary 'operator+'
std::string has a constructor that takes a char *, so you can create a std::string from buf like this:
std::string buf_str(buf);
From cplusplus.com's list of std::string constructors:
string (const char* s);
Copies the null-terminated character sequence (C-string) pointed by s.
I dunno if that can suit you but you can consider using the stringstream class so that you can merge the text variables as:
stringstream longone;
string text;
longone << received << "334 ";
string=longone.str()
This question already has answers here:
How do I tokenize a string in C++?
(37 answers)
How do I iterate over the words of a string?
(84 answers)
Closed 9 years ago.
I have the following example:
string name_data = "John:Green;96";
I need to parse the string name, the string surname and int data. I've tried using sscanf, but it isn't working!
How should I do this?
You can use strtok() to first extract, the element that ends with :, and then the one that ends with ;. What remains will be the 96.
sscanf() is another option, although I don't consider it to be quite as flexible.
If you want to do it with sscanf, you can do it as follows:
string name_data = "John:Green;96";
char name_[256], surname_[256];
int data;
sscanf(name_data.c_str(), "%[^:]:%[^;];%d", name_, surname_, &data);
string name = name_, surname = surname_;
Note this assumes you'll only have up to 255 characters for name and surname, otherwise you'll need a bigger temporary buffer before converting it to string.
"%[^:]:%[^;];%d" means read a string until you find a ':', then skip that ':', then read a string until you find a ';', then skip that ';' and then read an integer
You can find additional functionalities/specifiers here.
Without using any secondary function calls other than that assoc. with the string class, we can do it like this:
size_t index = 0;
string firstName, surname, dataStr;
string tmpInput;
while (index!=name_data.length())
{
// First identify the first name
if (firstName.empty())
{
if (name_data[index] == ':')
{
firstName = tmpInput;
tmpInput.clear();
}
else
tmpInput.push_back(name_data[index]);
}
// Next identify the surname
else if (surname.empty())
{
if (name_data[index] == ";")
{
surname = tmpInput;
tmpInput.clear();
}
else
tmpInput.push_back(name_data[index]);
}
// Finally identify the integer as a string object
else
{
dataStr.push_back(name_data[index]);
}
index++;
}
To convert dataStr to an int would be just a simple atoi() call or use of the stringstream library.
You can use stringstream to get your tokens. That program demonstrate how you can do that:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
string x = "John:Green;96";
stringstream str(x);
std::string first;
std::string second;
int age;
std::getline(str, first, ':');
std::getline(str, second,';');
str >> age;
cout << "First: " << first << " Last: " << second << " Age: " << age << endl;
}
I am trying to use the new stringstreams method to convert certain float+int combination into certain format but trying to see if there is any better way to handle this:
Now using //string String = static_cast( &(ostringstream() << Number) )->str(); kind of mode - How can I get this stored into a string form of the format - "1.10(3)". Precision is equal to decimals. The catch here is none of these values are constants. Even if the solution can't be an in-line function or stringstreams - it's fine as long as it's generic enough. Also note that in the end the plan is to use this string into GDI text string.
Thanks in advance - if any one can help.
Here is my current sample code(and looking for an alternate efficient way to get this done):
string Convert(float number,int decimals)
{
std::ostringstream buff;
buff<<setprecision(decimals)<<fixed<<number;
return buff.str();
}
float f=1.1; // this can have any values from 1,1.5 or 1.52
int decimals=2; //dynamic number - calculated by other means - not a fixed number
int i=3; // some dynamic number as well - calculated by other means
string s=Convert(f,decimals)+"("+Convert(i,0)+")"; // output - 1.10(3)
You can use std::fixed, std::setprecision, std::setw and std::setfill defined in <iomanip> :
float f=1.1;
int decimals=2;
int i=3;
ostringstream ss;
ss << std::fixed << std::setprecision(decimals) << f << '(' << i << ')';
string str = ss.str();
Which outputs :
1.10(3)
You can also configure the stringstream and keep this configuration :
ostringstream ss;
ss.precision(5);
ss.setf(std::ios::fixed);
EDIT
You can still do this in one line if you really want to :
string str = ((ostringstream&)(ostringstream() << fixed << setprecision(decimals) << f << '(' << i << ')')).str();
If you want a LPCWSTR (const wchar_t *) instead of a LPCSTR (const char*) you should use wstringstream instead of stringstream.
ostringstream ss;
string str = ss.str();
LPCSTR* c_str = str.c_str();
wostringstream wss;
wstring wstr = wss.str();
LPCWSTR* wc_str = wstr.c_str();
If you want a LPCTSTR (LPCSTR or LPCWSTR if UNICODE is defined), you can use some typedef like this :
typedef std::basic_string<TCHAR> tstring;
typedef std::basic_ostringstream<TCHAR , std::char_traits<TCHAR> > tstringstream;
tostringstream tss;
tstring tstr = tss.str();
LPCTSTR* tc_str = tstr.c_str();
TCHAR is a char * if UNICODE is not defined in your project and a wchar_t * if UNICODE is defined.
So i have a char *. And i want to cut off some bit at the end. So
char *sentence = "My name is Ted";
How do I cut off the Ted. I could make it a string and then use substring (coming from Java thats my go to method) but id rather not do that way. But im not sure how to do it with a char *.
EDIT: Further on the problem. The issue is in a function that takes a process and is meant to return the location when that process is started from. Thats fine i can get that. But the parameter char *procLocation is passed by reference so the location will be sent back there.
I can only get the location that includes the name of the process. I want to cut off the name of the process and just return the location. Ive tried making the location a string and doing a substring (string - length of the processName). Thats fine. But
procLocation = location.c_str(); // where location.substr is the location - the process name
gives back an error: error C2440: '=' : cannot convert from 'const char *' to 'char *'
Since that is a string literal, you can't modify it.
If you did:
char sentence[] = "My name is Ted";
You could simply set the character before Ted to \0.
You might be better off using std::string though.
Instead of cutting off your literal, you could use std::string constructor that copies fewer characters than is available in your char*:
const char *data = "Hello, Ted!";
string s(data, data+8);
cout << s << endl;
This prints Hello, T
This approach is less wasteful than making a std::string and taking a substring.
To your original problem, as you're coming from Java, you should (should, in the sense of RFC2119) definitely use std::string:
#include <string>
#include <iostream>
using namespace std;
int main(int argc, const char** argv) {
// copy c-string to std::string
string arg0 = argv[0];
cout << arg0 << endl;
// find last occurrence of path separator
size_t found = arg0.find_last_of("/\\");
// split off filename part of string
cout << arg0.substr(0,found) << endl;
return 0;
}
Further, you should not (should not, in the sense of RFC2119) declare the char array as a char pointer, but as a char array:
char[] s0 = "Hello World!"; // <-- is better
char * s1 = "Hello World!"; // <-- avoid this
See this post for actual reasons why this is better. It also gives the reasons for why not to modify such rvalue strings.
You've tagged the question 'c++' and 'string' but you say you don't want to do this with string and substr ? Not sure why that is. You should prefer these over char* and C style string manipulation functions wherever possible.
To do it the C++ way:
string sentence = "My name is Ted";
cout << "\"" << sentence.substr(0, sentence.rfind(' ') ) << "\"" << endl;
Although you could (modifying your code slightly so that you have a mutable string) do this in C:
char sentence[] = "My name is Ted";
*strrchr(sentence, ' ') = '\0';
printf("\"%s\"\n", sentence);