C++: Converting stringstream to char* runtime error - c++

I am trying to convert in C++ a stringstream of "1.txt" so that it is equal to a char* value of "1.txt". I need the raw char* as an argument for a function, so it can't be const char or anything else. When I run it, I get a blank output. Why, and how do I fix it?
#define SSTR(x) dynamic_cast< std::stringstream & >( (std::stringstream() << std::dec << x ) ).str()
int booknum = 1;
std::stringstream stringstream;
stringstream << SSTR(booknum) << ".txt";
std::vector<std::string> argv;
std::vector<char*> argc;
std::string arg;
std::string arg3;
while (stringstream >> arg) argv.push_back(arg);
for (auto i = argv.begin(); i != argv.end(); i++)
argc.push_back(const_cast<char*>(i->c_str()));
argc.push_back(0);
int arg4 = argc.size();
for (int i = 0; i < arg4; i++)
std::cout << &arg3[i] << std::endl;

That seems very complicated, instead of e.g.
std::ostringstream oss;
oss << booknum << ".txt";
std::string s = oss.str();
char* pString = new char[s.length() + 1];
std::copy(s.c_str(), s.c_str() + s.length() + 1, pString);
yourFunctionThatTakesCharPtr(pString);
delete[] pString;

Here's a sample conversion code:
#include <iostream>
#include <sstream>
#include <typeinfo> //it's just to print the resultant type to be sure
int main() {int booknum=1;
std::stringstream ss;
ss << booknum<<"1.txt";
char* x=new char[ss.str().length()+1];
ss >> x;
std::cout<<typeid(x).name();
return 0;}
Output:
Pc

Related

C++ XOR failing when reaching null byte?

Here is the code I have right now:
#include <iostream>
#include <string>
#include <sstream>
std::string string_to_hex(const std::string& input)
{
static const char* const lut = "0123456789ABCDEF";
size_t len = input.length();
std::string output;
output.reserve(2 * len);
for (size_t i = 0; i < len; ++i)
{
const unsigned char c = input[i];
output.push_back(lut[c >> 4]);
output.push_back(lut[c & 15]);
}
return output;
}
std::string encrypt(std::string msg, std::string key)
{
// Make sure the key is at least as long as the message
std::string tmp(key);
while (key.size() < msg.size())
key += tmp;
// And now for the encryption part
for (std::string::size_type i = 0; i < msg.size(); ++i)
msg[i] ^= key[i];
return msg;
}
std::string decrypt(std::string msg, std::string key)
{
return encrypt(msg, key); // lol
}
int main()
{
std::cout << string_to_hex(encrypt("Hello World!", "monkey")) << std::endl;
std::cout << decrypt("\x25\x0A\x02\x07\x0A\x59\x3A\x00\x1C\x07\x01\x58", "monkey") << std::endl;
std::cout << string_to_hex(encrypt("Hello. This is a test of encrypting strings in C++.", "monkey")) << std::endl;
std::cout << decrypt("\x25\x0A\x02\x07\x0A\x57\x4D\x3B\x06\x02\x16\x59\x04\x1C\x4E\x0A\x45\x0D\x08\x1C\x1A\x4B\x0A\x1F\x4D\x0A\x00\x08\x17\x00\x1D\x1B\x07\x05\x02\x59\x1E\x1B\x1C\x02\x0B\x1E\x1E\x4F\x07\x05\x45\x3A\x46\x44\x40", "monkey") << std::endl;
}
The output is the following:
250A02070A593A001C070158
Hello W
250A02070A574D3B06021659041C4E0A450D081C1A4B0A1F4D0A000817001D1B070502591E1B1C020B1E1E4F0705453A464440
Hello. This is a test of e
The decryption seems to stop when reaching a \x00. Does anyone have any ideas on how to fix or get around that?
Thanks!
The std::string constructor that takes in a char* assumes that the input is a null-terminated string, so even though your string literal has lots of data in it past the null byte, when you pass it into your function the std::string constructor will stop reading as soon as it hits that null byte.
You have a couple of options to fix this. As one option, the std::string type has a two-argument constructor where you can give a pointer to the first element in the string and the past-the-end byte of the string. The std::string will then initialize itself to the text in that range, ignoring intermediary null terminators.
char s1[] = "\x25\x0A\x02\x07\x0A\x59\x3A\x00\x1C\x07\x01\x58";
char s2[] = "\x25\x0A\x02\x07\x0A\x57\x4D\x3B\x06\x02\x16\x59\x04\x1C\x4E\x0A\x45\x0D\x08\x1C\x1A\x4B\x0A\x1F\x4D\x0A\x00\x08\x17\x00\x1D\x1B\x07\x05\x02\x59\x1E\x1B\x1C\x02\x0B\x1E\x1E\x4F\x07\x05\x45\x3A\x46\x44\x40";
std::cout << string_to_hex(encrypt("Hello World!", "monkey")) << std::endl;
std::cout << decrypt(std::string(std::begin(s1), std::end(s1)-1), "monkey") << std::endl;
std::cout << string_to_hex(encrypt("Hello. This is a test of encrypting strings in C++.", "monkey")) << std::endl;
std::cout << decrypt(std::string(std::begin(s2), std::end(s2)-1), "monkey") << std::endl;
Demo.

Convert char* array of integers to hex

I have a struct that stores the integer value as a custom string type.
typedef char OneLine[MAX_LINE + 1];
So I have some instances where I want the string that contains "12" to be converted to
C.
OneLine testString;
strcpy(testString, "12");
I'd like a way for me to convert testString to be "C"
How should I tackle this?
Thanks in advance.
You can use sscanf to convert "12" to an integer 12. Then you can use sprintf with %x format to convert integer 12 to "C"
The conversion can be done using stringstreams
#include <iostream>
#include <sstream>
#include <string>
#include <ios>
int main()
{
char const *str = "12";
std::istringstream iss( str );
int val;
if( !( iss >> val ) ) {
// handle error
}
std::ostringstream oss;
oss << std::hex << val;
std::cout << oss.str() << std::endl;
}
Or slightly less verbose way with C++11
char const *str = "12";
auto val = std::stoi( str );
std::ostringstream oss;
oss << std::hex << val;
std::cout << oss.str() << std::endl;
First, even if you were to do this manually, you shouldn't use char arrays for strings. Use std::[w]string.
Second, you can do this with std::[w][i|o]stringstream:
istringstream iss("12");
int number;
iss >> number;
ostringstream oss;
oss << hex << number;
const string& hexNumber = oss.str();
// hexNumber now contains "C"

What is the proper way to create a temporary char* and print to it?

I have a helper function that takes an unsigned char array of a fixed length, and returns it as a formatted char *. However, I'm having some problems.
I tried
char* byteArrayToString(unsigned char byte[6]) {
char t[18] = {""};
char* str = t;
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
return str;
}
and
char* byteArrayToString(unsigned char byte[6]) {
std::string t = "";
char* str = t;
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
return str;
}
and
char* byteArrayToString(unsigned char byte[6]) {
char* str = new char();
sprintf(str, "%02X:%02X:%02X:%02X:%02X:%02X", byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
return str;
}
The second one results in some side effects of the value of that string being changed. The first one ends up giving me junk values and the last seg faults (but I can't figure out why).
The problem with your first one is not in the printing, but in the returning. You're returning a pointer to an array which has been reclaimed (because it is an automatic variable, its lifetime ends when the function returns).
Instead try:
string byteArrayToString(const unsigned char* const byte)
{
char t[18] = {""};
sprintf(t, "%02X:%02X:%02X:%02X:%02X:%02X", byte[0], byte[1], byte[2], byte[3], byte[4], byte[5]);
return t;
}
Proper way is to return std::string as:
#include <sstream> //for std::ostringstream
#include <string> //for std::string
#include <iomanip> //for std::setw, std::setfill
std::string byteArrayToString(unsigned char byte[6])
{
std::ostringstream ss;
for(size_t i = 0 ; i < 5 ; ++i)
ss << "0X" << std::hex << std::setw(2) << std::setfill('0') << (int) byte[i] << ":";
ss << "0X" << std::hex << std::setw(2) << std::setfill('0') << (int) byte[5];
return ss.str();
}
Online demo
On the callsite you can get const char* as:
std::string s = byteArrayToString(bytes);
const char *str = s.c_str();

concatenate char with int

I have to concatenate char with int.
Here's my code:
int count = 100;
char* name = NULL;
sprintf((char *)name, "test_%d", count);
printf("%s\n", name);
Nothing printed. What's the problem?
You didn't allocate any memory into which sprintf could copy its result. You might try:
int count = 100;
char name[20];
sprintf(name, "test_%d", count);
printf("%s\n", name);
Or even:
int count = 100;
char *name = malloc(20);
sprintf(name, "test_%d", count);
printf("%s\n", name);
Of course, if your only goal is the print the combined string, you can just do this:
printf("test_%d\n", 100);
If you programm C++ use sstream instead:
stringstream oss;
string str;
int count =100
oss << count;
str=oss.str();
cout << str;
You have to allocate memory for name first. In C, library functions like sprintf won't make it for you.
In fact, I am very surprised that you didn't get a segmentation fault.
A simple workaround would be using char name[5+11+1] for the case of 32-bit int.
I use boost::format for this.
#include <boost/format.hpp>
int count = 100;
std::string name = boost::str( boost::format("test_%1%") % count );
Since the answer is tagged C++, this is probably how you should do it there:
The C++11 way: std::string str = "Hello " + std::to_string(5);
The Boost way: std::string str = "Hello " + boost::lexical_cast<std::string>(5);
#include <iostream>
#include <string>
#include <sstream>
int count = 100;
std::stringstream ss;
ss << "Helloworld";
ss << " ";
ss << count ;
ss << std::endl;
std::string str = ss.str();
std::cout << str;
const char * mystring = str.c_str();

how do i add a int to a string

i have a string and i need to add a number to it i.e a int. like:
string number1 = ("dfg");
int number2 = 123;
number1 += number2;
this is my code:
name = root_enter; // pull name from another string.
size_t sz;
sz = name.size(); //find the size of the string.
name.resize (sz + 5, account); // add the account number.
cout << name; //test the string.
this works... somewhat but i only get the "*name*88888" and... i don't know why.
i just need a way to add the value of a int to the end of a string
There are no in-built operators that do this. You can write your own function, overload an operator+ for a string and an int. If you use a custom function, try using a stringstream:
string addi2str(string const& instr, int v) {
stringstream s(instr);
s << v;
return s.str();
}
Use a stringstream.
#include <iostream>
#include <sstream>
using namespace std;
int main () {
int a = 30;
stringstream ss(stringstream::in | stringstream::out);
ss << "hello world";
ss << '\n';
ss << a;
cout << ss.str() << '\n';
return 0;
}
You can use string streams:
template<class T>
std::string to_string(const T& t) {
std::ostringstream ss;
ss << t;
return ss.str();
}
// usage:
std::string s("foo");
s.append(to_string(12345));
Alternatively you can use utilities like Boosts lexical_cast():
s.append(boost::lexical_cast<std::string>(12345));
Use a stringstream.
int x = 29;
std::stringstream ss;
ss << "My age is: " << x << std::endl;
std::string str = ss.str();
you can use lexecal_cast from boost, then C itoa and of course stringstream from STL