String reverse program throws exception - c++

// ExampleCodes.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include<stdio.h>
#include<iostream>
using namespace std;
char* stringReverse(char* s)
{
char temp, *p,*q;
q = s;
while( *(++q));
for( p = s; p < --q; p++)
{
temp = *p;
*p = *q;
*q = temp;
}
return s;
}
int _tmain(int argc, _TCHAR* argv[])
{
stringReverse("StringReverse");
return 0;
}

You can't modify constant string literals.
stringReverse("StringReverse");
You could use a character array instead:
char str[] = "StringReverse";

String literals, like "StringReverse", are not allowed to be modified in C. Use an array:
char str[] = "StringReverse";
stringReverse(str);
Note that your stringReverse() function has undefined behaviour if you feed it a zero-length string.

You never allocated any memory for p. You can try p = new char[sizeof(s)];

Perhaps you should write something like this:
// in - string to reverse
// out - buffer for reversed string
// l - size of in
StringReverse(char* in, char* out, int l) {
for (int i=0;i<l;i++) {
out[l-(i+1)] = in[i];
}
}
*There is very very little to no speed difference between [] and *(p++) / *(p--)

Well I was going to clean up the awful source in the OP but instead I'll just post a cleaner version:
#include <stdio.h>
#include <string.h>
void reverse_string(char *s)
{
char *q = s + strlen(s);
for (char *p = s; p < --q; p++)
{
char temp = *p;
*p = *q;
*q = temp;
}
}
int main()
{
char s[] = "StringReverse";
reverse_string(s);
puts(s);
return 0;
}
I hope for your sake Amit that you're still a student.
Update0
This is actually pure C, so learn from and awe at its performance but don't start writing C++ like this.

Related

C++ Combining two zero terminated strings?

So I am doing a question where I have to join two zero terminated strings, the first contains a word, and the second is empty and twice the size of the original array. I was able to get this working using the following code
#include <stdio.h>
#include <iostream>
using namespace std;
int main()
{
char str1[] = "test";
char str2[(sizeof(str1)-1)*2];
char *p;
int count = 0;
for(p = str1; *p != 0; p++) {
str2[count] = *p;
count++;
}
cout << str2;
}
However I have to use a function with the following prototype
char *combine(char *a);
So I tried this
#include <stdio.h>
#include <iostream>
using namespace std;
char *copy_and_reverse(char *a) {
char str2[8];
int count = 0;
char* b = str2;
for(a; *a != 0; a++) {
str2[count] = *a;
count++;
}
return b;
}
int main()
{
char str1[] = "test";
char *a;
a = str1;
char* b = copy_and_reverse(a);
for(b; *b != 0; b++) {
cout << *b;
}
}
But it does not work (it is printing the string but it's printing a few random characters after it), I'm getting so confused with the pointers, can anyone help me out with this?
Edit: here is the question I am trying to answer
Write a function in C++ that takes as a char * style zero terminated string and returns a char* string twice the length of the input. The first half of the returned string should contain a copy of the contents of the original array. The second half of the string should contain the contents of the original string in reverse order.
The function should have the following prototype:
char *copy_and_reverse(char* a);
Note: you should not use any library functions (e.g from string.h).
There are two big problems in your copy_and_reverse code.
After copying the input string, you are not terminating the result. This means str2 is not a valid string. Fix:
str2[count] = '\0'; // after the loop
copy_and_reverse returns a pointer to a local variable (str2). After the function returns, all its local variables are gone, and main is dealing with an invalid pointer. To fix this, either use static memory (e.g. by declaring str2 as static or making it a global variable) or dynamic memory (allocate storage with new[] (or malloc())). Both approaches have their disadvantages.
Minor stuff:
variable; does nothing (see for (a; ...), for (b; ...)).
str2 isn't big enough for the final result. str1 is 5 bytes long ('t', 'e', 's', 't', '\0'), so char str2[8] is sufficient for now, but in the end you want to allocate length * 2 + 1 bytes for your result.
I believe that this will suit your needs:
#include <stdio.h>
#include <stdlib.h>
static char* copy_and_reverse(char* a);
static int strlen(char *c); // self-implemented
int main(void) {
char *a = "some string";
char *b = copy_and_reverse(a);
printf("%s", b);
free(b);
return 0;
}
static char* copy_and_reverse(char* a) {
int n = strlen(a);
char *b = new char[n * 2 + 1]; // get twice the length of a and one more for \0
for (int i = 0; i < n; ++i) { // does copying and reversing
b[i] = a[i];
b[i+n] = a[n-i-1];
}
b[2 * n] = '\0'; // null out last one
return b;
}
static int strlen(char *c) {
char *s = c;
while( *s++ );
return s-c-1;
}

EXC_BAD_ACCESS occurred when assign char with a poitner

EXC_BAD_ACCESS occurred in *str++ = *end;. What's wrong with this?
#include <iostream>
using namespace std;
int main() {
char *hello = "abcdefgh";
char c = 'c';
char *str = hello;
//printf("%s",str);
char * end = str;
char tmp;
if (str) {
while (*end) {
++end;
}
--end;
while (str < end) {
tmp = *str;
printf("hello:%s str:%c, end:%c\n", hello, *str, *end);
*str++ = *end;
*end-- = tmp;
}
}
return 0;
}
It is undefined behavior to attempt to alter a string literal. Change your code to the equivalent below, and you will see the issue:
const char *hello = "abcdefgh";
const char *str = hello;
const char * end = str;
So do you see why the line *str++ = *end; had a problem? You're attempting to write to a const area, and you can't do that.
If you want an even simpler example:
int main()
{
char *str = "abc";
str[0] = 'x';
}
Don't be surprised if this simple program produces a crash or segmentation fault when the
str[0] = 'x';
line is executed.
Unfortunately, string-literals did not have to be declared as const char* in C, and C++ brought this syntax over. So even though it looks like you are not using const, you are.
If you want the code to actually work, declare a writeable buffer, i.e. an array of char:
char hello[] = "abcdefgh";
char str[100];
strcpy(str, hello);
char end[100];
strcpy(end, str);
It seems like you're trying to reverse the string. It also looks like you're overcomplicating things.
C-style strings declared on the stack have to be declared as const char *, which means you can't change the characters as they are constant.
In C++ we use strings, and string iterators:
#include <iostream>
#include <string>
using std::string;
using std::reverse;
using std::swap;
using std::cout;
using std::endl;
int main(int argc, const char * argv[])
{
string hello("abcdefgh");
reverse(hello.begin(), hello.end());
cout << hello << endl;
return 0;
}
Manually:
static void reverse(std::string & str)
{
string::size_type b = 0, e = str.length() - 1, c = e / 2;
while(b <= c)
{
swap(str[b++], str[e--]);
}
}
Recursively:
static void reverse_helper(std::string & str,
string::size_type b,
string::size_type e)
{
if(b >= e)
return;
swap(str[b], str[e]);
reverse_helper(str, ++b, --e);
}
static void reverse(std::string & str)
{
reverse_helper(str, 0, str.length() - 1);
}

reverse a string using pointers

I have to admit, i have no idea how to use pointers, but I tried non the less. the problem with my program is that it shows the string in reverse, except for what was the first letter being missing and the entire string is moved one space forward with the first element being blank.
for example it show " olle" when typing "hello".
#include <iostream>
#include <string>
using namespace std;
string reverse(string word);
int main()
{
char Cstring[50];
cout<<"enter a word: ";
cin>>Cstring;
string results = reverse(Cstring);
cout <<results;
}
string reverse(string word)
{
char *front;
char *rear;
for (int i=0;i< (word.length()/2);i++)
{
front[0]=word[i];
rear[0]=word[word.length()-i];
word[i]=*rear;
word[word.length()-i]=*front;
}
return word;
}
The new code works perfectly. changed the strings to cstrings. the question technicaly asked for cstrings but i find strings easier so i work with strings then make the necesary changes to make it c string. figured out ho to initialize the rear and front as well.
#include <iostream>
#include <cstring>
using namespace std;
string reverse(char word[20]);
int main()
{
char Cstring[20];
cout<<"enter a word: ";
cin>>Cstring;
string results = reverse(Cstring);
cout <<results;
}
string reverse(char word[20])
{
char a='a';
char b='b';
char *front=&a;
char *rear=&b;
for (int i=0;i< (strlen(word)/2);i++)
{
front[0]=word[i];
rear[0]=word[strlen(word)-1-i];
word[i]=*rear;
word[strlen(word)-1-i]=*front;
}
return word;
}
char *front;
char *rear;
then later
front[0]=word[i];
rear[0]=word[strlen(word)-1-i];
Not good. Dereferencing uninitialized pointers invokes undefined behavior.
Apart from that, your code is overly complicated, it calls strlen() during each iteration (and even multiple times), which is superfluous, and the swap logic is also unnecessarily complex. Try using two pointers instead and your code will be much cleaner:
void rev_string(char *str)
{
char *p = str, *s = str + strlen(str) - 1;
while (p < s) {
char tmp = *p;
*p++ = *s;
*s-- = tmp;
}
}
The thing is, however, that in C++ there's rarely a good reason for using raw pointers. How about using std::reverse() instead?
string s = "foobar";
std::reverse(s.begin(), s.end());
inline void swap(char* a, char* b)
{
char tmp = *a;
*a = *b;
*b = tmp;
}
inline void reverse_string(char* pstart, char* pend)
{
while(pstart < pend)
{
swap(pstart++, pend--);
}
}
int main()
{
char pstring[] = "asfasd Lucy Beverman";
auto pstart = std::begin(pstring);
auto pend = std::end(pstring);
pend -= 2; // end points 1 past the null character, so have to go back 2
std::cout << pstring << std::endl;
reverse_string(pstart, pend);
std::cout << pstring << std::endl;
return 0;
}
you can also do it like this:
#include <iostream>
#include <cstring>
using namespace std;
string reverse(char word[20]);
int main()
{
char Cstring[20];
cout<<"enter a word: ";
cin>>Cstring;
string results = reverse(Cstring);
cout <<results;
}
string reverse(char word[20])
{
char a='a';
char b='b';
char *front=&a;
char *rear=&b;
for (int i=0;i< (strlen(word)/2);i++)
{
*front=word[i];
*rear=word[strlen(word)-1-i];
word[i]=*rear;
word[strlen(word)-1-i]=*front;
}
return word;
}
it successfully works on my system ,i.e. on emacs+gcc on windows 7
Taken from C How To Program Deitel & Deitel 8th edition:
void reverse(const char * const sPtr)
{
if (sPtr[0] == '\0')
return;
else
reverse(&sPtr[1]);
putchar(sPtr[0]);
}

Run time error reverse a string

I know return end is not correct, I am thinking about to use one of my pointer to go to the end, and then go back by the size of the string to return the reversed string. Is there a more efficient way of doing that? Also, more importantly, am I getting a run time error here? http://ideone.com/IzvhmW
#include <iostream>
#include <string>
using namespace std;
string Reverse(char * word)
{
char *end = word;
while(*end)
++end;
--end;
char tem;
while(word < end) {
tem = *word;
*word = *end;
*end = tem; //debug indicated the error at this line
++word;
--end;
}
return end;
}
int main(int argc, char * argv[]) {
string s = Reverse("piegh");
cout << s << endl;
return 0;
}
You're passing "piegh" to Reverse, which gets converted to a pointer to char. That pointer to char points into a read only string literal. Perhaps you meant to copy the string literal "piegh" before attempting to assign to it:
char fubar[] = "piegh";
string s = Reverse(fubar);
After all, how could you justify "piegh"[0] = "peigh"[4];?
What does this part of your code do?
while(*end)
++end; //Assuming you are moving your pointer to hold the last character but not sure y
--end; //y this one
while(word < end)// also i am not sure how this works
This code works and serves the same purpose
char* StrReverse(char* str)
{
int i, j, len;
char temp;
char *ptr=NULL;
i=j=len=temp=0;
len=strlen(str);
ptr=malloc(sizeof(char)*(len+1));
ptr=strcpy(ptr,str);
for (i=0, j=len-1; i<=j; i++, j--)
{
temp=ptr[i];
ptr[i]=ptr[j];
ptr[j]=temp;
}
return ptr;
}

C Function to reverse char array string [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Reversing a string in C
I'm currently switching from C++ to C programming for a project and I haven't done much with Char arrays as strings. I need a function that will read in a pointer to a char array and reverse it. I wrote this in C++, which is pretty easy using the string functions, but I'm a little confused on if there are functions or something else in C that is the best way to do this. Thanks, and I'm not necessarily looking for someone to completely finish the code, but to point me in the right direction. If it's simple one line something feel free, but don't do anything that makes you feel uncomfortable.
#include<stdio.h>
#include<string.h>
void reverseString(char *myString)
{
//reverse string here
}
int main(void)
{
char myString[] = "This is my string!";
reverseString(myString);
return 0;
}
Simplest way: Loop the string char by char and insert each char to another char array in the reverse order.
Or try this:
2)
void reverse_string(char str[])
{
char c;
char *p, *q;
p = str;
if (!p)
return;
q = p + 1;
if (*q == '\0')
return;
c = *p;
reverse_string(q);
while (*q != '\0') {
*p = *q;
p++;
q++;
}
*p = c;
return;
}
3)
if( strlen( str ) > 0 ) {
char* first = &str[ 0 ];
char* last = &str[ strlen( str ) - 1 ];
while( first < last ) {
char tmp = *first;
*first = *last;
*last = tmp;
++first;
--last;
4)
char* strrev( char* s )
{
char c;
char* s0 = s - 1;
char* s1 = s;
/* Find the end of the string */
while (*s1) ++s1;
/* Reverse it */
while (s1-- > ++s0)
{
c = *s0;
*s0 = *s1;
*s1 = c;
}
return s;
}