I tried to reverse a string using char array but in the output it prints some garbage value, I am unaware of that what is the cause plus it is only happening in large strings.
my code
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
char t[n]={0};
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}
input = APFGMRZXIFPSXKOQDRRQJBBZ
output = ZBBJQRRDQOKXSPFIXZRMGFPAB#
I want to know the reason behind # these two garbage values
Using online IDE of gfg.
C-style strings must be terminated by a null-character '\0'.
Instead of using Variable-Length Array, which is not in the standard C++, you should directly allocate string because you are returning that. (assuming that string here means std::string)
string reverseWord(string str){
int j = 0, n=0;
n = str.length();
string t(n); // allocate string instead of VLA
for(int i=n-1;i>=0;i--)
{
t[j]=str[i];
j+=1;
}
return t;
}
Related
I am writing code that finds the number of palindrome strings in a given array of strings. I think I have the right idea, but I am getting weird errors when I run it. What exactly am I doing wrong?
int countPalindromes(string s) {
int size = s.size();
int counter = 0;
string forwardSum = "";
string backwardSum = "";
for(int i = 0; i < size; i++){
for(int j = i; j < size; i++){
forwardSum.push_back(s[j]);
backwardSum.push_back(s[(n - 1)-j]);
if(forwardSum == backwardSum){
counter++;
}
}
}
return counter;
}
string forwardSum[] = {};
This is an array of zero size (which I don't believe is legal but we'll let that pass)
forwardSum[i] = forwardSum[i] + s[j];
This is an attempt to access the ith element of an array which has zero size.
That's bad.
I'm not really following your code (it's late at night), but I think you probably want forwardSum and backwardSum to be strings not arrays of strings. And you probably want to use push_back to add characters from s to those strings. I.e.
string forwardSum;
...
forwardSum.push_back(s[j]); // add s[j] to forwardSum
But if you really do want forwardSum to be an array, then the sensible thing to do would be to use a vector instead.
vector<string> forwardSum(size); // a vector of strings with the given size
Now that should at least not crash with the rest of your code.
The following code is part of my project in C++98, therefore i'm not allowed to use vectors and such. Now the main use for this function is to break down a single string line, to an array of strings using the given delimeter, and the size is basically the number of words that i need to return. the problem is that when i debug and check nums towards the end, it changed it's size to 4, and only returned the first word, filled by every char of it.As if, nums is now char* i have changed the code many times, but i don't where i went wrong, any advice?
string* Split(string ss,char delimeter,int size)
{
string *nums=new string[size];
int index_c, index_sw=0;
for (int i = 0; i < size; i++)
{
for(unsigned int j=0;j<ss.length();j++)
{
if (ss.at(j) == delimeter)
{
index_c = j;
nums[i] = ss.substr(index_sw, index_c);
index_sw += index_c;
i++;
}
}
break;
}
return nums;
}
Since you do not know the number of words in the string ss beforehand, you cannot specify size when calling the Split function. Not knowing size you will not be able to allocate memory to nums.
So you are better off using a vector of strings. As pointed out, vector is available in C++98.
Then your modified Split function will look like this:
vector<string> Split(string ss, char delimiter)
{
vector<string> vs;
int index_c, index_sw=0, j;
for(j=0;j<ss.length();j++)
{
if (ss.at(j) == delimiter)
{
index_c = j;
vs.push_back(ss.substr(index_sw, index_c - index_sw));
index_sw = index_c + 1;
}
}
vs.push_back(ss.substr(index_sw, j - index_sw));
return vs;
}
which then can be called like this:
vector<string> ret = Split("This is a stackoverflow answer", ' ');
See demo here.
I have a string vector which contains some number of strings greater than 500. I am using openssl functions that require buffers for encryption/decryption. Given that I am using string vectors and buffers in this manner, what is the best algorithm in terms of space and time to make this conversion. Each string can be assumed to be less than 200 chars.
Currently, I am extracting each entry in paths, concatenating the strings, calling the .c_str() method and using strcpy to extract from a function.
void copy(vector<string>& paths, unsigned char** plainTextBuffer, size_t& p_len){
int size = paths.size();
int i = 0;
string temp = "";
for(i=0; i<size; i++){
temp+= paths[i];
temp+= "\n";
}
p_len = temp.length();
(*plainTextBuffer) = malloc(p_len + 1);
strcpy((*plainTextBuffer), temp.c_str());
return;
}
Are there any built in tools to do this better and faster? (I have excluded error checking and casting from this snippet)
Edit:
I added the +1 to the malloc. I asked for a minimum complexity manner of getting from the initial conditions to the expected output. I am using malloc because I am using a simple buffer and it is faster than new.
Edit 2:
Thanks to some of the comments I am cutting out the middleman with some of the copying and have the following
void copy(vector<string>& paths, unsigned char** plainTextBuffer, size_t& p_len){
int size = paths.size(), total = 0, i = 0;
for(i=0; i<size; i++){
total+= paths[i].size() + 1;
}
p_len = total;
(*plainTextBuffer) = malloc(p_len + 1);
(*plainTextBuffer)[0] = '\0';
for(i=0; i<size; i++){
strcat((*plainTextBuffer), paths[i].c_str());
strcat((*plainTextBuffer, "\n");
}
return;
}
Again I left out some casting. Is there a more efficient manner of getting the buffer data into the plainTextBuffer?
The fastest way to convert a string to a C-style string is to not do any conversions. So first, let's convert our std::vector<std::string> into one std::string:
std::vector<std::string> v = ...;
std::string output;
for (auto& s : v) {
output += s;
output += '\n';
}
And then you can pass that in:
void some_c_api(char*, size_t );
void some_const_c_api(const char*, size_t);
some_c_api(&output[0], output.size());
some_const_c_api(output.c_str(), output.size());
Appending repeatedly into a string will result in the string repeatedly reallocating memory and shuffling its content into the new bigger space. A stringstream has a bigger creation cost, but it appends much faster than std::string, so instead of appending to a string in a loop, append to a stringstream:
stringstream temp;
for(size_t i=0; i<paths.size(); i++){
temp << paths[i] << endl;
}
const std::string& tmp = temp.str();
Then just use tmp like you would have used your previous temp string. It is better to get a constant reference to temp.str() because it will not copy the content of the temporary created by str().
Basically, here, I'm trying to reverse an array, and convert the reversed int array into a string (I'm trying to write the equivalent of Java's BigInteger class in C++ - basically turning the input into big endian ordering, breaking down the operations, reversing the result back to little endian format, and returning the string).
And as you can see below, it outputs some strange characters (I think it's an out of range reference?) - but I'm not entirely sure what caused this output?
I would really appreciate if you could take a look at it:
Sample input
int a[] = {1, 2, 3};
int rA[3];
reverseIntArray(a, rA, 3);
string aString = intArrayToString(a, 3);
cout << aString << endl;
Console output
123\216\377
As you can see - it calculates the answer correctly, with the exception of the \277_\377.
I'll post the rest of the relevant functions:
reverseIntArray
void reverseIntArray(int array[], int reversedArray[], int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
reversedArray[i] = array[arrayLength - 1 - i];
}
}
intArrayToString
string intArrayToString(int digits[], int length) {
// convert int array to char array
char digitsChar[length];
for (int i = 0; i < length; i++) {
digitsChar[i] = '0' + digits[i];
}
// convert char array to string
string intString(digitsChar);
return intString;
}
I'm quite sure this is a subtle issue to do with pointers, but I'm still relatively new to C++ (migrating from Java) and I've stared at this for hours but haven't come up with any ideas.
The std::string constructor you are using is assuming that the string you pass is properly terminated, which it isn't and that leads to undefined behavior as the std::string constructor goes beyond the end of the digitsChar array.
Three possible solutions:
Make room for another character in the digitsChar array and terminate it:
char digitsChar[size + 1];
for (...) { ... }
digitsChar[3] = '\0';
string intString(digitsChar);
Use another constructor where you pass the length of the character array:
string intString(digitsChar, length);
Append the characters directly to the string:
string intString;
for (int i = 0; i < length; i++) {
intString += '0' + digits[i];
}
There are of course other solutions as well, like for example using std::ostringstream.
so I'm working on a project that I have to read contents from a file and then analyze them. But I'm having a problem with getting the string out of a pointer that contains the address to what I need.
string lePapel(vector<char> vec){
string *str, s;
int i, j = 0;
vector<char> aux;
aux.resize(6);
for (i = 57; i <= 62; i++){
aux[j] = vec[i];
j++;
}
str = new string[aux.size()];
for (i = 0; i < 6; i++){ str[i] = aux[i]; }
return s;
}
So, the file contains in the array positions from 57 to 62 the word: ABCB4, but when returning the string s my output is A only as expected because of the pointer.
The thing is that I have been trying to find a solution and storing the whole content from vec[57] to vec[64] into the string s and returning it, and the closest that I got to returning anything plausible was using a pointer.
So, now to my question, how can I iterate the *str pointer and copy the whole content to s and return it?
Thanks in advance
I'd suggest you to not use pointers on string in your case. The following code is probably what you want :
#include <iostream>
#include <string>
#include <vector>
using namespace std;
string lePapel(vector<char> vec){
int j = 0;
vector<char> aux;
aux.resize(6);
for (int i = 57; i <= 62; i++){
aux[j] = vec[j];
j++;
}
string str;
str.reserve(6);
for (int i = 0; i < 6; i++){ str.push_back(aux[i]); }
return str;
}
int main() {
char x[5] = {'A', 'B', 'C', 'B', '4'};
vector<char> vec(x, x + 5);
string s = lePapel(vec);
cout << s;
return 0;
}
Tested here : Tested code
About reserving space to your vector : c++ vector::reserve
Same for strings : reserve for strings
The dynamic array of string objects and the whole aux vector seem completely needless here (unless there's some other purpose for them in your code). Additionally, str is currently causing a memory leak because you never delete it when you're finished.
A much simpler approach is just to append the characters one-at-a-time to the s string object (assuming it's a std::string):
string lePapel(vector<char> vec) {
string s;
for (int i = 57; i <= 62; i++) {
s += vec[i];
}
return s;
}
There are various ways to make the code even shorter (and more efficient) than that though, if you really want to.
EDIT: If you still need/want to iterate your dynamic array and concatenate the contents into s, here's how you could do it:
for (i = 0; i < 6; i++) s += str[i];
delete [] str; //<-- very important!
Short answer, you don't want a string * you want a char *. What you created is a string array. String objects contain a pointer to the char * data you are trying to capture. Also, the sizeof(std::string) (8 bytes in size) is a lot bigger than sizeof(char) (1 byte in size) the second character you store is 8 bytes away from the first character instead of being adjacent.
There are a lot of other C++ style and safety concerns, but I'll stick with the question. ;)