I gotta question about Ice in C++. One of my methods requires that I pass in a Ice::ByteSeq. I would like to build this ByteSeq from a string. How is this conversion possible?
I tried the options below.
Ice::ByteSeq("bytes") // Invalid conversion to unsigned int
Ice::ByteSeq((byte*)"bytes") // Invalid conversion from byte* to unsigned int
(Ice::ByteSeq)"bytes" // Invalid conversion from const char& to unsigned int
(Ice::ByteSeq)(unsigned int)atoi("bytes") // Blank (obviously, why did I try this?)
How can I make this happen?
EDIT
"bytes" is a placeholder value. My actualy string is non-numeric text information.
Looking at the header, ByteSeq is an alias for vector<Byte>. You can initialise that from a std::string in the usual way
std::string s = "whatever";
Ice::ByteSeq bs(s.begin(), s.end());
or from a string literal with a bit more flappery, such as
template <size_t N>
Ice::ByteSeq byteseq_from_literal(char (&s)[N]) {
return Ice::ByteSeq(s, s+N-1); // assuming you don't want to include the terminator
}
Ice::ByteSeq bs = byteseq_from_literal("whatever");
You were almost there,
Ice::ByteSeq((unsigned int)atoi("bytes"));
should do it
Assuming your Ice::ByteSeq has a constructor that takes unsigned int
To split this down, it's basically doing
int num = atoi("12345"); // num = (int) 12345
unsigned int num2 = (unsigned int)num; // num2 = (unsigned int) 12345
Ice::ByteSeq(num2);
If Ice::ByteSeq is simply a vector of bytes you can convert a string to a vector of bytes by doing a variation of the following:
std::string str = "Hello World";
std::vector<char> bytes(str.begin(), str.end());
The implementation of Ice::Byte is an unsigned char just change the standard code I posted from:
std::vector<char> bytes(str.begin(), str.end());
to
std::vector<unsigned char> bytes(str.begin(), str.end());
and the generated vector should be directly compatible with an Ice::ByteSeq
sample code:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::string str = "Hello World";
std::vector<unsigned char> bytes(str.begin(), str.end());
cout << str << endl;
for(int i=0; i < bytes.size(); i++)
std::cout << bytes[i] << '\n';
return 0;
}
Hope this helps:)
Related
I have a string which has 1000 characters. I want to split this string to an array of strings of 5 characters each. The code is:
int main()
{
string myarray[200];
int k = 0;
string num = "a string with 1000 characters";
while(!num.empty())
{
strncpy(myarray[k],num.c_str(),5);
num.erase(0,5);
k++;
}
}
This code gives this error :
cannot convert 'std::string {aka std::basic_string}' to 'char*'
for argument '1' to 'char* strncpy(char*, const char*, size_t)'|
I tried the code without .c_str(), the result was same.
How can I fix this? Thanks.
Function strncpy expect first argument is char* while you passed string to it. Compiler will complain that it can't convert std::string to char*:
char *strncpy( char *dest, const char *src, std::size_t count );
Better use std::vector and call std::string::substr:
#include <string>
#include <vector>
std::string num("a string with 1000 characters");
std::vector<std::string> myarray;
myarray.reserve(200);
for (int i=0; i<num.size(); i+=5)
{
myarray.push_back(num.substr(i, 5));
}
You should use std::substr and std::vector:
#include <string>
#include <vector>
std::string num = "a string with 1000 characters";
std::vector<std::string> myArray;
for ( unsigned int i = 0; i < num.length(); i += 5 )
{
myArray.push_back( num.substr( i, 5 ) );
}
std::vector is a bit more flexible than array.
A working live example.
You may use std::substr as:
string MyArray[200];
for int i = 0;i<1000;i+=5)
{
MyArray[i] = num.substr(i,5);
}
And I would advice you to use vector<string> instead of MyArray[200] for a bit more flexibility.
So I am working on a tool that dereferences the values of some addresses, it is in both C and C++, and although I am not familiar with C++ I figured out I can maybe take advantage of the string type offered by C++.
What I have is this:
unsigned char contents_address = 0;
unsigned char * address = (unsigned char *) add.addr;
int i;
for(i = 0; i < bytesize; i++){ //bytesize can be anything from 1 to whatever
if(add.num == 3){
contents_address = *(address + i);
//printf("%02x ", contents_address);
}
}
As you can see what I am trying to do is dereference the unsigned char pointer. What I want to do is have a string variable and concatenate all of the dereferenced values into it and by the end instead of having to go through a for case for getting each one of the elements (by having an array of characters or by just going through the pointers) to have a string variable with everything inside.
NOTE: I need to do this because the string variable is going to a MySQL database and it would be a pain to insert an array into a table...
Try this that I borrowed from this link:
http://www.corsix.org/content/algorithmic-stdstring-creation
#include <sstream>
#include <iomanip>
std::string hexifyChar(int c)
{
std::stringstream ss;
ss << std::hex << std::setw(2) << std::setfill('0') << c;
return ss.str();
}
std::string hexify(const char* base, size_t len)
{
std::stringstream ss;
for(size_t i = 0; i < len; ++i)
ss << hexifyChar(base[i]);
return ss.str();
}
I didn't quite understand what you want to do here (why do you assign a dereferenced value to a variable called ..._address)?.
But maybe what you're looking for is a stringstream.
Here's a relatively efficient version that performs only one allocation and no additional function calls:
#include <string>
std::string hexify(unsigned char buf, unsigned int len)
{
std::string result;
result.reserve(2 * len);
static char const alphabet[] = "0123456789ABCDEF";
for (unsigned int i = 0; i != len)
{
result.push_back(alphabet[buf[i] / 16]);
result.push_back(alphabet[buf[i] % 16]);
{
return result;
}
This should be rather more efficient than using iostreams. You can also modify this trivially to write into a given output buffer, if you prefer a C version which leaves allocation to the consumer.
I'm trying to write a code which stores strings in an array. I'm trying to do it with char* but I couldn't achieve. I search the net but couldn't find an answer. I've tried the code below, but it didn't compile.I use string stream because at some point I need to concatenate a string with an integer.
stringstream asd;
asd<<"my name is"<<5;
string s = asd.str();
char *s1 = s;
> I'm trying to write a code which stores strings in an array.
Well, first you'll need an arary of strings. I don't like using naked arrays, so I use std::vector:
std::vector<std::string> myStrings;
But, I understand you have to use an array, so we'll use an array instead:
// I hope 20 is enough, but not too many.
std::string myStrings[20];
int j = 0;
> I use string stream because ...
Okay, we'll use stringstream:
std::stringstream s;
s << "Hello, Agent " << 99;
//myStrings.push_back(s.str()); // How *I* would have done it.
myStrings[j++] = s.str(); // How *you* have to do it.
That gets us one string, but you want an array of them:
for(int i = 3; i < 11; i+=2) {
s.str(""); // clear out old value
s << i << " is a" << (i==9?" very ":"n ") << "odd prime.";
//myStrings.push_back(s.str());
myStrings[j++] = s.str();
}
Now you have an array of strings.
Complete, tested program:
#include <sstream>
#include <iostream>
int main () {
// I hope 20 is enough, but not too many.
std::string myStrings[20];
int j = 0;
std::stringstream s;
s << "Hello, Agent " << 99;
//myStrings.push_back(s.str()); // How *I* would have done it.
myStrings[j++] = s.str(); // How *you* have to do it.
for(int i = 3; i < 11; i+=2) {
s.str(""); // clear out old value
s << i << " is a" << (i==9?" very ":"n ") << "odd prime.";
//myStrings.push_back(s.str());
myStrings[j++] = s.str();
}
// Now we have an array of strings, what to do with them?
// Let's print them.
for(j = 0; j < 5; j++) {
std::cout << myStrings[j] << "\n";
}
}
How about something like this?
vector<string> string_array;
stringstream asd;
asd<<"my name is"<<5;
string_array.push_back(asd.str());
char *s1 = s;
Is illegal. You either need:
const char *s1 = s.c_str();
if you're not set on char*, or you'll need to allocate a new char* and use strcpy to copy the contents from the string.
Just change your code to
char const* s1 = s.c_str();
because a pointer to char can't store a string object, only a pointer to char, which is what c_str() returns.
I wouldn't use the char * directly. I would wrap it in something like the template below. You can override the operators you need to do any more operations (example, I would make data a private member, and override the operators to make the data print out cleanly). I did the assignment operator just to demonstrate how clean that could make code.
#include "MainWindow.h"
#include <stdio.h>
using namespace std;
template<size_t size>
class SaferChar
{
public:
SaferChar & operator=(string const & other)
{
strncpy(data, other.c_str(), size);
return *this;
}
char data[size];
};
int main(int argc, char *argv[])
{
SaferChar<10> safeChar;
std::string String("Testing");
safeChar = String.c_str();
printf("%s\n", safeChar.data);
return 0;
}
I am new in c++ programming and I have been trying to convert from const char* to unsigned int with no luck.
I have a:
const char* charVar;
and i need to convert it to:
unsigned int uintVar;
How can it be done in C++?
Thanks
#include <iostream>
#include <sstream>
const char* value = "1234567";
stringstream strValue;
strValue << value;
unsigned int intValue;
strValue >> intValue;
cout << value << endl;
cout << intValue << endl;
Output:
1234567
1234567
What do you mean by convert?
If you are talking about reading an integer from the text, then you have several options.
Boost lexical cast: http://www.boost.org/doc/libs/1_44_0/libs/conversion/lexical_cast.htm
String stream:
const char* x = "10";
int y;
stringstream s(x);
s >> y;
Or good old C functions atoi() and strtol()
If you really want to convert a pointer to a constant character into an unsigned int then you should use in c++:
const char* p;
unsigned int i = reinterpret_cast<unsigned int>( p );
This converts the address to which the pointer points to into an unsigned integer.
If you want to convert the content to which the pointer points to into an unsigned int you should use:
const char* p;
unsigned int i = static_cast<unsigned int>( *p );
If you want to get an integer from a string, and hence interpret the const char* as a pointer to a const char array, you can use one of the solutions mentioned above.
The C way:
#include <stdlib.h>
int main() {
const char *charVar = "16";
unsigned int uintVar = 0;
uintVar = atoi(charVar);
return 0;
}
The C++ way:
#include <sstream>
int main() {
istringstream myStream("16");
unsigned int uintVar = 0;
myStream >> uintVar;
return 0;
}
Notice that in neither case did I check the return code of the conversion to make sure it actually worked.
In C this can be done using atoi which is also available to C++ via cstdlib.
I usually use this generic function to convert a string into "anything":
#include <sstream>
// Convert string values into type T results.
// Returns false in case the conversion fails.
template <typename T>
bool getValueFromString( const std::string & value, T & result )
{
std::istringstream iss( value );
return !( iss >> result ).fail();
}
just use it as in:
int main()
{
const char * a_string = "44";
unsigned int an_int;
bool success;
// convert from const char * into unsigned int
success = getValueFromString( a_string, an_int );
// or any other generic convertion
double a;
int b;
float c;
// conver to into double
success = getValueFromString( "45", a );
// conve rto into int
success = getValueFromString( "46", b );
// conver to into float
success = getValueFromString( "47.8", c );
}
atoi function will convert const char* to int, which can be implicitly converted to unsigned. This won't work for large integers that don't fit in int.
A more C++-ish way is to use strings and streams
#include <sstream>
#include <string>
int main()
{
std::string strVar;
unsigned uintVar;
std::istringstream in(strVar);
in >> uintVar;
}
An easier but nonstandard way would be to use boost's lexical cast.
HTH
So I know this is old but thought I would provide a more efficient way of doing this that will give you some flexibility on what you want as a base is.
#include<iostream>
unsigned long cstring_to_ul(const char* str, char** end = nullptr, int base = 10)
{
errno = 0; // Used to see if there was success or failure
auto ul = strtoul(str, end, base);
if(errno != ERANGE)
{
return ul;
}
return ULONG_MAX;
}
What this will do is create a wrapper around the method strtoul(const char* nptr, char** endptr, int base) method from C. For more information on this function you can read the description from the man page here https://linux.die.net/man/3/strtoul
Upon failure you will have errno = ERANGE, which will allow you to do a check after calling this function along with the value being ULONG_MAX.
An example of using this can be as follows:
int main()
{
unsigned long ul = cstring_to_ul("3284201");
if(errno == ERANGE && ul == ULONG_MAX)
{
std::cout << "Input out of range of unsigned long.\n";
exit(EXIT_FAILURE);
}
std::cout << "Output: " << ul << "\n";
}
This will give the output
Output: 3284201
Try in this way
#include<iostream>
#include <typeinfo> //includes typeid
using namespace std;
int main(){
char a = '3';
int k = 3;
const char* ptr = &a;
cout << typeid(*ptr).name() << endl; //prints the data type c = char
cout << typeid(*ptr-'0').name() << endl; //prints the data type i = integer
cout << *ptr-'0' << endl;
return 0;
}
Without more information there is no way to properly answer this question. What are you trying to convert exactly? If charVar is an ascii representation of the string, then you can do like others have suggested and use stringstreams, atoi, sscanf, etc.
If you want the actual value pointed to by charVar, then instead you'd want something like:
intValue = (unsigned int)(*charVal);
Or if charVal is the pointer to the first byte of an unsigned integer then:
intValue = *((unsigned int*)(charVal));
const char* charVar = "12345";
unsigned int uintVar;
try {
uintVar = std::stoi( std::string(charVar) );
}
catch(const std::invalid_argument& e) {
std::cout << "Invalid Arg: " << e.what() << endl;
}
catch(const std::out_of_range& e) {
std::cout << "Out of range: " << e.what() << endl;
}
You can also use strtoul or _tcstoul to get unsigned long value from const char* and then cast the value to unsigned int.
http://msdn.microsoft.com/en-us/library/5k9xb7x1(v=vs.71).aspx
const char* charVar = "1864056953";
unsigned int uintVar = 0;
for (const char* it = charVar; *it != 0; *it++){
if ((*it < 48) || (*it > 57)) break; // see ASCII table
uintVar *= 10; // overflow may occur
uintVar += *it - 48; //
}
std::cout << uintVar << std::endl;
std::cout << charVar << std::endl;
How do I convert a string into an array of integers? Can I use sstream, because atoi doesn't work?!
As you said in the comments, you got a binary string and you want to convert it into integers. Use bitset for that:
std::istringstream is(str);
std::bitset<32> bits; // assuming each num is 32 bits long
while(is >> bits) {
unsigned long number = bits.to_ulong();
// now, do whatever you want with that long.
v.push_back(number);
}
If you only have one binary number in that string str, you can get away with
unsigned long number = std::bitset<32>(str).to_ulong();
Converting that in C is also possible...
long value;
char const *c = str;
for(;;) {
char * endp;
value = strtol(c, &endp, 2);
if(endp == c)
break;
/* huh, no vector in C. You gotta print it out maybe */
printf("%d\n", value);
c = endp;
}
atoi can't parse binary numbers. But strtol can parse them if you tell it the right base.
How exactly would you like the conversion to work?
Do you simply want an array containing the ASCII value of each character in the array? (so "abc" becomes [97, 98, 99, 0])?
Or do you want to parse the string somehow? ("1, 2, 3" becomes an array [1, 2, 3])
In the first case, in C++, I'd do something like this:
struct convert {
int operator()(char c) {
return static_cast<int>(c);
}
};
std::string str = "hello world";
std::vector<int> result;
std::transform(str.begin(), str.end(), std::back_inserter(result), convert())
Of course you could use a raw array instead of the vector, but since the length of the string is probably going to be variable, and then arrays are just asking for trouble.
If this wasn't what you wanted, you might want to edit your question to be more specific.
From what I understand, for input string "110013" would be converted to array {1,1,0,0,1,3}. Here is how to do it in C++:
string a = "1110011000";
vector<int> v;
for(int i = 0 ; i < a.length() ; i++){
v.push_back(a[i] -'0');
}
// Check the result
for(int i = 0 ; i < v.size() ; i++){
cout << v[i] << endl;
}
Quick string splitter routine:
convert(string str, string delim, vector<int>& results)
{
int next;
char buf[20];
while( (next= str.find_first_of(delim)) != str.npos ) {
if (next> 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
str = str.substr(next+1);
}
if(str.length() > 0)
results.push_back(atoi(str.substr(0,next), buf, 10));
}
You can use stringstream instead of atoi (which does work, on a single int at a time)
int i;
stringstream s (input_string)
s >> i;
If you combine my and jalf's code, you'll get something really good.
Use the istream_iterator in conjunction with a string stream.
By Array I am assuming you really mean a std::vector as you don't know the number of integers at compile time. But the code can easily be modified to use an array rather than a vector.
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
int main()
{
std::string data = "5 6 7 8 9";
std::vector<int> store;
std::stringstream dataStream(data);
std::copy(std::istream_iterator<int>(dataStream),
std::istream_iterator<int>(),
std::back_inserter(store)
);
// This line just copies the store to the std::cout
// To verify it worked.
std::copy(store.begin(),
store.end(),
std::ostream_iterator<int>(std::cout,",")
);
}
Language: C
Header:
#include <stdlib.h>
Function Prototype:
long int strtol(const char *nptr, char **endptr, int base);
Example Usage:
strtol(nptr, (char **) NULL, 10);