Reversing the sequence of a string [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
A fairly simple program, trying to reverse the characters in a null terminated string in C++, but something seems to be going wrong.
#include <iostream>
using namespace std;
void reverse(char*);
int main(){
char *str;
cout<< "Please enter a string, no spaces please..";
cin >> str;
//reverse(str);
}
void reverse(char *str){
char temp;
size_t len = strlen(str);
for (size_t i = 0; i < len/2; i--)
{
temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
Getting the following error
Bus error: 10
Any help appreciated.

Allocate memory for str before use char *str = new char[25];
In reverse function for for loop increment i for (size_t i = 0; i < len/2; i++ )
Deallocate memory after use delete [] str ;

You are decrementing iterator i insted of incrementing it. A little bit compact version of yours:
#include <algorithm>
#include <cstring>
void reverse(char* const str)
{
unsigned long const len = strlen(str);
for(unsigned long i = 0; i < len >> 1; i++)
std::swap(str[len - i - 1], str[i]);
}

#include <algorithm>
#include <string>
#include <iostream>
#include <cstring>
int main() {
// You can't read something to nowhere.
// String will be holded in static array.
char str[1024];
// To keep it as null terminated string after
// writing of inputed string: `std::cin` don't
// write null character after writing of data.
memset(str, 0, 1024);
std::cin >> str;
// If you do reversing of strings in C++,
// you shouldn't use hand written loops:
std::reverse(str, str + strlen(str));
std::cout << str << std::endl;
}

Try this modified version of your code:
#include <iostream>
#include <cstring>
using namespace std;
void reverse(char*);
int main(){
char str[1024]; // buffer of 1024 chars
cout<< "Please enter a string, no spaces please..";
cin >> str;
reverse(str);
cout << "\nReversed: " << str;
}
void reverse(char *str){
char temp;
size_t len = strlen(str);
for (size_t i = 0; i < len/2; i++) // loop until half of the user input
{
temp = str[i];
str[i] = str[len-i-1];
str[len-i-1] = temp;
}
}
I simply added the array of char char str[1024]; to store the user input.. and changed the loop to: for (size_t i = 0; i < len/2; i++)
However, you must be very careful with the above code.. it works properly if the size of the input is less than the array fixed size.

Related

How can I convert an char array to string without dealing with the string as an array

int main() {
char arr[10] = {};
string str;
arr[0] = 'h';
arr[1] = 'e';
arr[2] = 'y';
for (int i = 0; i < 10; i++) {
str[i] = arr[i];
}
cout << str;
}
Why this code is not printing hey?
I didn't forget to include the libraries I just put the important part of the code.
when I try to cout str[1] as an example it cout 'e' but when I try to cout the string as it is it doesn't print anything.
I apologize in advance if my explanation is a bit vague but you forgot to include the <iostream> and <string> libraries in your header. Also, since you are using the string library, you must include the using namespace std; within the scope of your string str;. There is a bit more optimization that you can do to your code. For example, in this case, it is optimal to iterate up to the size of your array instead of iterating through to 10 as most of your array is empty. Also, because you are adding char values to a string object, you can just concatenate the empty string with the value at arr[i].
#include <iostream>
#include <string>
int main ()
{
using namespace std; //must include this as string object requires it
char arr[10];
string str;
arr[0]='h';
arr[1]='e';
arr[2]='y';
for (int i = 0; i < sizeof(arr); i++)
{
str += arr[i]; //adds arr[i] to the end of str
}
cout << str; //prints string
}
I hope this helps and was clear enough!

Reversing characters from input

I am trying to reverse a char which has been provided in input from an user. I am having issues with the reverse function, particularly the loop. I can't get it to work- can I get advice?
#include <iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char temp[len];
for(int i=len; i>len; --i) {
temp[i]+=input[i];
}
return temp;
}
int main()
{
char input[100];
while(cin>>input) {
cout << reverse(input);
}
return 0;
}
Your Program has few issues
You're trying to return local variable address i.e. temp array address. The Function will return the address to main function. Since memory might get cleaned so it will print garbage value present at the address.
As Rohan Bari mentioned variable length array might cause undefined behavior. There for you can create a constant length array i.e.
char temp[100];
or you can dynamically allocate array on heap. Memory allocated on heap do not get cleared after termination of block but we have to manually delete it.
char* temp = new char[len];
As array start from 0 it goes till len-1 so loop condition should start from len-1 and has to go till 0 to reverse.
+ operator do not work's with array or char even if you are trying to add just char it preforms normal integer addition of their ASCII value.
Here is improved version of your code
#include<iostream>
using namespace std;
#include <cstring>
char* reverse(char* input) {
int len = strlen(input);
char* temp = new char [len]; // or you can use char temp[100];
int j = 0; //temp variable to enter values from 0th index if we use same as loop it just enter in the same order as original char array.
for(int i=len-1; i>=0; --i) {
temp[j++] = input[i];
}
temp[j] = '\0';
return temp;
}
You have got several errors in the program.
The variable-length arrays are used here:
char temp[len];
This should not be applied in C++ since this invokes undefined-behavior. Note that this is a valid statement in the C99 standard.
There is a better alternative to this. That is to take the std::string built-in type in use.
In the following line:
temp[i] += input[i];
You are not sequentially adding one character after another, but the values of them in a single integer. This could be not a problem if temp was of the type std::string.
The reverse function should look like this:
const char *reverse(char *input) {
int len = strlen(input);
std::string temp;
while (len--)
temp += input[len];
return temp.c_str();
}
len should actually be (len-1) and i should be >= 0 not len, so from (len-1) to 0 your loop should run.
for(int i = len-1; i >= 0; i--){}
You have to allocate the new array with the new keyword if you don't want to use a string. The following code does what you need:
char* reverse(char* input)
{
int len = strlen(input);
char* temp = new char[len + 1];
for (int i = len; i >= 0; --i)
{
temp[len-i-1] = input[i];
}
temp[len] = '\0';
return temp;
}
You could use a std::stack to reverse your input:
std::stack<char> s;
char c;
while (std::cin >> c)
{
s.push(c);
}
while (!s.empty())
{
std::cout << s.top();
s.pop();
}
It's 2021. Use the STL. If your instructor isn't aware of it or doesn't allow you to use it, your instructor is not keeping up-to-date and you should fire your instructor.
#include <algorithm>
#include <iostream>
#include <string>
int main() {
std::string input{};
while(std::getline(std::cin, input)) {
std::reverse(std::begin(input), std::end(input));
std::cout << input << '\n';
}
return 0;
}
There's quite many things wrong with the code as many people have already mentioned! Since you want to implement this without using STL it can be done this way,
#include <iostream>
using namespace std;
#include <cstring>
void reverse(char* input,int len) { //added len as argument
char temp[len];
for(int i=len-1; i>=0; --i) {
temp[len-i-1]=input[i];
cout<<temp[len-i-1]; //printing while reversing
}
cout<<endl;
}
int main()
{
char input[100];
int len=0;
//using do while since it has to run atleast once
do{
cin.getline(input,100);
len=strlen(input);
input[len]='\0';
if(len!=0)
reverse(input,len);
}while(len!=0) ;
return 0;
}

How do I read a stringstream into a char *[40] / char ** array?

I am working on creating a UNIX shell for a lab assignment. Part of this involves storing a history of the past 10 commands, including the arguments passed. I'm storing each command as a C++ string, but the parts of the program that actually matter, and that I had no input in designing (such as execve) use char * and char ** arrays exclusively.
I can get the whole command from history, and then read the program to be invoked quite easily, but I'm having a hard time reading into an arguments array, which is a char *[40] array.
Below is the code for a program I wrote to simulate this behavior on a test string:
#include <sstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char *chars[40];
string test = "Hi how are you";
stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
string test_2;
testStream >> test_2;
if (testStream.fail())
{
break;
};
chars[i] = (char *)test_2.c_str();
i++;
}
for (int i=0; i < 4; i++)
{
cout << chars[i];
}
cout << "\n";
}
I get the feeling it has something to do with the array being declared as an array of pointers, rather than a multi-dimensional array. Am I correct?
This line:
chars[i] = (char *)test_2.c_str();
leaves chars[i] 'dangling' when you go back round the loop or fall off the end. This is because test_2.c_str() is only valid while test_2 is in scope.
You'd do better to do something like this:
#include <sstream>
#include <iostream>
#include <string>
#include <vector>
#include <memory>
int main()
{
std::vector <std::string> args;
std::string test = "Hi how are you";
std::stringstream testStream;
testStream << test;
int i = 0;
while (true)
{
std::string test_2;
testStream >> test_2;
if (testStream.fail())
break;
args.push_back (test_2);
i++;
}
auto char_args = std::make_unique <const char * []> (i);
for (int j = 0; j < i; ++j)
char_args [j] = args [j].c_str ();
for (int j = 0; j < i; ++j)
std::cout << char_args [j] << "\n";
}
Now your vector of strings remains in scope while you are building and using char_args.
Live demo

Use Strcpy_s to Copy Dynamically Allocated Char Array

I'm simply trying to copy what is in 'temp' into 'p' but the program crashes on the strcopy_s line. Am I missing some important rule?
#include <iostream>
#include <string>
#include <cstring>
using namespace std;
int main() {
char temp[100] = "Coolbeans";
int len = strlen(temp);
char* p = new char[len+1];
strcpy_s(p, len, temp);
for (int i = 0; i < len; i++)
cout << p[i] << endl;
for (int i = 0; i < len; i++)
cout << temp[i] << endl;
}
Praetorian hit it on the head. "The important rule you're missing is use std::string". Old C functions like strcpy_s are notoriously incredibly unreliable and that's the whole point of not doing it anymore. So don't do it. Use std::string.
The above code snippet result in "Debug Assertion failed" run time error.
strcpy_s(p, len, temp); //Expression:(L"Buffer is too small" &&0)
So the answer is strcpy_s(p, len+1, temp); will work fine in your case.

sorting array of strings one off

This code is supposed to make a array of strings, randomly order them, and then print the order. Unfortunately it adds a blank line in one of the spaces ( i think this is getline's doing). Any ideas how to fix that? I tried setting array [0] = NULL; it complains about operators...
#include <iostream>
#include <stdio.h>
#include <conio.h>
#include <time.h>
#include <string>
#include <cstdlib>
using std::cout;
using std::endl;
using namespace std;
void swap (string &one, string &two)
{
string tmp = one;
one = two;
two = tmp;
}
int rand_loc (int size)
{
return (rand() % size);
}
int main()
{
srand(time(NULL));
int size;
cin >> size;
string *array = new string[size];
//array[0] = NULL ;
for (int x = 0; x < size; x++)
{
getline(cin, array[x]);
}
//for (int x = 0; x < size; x++)
//{
// swap (array[rand_loc(size)], array[rand_loc(size)]);
//}
cout << endl;
for (int x = 0; x < size; x++)
{
//out << array[x] << endl;
int y = x + 1;
cout<<y<<"."<<" "<<array[x]<<endl;
}
delete[] array;
}
The first call to getline() will immediately hit the newline that the user entered after inputting size, and will therefore return an empty string. Try to call cin.ignore(255, '\n'); before the first call to getline(). This will skip up to 255 (an arbitrarily selected number) characters until a \n is encountered (and the newline will be skipped as well).
Edit: As #Johnsyweb and #ildjarn point out, std::numeric_limits<streamsize>::max() is a much better choice than 255.