How can I insert integer into a string using insert function in C++? - c++

Below check is string and temp1->data is integer. I want to insert temp1->data into check. So I type cast int into const char*. This gives warning : cast to pointer from integer of different size [-Wint-to-pointer-cast]
Part of code:
temp1 = head;
std::string check;
check = "";
int i = 0;
while(temp1 != NULL)
{
check.insert(i, (const char*)temp1->data);// here is the warning
temp1 = temp1->next;
++i;
}
I want to know what other choices I have to insert the integer (temp1->data) into string(check) using insert function and what is the actual effect of warning [-Wint-to-pointer-cast] on my code.
Points:
data is integer, next is pointer to Node
I'm trying to implement a function to check if a linked list containing single digit number is palindrome or not. Yes, I know other methods for this but I just want to implement through this method too.
Here I want to store all the data of linked list into a string and directly check if the string is palindrome or not.
This question may seem duplicate of this . But it is not, here I explicitly asked for inserting integer into string using insert function contained in string class.
PS: on using std::to_string(temp1->data) gives me error ‘to_string’ is not a member of ‘std’.

You can use std::to_string function to convert integer to string and then insert it in a string using insert function on std::string.
std::string check;
check = "";
int i = 0;
check.insert(i, std::to_string(10));
The reason you are getting error "to_string is not a member of std" is may be because you did not include <string> header.

First, here's a way to convert an integer to a string without much work. You basically create a stream, flush the int into it, and then extract the value you need. The underlying code will handle the dirty work.
Here's a quick example:
stringstream temp_stream;
int int_to_convert = 5;
temp_stream << int_to_convert;
string int_as_string(temp_stream.str());
Here's more info on this solution and alternatives if you want to know more:
Easiest way to convert int to string in C++
Regarding the impact of the cast that you're doing, the behavior will be undefined because you're setting char* to an int value. The effect won't be converting the int value to a series of characters, instead you'll be setting the memory location of what the system interprets as the location of first character of a char array to the value of the int.

Related

Why do I have to make a 2d array for this

I was solving a question online on strings where we had to perform run-length encoding on a given string, I wrote this function to achieve the answer
using namespace std;
string runLengthEncoding(string str) {
vector <char> encString;
int runLength = 1;
for(int i = 1; i < str.length(); i++)
{
if(str[i - 1] != str[i] || runLength == 9)
{
encString.push_back(to_string(runLength)[0]);
encString.push_back(str[i - 1]);
runLength = 0;
}
runLength++;
}
encString.push_back(to_string(runLength)[0]);
encString.push_back(str[str.size() - 1]);
string encodedString(encString.begin(), encString.end());
return encodedString;
}
Here I was getting a very long error on this particular line in the for loop and outside it when I wrote:
encString.push_back(to_string(runLength));
which I later found out should be:
encString.push_back(to_string(runLength)[0]);
instead
I don't quite understand why I have to insert it as a 2D element(I don't know if that is the right way to say it, forgive me I am a beginner in this) when I am just trying to insert the integer...
In stupid terms - why do I gotta add [0] in this?
std::to_string() returns a std::string. That's what it does, if you check your C++ textbook for a description of this C++ library function that's what you will read there.
encString.push_back( /* something */ )
Because encString is a std::vector<char>, it logically follows that the only thing can be push_back() into it is a char. Just a single char. C++ does not allow you to pass an entire std::string to a function that takes a single char parameter. C++ does not work this way, C++ allows only certain, specific conversions betweens different types, and this isn't one of them.
And that's why encString.push_back(to_string(runLength)); does not work. The [0] operator returns the first char from the returned std::string. What a lucky coincidence! You get a char from that, the push_back() expects a single char value, and everyone lives happily ever after.
Also, it is important to note that you do not, do not "gotta add [0]". You could use [1], if you have to add the 2nd character from the string, or any other character from the string, in the same manner. This explains the compilation error. Whether [0] is the right solution, or not, is something that you'll need to figure out separately. You wanted to know why this does not compile without the [0], and that's the answer: to_string() returns a std::string put you must push_back() a single char value, and using [0] makes it happen. Whether it's the right char, or not, that's a completely different question.

string not copying correctly and showing error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string<char>}'

I was trying to make Substrings of exactly half the length of original string and then sorting them in order of their ASCII codes and finally checking their equality by using strcmp() library function.
(That is i was trying to check if the parent string can be divided in two equal halves.)
So here is what I did:
Took input of parent string from user by cin.
Then I used variable hlength to store the value of half of the length of original string.
Now I declared two strings of equal lengths (equal to hlength ) so that first half of string is copied to substring named "s1" and the rest half is copied to substring "s2". i used for loops to copy the elements of the string.
To check whether the strings are correctly copied or not I printed each element of string just after copying them by using cout<< as you can see in the attached code.
Till now everything seemed alright as the result of individual elements when being printed were correct.
But!! here comes a situation which I never faced before: When I tried to print complete string using cout<<
The output was blank.
Later instead of printing the strings I just tried comparing them with the strcmp() function but it resulted in error: cannot convert 'std::__cxx11::string {aka std::__cxx11::basic_string}' to 'const char' for argument '1' to 'int strcmp(const char*, const char*)'*
#include <bits/stdc++.h>
#define fastIO ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define llt long long int
using namespace std;
int main()
{
int length,hlength,i,result;
string s;
cin>>s;
length = s.length();
hlength = length/2;
string s1,s2;
for(i = 0; i< hlength;i++)
{
s1[i] = s[i];
cout<<s1[i]<<endl; //each element gets printed successfully
}
for(i = 0; i< hlength ; i++)
{
s2[i] = s[length -1 - i];
cout<<s2[i]<<endl; //the elements are printed successfully, but obviously in the reverse order( order not matters)
}
cout<<s1<<endl<<s2; // no strings printed
sort(s1.begin(),s1.end());
sort(s2.begin(),s2.end());
result = strcmp(s1 , s2); //ERROR
cout<<result<<endl;
return 0;
}
PS: The original string is even in length.
Please help me know why the string is not printed but individual elements are printed correctly.
And what does that error means?
strcmp expects char pointers - this is what your error message tells you.
There is string::compare or operator == which you can use without this error. See:
Stackexchange Topic and cppreference.
For completeness you could also convert your std::strings to char pointers with c_str() method of your strings, but this is kind of ugly.
You see the real values, but you experience undefined behaviour. s1 and s2 are intialized with zero length. Operator [pos] definition:
If pos is less than the string length, the function never throws exceptions (no-throw guarantee).
If pos is equal to the string length, the const-version never throws exceptions (no-throw guarantee).
Otherwise, it causes undefined behavior.
The last point is what you experience - Maybe you write to a part of memory which does not belong to the string, but can access it in the same scope still. But when you try to cout the string, there is nothing written in the strings memory block. But who knows, its undefined behavior, anything can happen.
Section Exception safety in:
http://www.cplusplus.com/reference/string/string/operator[]/

Need to access an element from part of a string array

Suppose I have this code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string disectedString[5];
disectedString[0] = "011001";
string temp = disectedString[0];
string print = temp[0];
return 0;
}
So I'm selecting an element out of my array of strings, and then assigning it to a temp variable. From there, I want to select the first element out of the temp variable,(the first character). How would I go about doing this?
Your intuition is mostly valid: You use the square brackets operator, [], to access the element at an indexed position within a collection or sequence. Thus
disectedString[0] means "the first element of disectedString";
temp[0] means "the first element of temp";
What you've gotten mixed up are the types, as commenters and #demogorgon.net's answer have explained.
Now, with modern C++ you can "play dumb" and not declare what you know the types to be:
std::string disectedString[5];
disectedString[0] = "011001";
auto temp = disectedString[0];
auto print = temp[0];
Note the use of auto instead of a specific type name. This will work as you would like it to. You can then use use print, and do, for example:
std::cout << print;
and this will output 0.
By the way, I believe you should reconsider your choice of names:
Intuitively, print should refer to a function, or a method, which prints things; I'd suggest first_character or char_to_print or just c if you want to be brief.
temp is no more a temporary variable than, say, print.
It's better to avoid variable names which contain the type name, although we sometimes sort of have to resort to that. Specifically you using the word 'string' in variable names; probably not a good idea.
Your disectedString variable is not a string, it's an array of strings, which is confusing.
A string behaves in many ways like an array of char's (*). You need to set print to char type instead of string since you are trying to get a specific element from the string. So your print should look like this:
char print = temp[0];
(*) but it's really more complicated than that.
Here is a code example that prints the output.

Convert char* into String

I am using ESP8266 Wifi chip with the SMING framework which uses C++. I have a tcpServer function which receives data from a TCP port. I would like to convert the incoming char *data into String data type. This is what I did.
bool tcpServerClientReceive(TcpClient& client, char *data, int size)
{
String rx_data;
rx_data = String(data);
Serial.printf("rx_data=%s\r",rx_data);
}
The contents of rx_data is rubbish. What is wrong with the code? How to make rx_data into a proper string?
Why what you are doing is wrong:
A C style string is an array of char where the last element is a 0 Byte. This is how functions now where the string ends. They scan the next character until they find this zero byte. A C++ string is a class which can hold additional data.
For instance to get the length of a string one might choose to store the length of the stirng in a member of the class and update it everytime the string is modified. While this means additional work if the string is modified it makes the call t length trivial and fast, since it simply returns the stored value.
For C Strings on the other hand length has to loop over the array and count the number of characters until it finds the null byte. thus the runime of strlen depends on the lengh of the string.
The solution:
As pointed out above you have to print it correctly, try either:
#include <iostream>
...
std::cout << "rx_data=" << rx_data << std::endl;
or if you insist on printf (why use c++ then?) you can use either string::c_str(), or (since C++11, before the reutrned array might not be null terminated) string::data(): your code would become:
Serial.printf("rx_data=%s\r",rx_data.c_str());
I would suggest you have a look at std::string to get an idea of the details. In fact if you have the time a good book could help explaining a lot of important concepts, including containers, like std::string or std::vector. Don't assume that because you know C you know how to write C++.

Tokenizer - Initialization with '{...}' expected for aggregate object

I'm working on creating a program that will take a fraction and reduce it to it's lowest terms. I'm using a tokenizer to parse through the string (In my case I'm reading in a string) and separate the numerator from the denominator.
I'm getting the following error, and am looking for an explanation to why it's happening. I've looked up people with similar problems, but I'm still a beginner looking for a basic explanation and suggestion for an alternative way to solve it.
RationalNum() // Default
:numerator(0), denominator(1){}
RationalNum(int num) // Whole Number
:numerator(num), denominator(1){}
RationalNum(int num, int denom) // Fractional Number
:numerator(num), denominator(denom){}
RationalNum(string s)
{
int num = 0;
char str[] = s;
}
I know the problem lies in the setting the char array to s.
Thanks for taking the time to look at this.
You are trying to initialise an array of char to a std::string, which is an object. The literal meaning of the error is that the compiler is expecting an initialisation that looks something like this :
char str[] = {'1','2','3','4'};
However, since you are planning on string manipulation anyway, you would have a much easier time just keeping the string object rather than trying to assign it to a char array.
Instead of building your parser from scratch, you can use string stream and getline. with '/' as your delimiter. You can initialise an std::stringstream with a string by passing it as an argument when constructing it. You can also use another stringstream to convert a string into a number by using the >> operator.