String Reversal using Recurrsion using char* - arrays

I want string reversed in-place using Recursion. Though this might be duplicate question but I don't understand error in my code below and I searched for answers before asking here.
#include "Reversal.h"
#include <iostream>
#include <cstdlib>
using namespace std;
int size = 10;
char* Reversal :: rever (char *str, int i, int j)
{
if (i>=j)
return str;
char a;
a = str[i];
str[i] = str[j];
str[j] = a;
rever(str, i+1, j-1);
}
int main()
{
Reversal obj;
char *ptr = new char[size];
char *reverse = new char[size];
cout << " Enter a string \n";
for (int i = 0; i < size-1; i++)
{
cin >> ptr[i];
}
reverse = obj.rever(ptr, 0, strlen(ptr)-1);
for (int k = 0; k < strlen(reverse)-1; k++)
{
cout << reverse[k];
}
return 0;
}
and Reversal.h file is
#ifndef REVERSAL_H_
#define REVERSAL_H_
class Reversal {
public:
Reversal();
char* rever(char*, int,int);
virtual ~Reversal();
};
#endif /* REVERSAL_H_ */

This code has quite a few problems. The first thing you need to decide is whether you are reversing your input string in place, or returning a pointer to a newly allocated string. Since it looks like you planned on filling a second array, let's stick with that:
void Reversal::rever(char* buf, char* str, int i, int j)
{
if (i>=j)
{
buf[strlen(str)] = '\0';
return;
}
buf[j] = str[i];
buf[i] = str[j];
rever(buf, str, i+1, j-1);
}
Called as:
obj.rever(reverse, str, 0, strlen(str)-1);
Note that I would not make this part of a class unless there is some other reason to do so (like if it were instead to return the reverse of a char* contained in the class), and since we are using C++ I would recommend using std::string instead of char*.

Related

Reverse string function not working properly

Here is my code. I just can't seem to figure it out. Sometimes i get no output, and sometimes i just get 3 random characters, regardless of how long the entered string is.
#include <stdio.h>
#include <math.h>
#include <string.h>
void reverse(char* array, int numberOfChars);
int main()
{
char string[250];
int length;
printf("Enter a string: ");
gets(string);
printf("How long is the string:");
scanf("%d", &length);
reverse(string, length);
printf("Reversed string is: %s\n"), string;
return 0;
}
void reverse(char *userArray, int numberOfChars)
{
char temp;
int fromEnd = 0, fromStart = 0;
fromEnd = numberOfChars;
while (fromStart < fromEnd)
{
temp = userArray[fromStart];
userArray[fromStart] = userArray[fromEnd];
userArray[fromEnd] = temp;
fromStart++;
fromEnd--;
}
}
I really dread asking these questions here but I can't seem to fix it...
Any help appreciated
Conceptually you need to swap the ends until you are left with a string of length 0 or 1. You don't need to test for the length of the remaining portion of the string after each iteration however, because it can be shown that exactly length/2 swaps will be needed.
void reverse (char *s)
{
size_t length = strlen (s);
for (size_t i = 0; i < length / 2; i++) {
char tmp;
tmp = s[i];
s[i] = s[length - 1 - i];
s[length - 1 - i] = tmp;
}
}
There is no need to complicate things like that, try this:
#include <stdio.h>
int main(void){
char *src = "Michi";
char dest[256];
int i=-1,j=0;
while(src[++i]!='\0');
while(i>=0){
dest[j++] = src[--i];
}
dest[j]='\0';
printf("Your new string is: %s",dest);
return 0;
}
Output:
Your new string is: ihciM
This is probably what you need:
#include<stdio.h>
#include<string.h>
void reverse(char *ptr);
int main(void) {
char src[256] = "Michi";
reverse(src);
printf("Your new string is: %s",src);
return (0);
}
void reverse(char *src){
char dest;
size_t i, j = 0;
i = 0;
j = strlen(src) - 1;
while (i < j) {
dest = src[i];
src[i] = src[j];
src[j] = dest;
i++;
j--;
}
}
don't use gets(),use fgets().To reverse strings,you don't need to pass number of characters,since strings in C are null-terminated.check this very simple function:
#include <stdio.h>
void reverse(char *_Str);
int main(void)
{
char str[] = "Hello Buddy";
reverse(str);
printf("%s\n",str);
return 0;
}
void reverse(char *_Str)
{
char tmp,*_b,*_e;
_b = _e = _Str;
while(*_e) _e++;
_e--;
while(_b < _e)
{
tmp = *_b;
*_b++ = *_e;
*_e-- = tmp;
}
}
Well the very important line you missed is assigning the null character. And do not take the length of your string as an input from the user. use the function some_integer=strlen(stringname); This will return the length of your stringname and assign it to some_integer. Your function to reverse the string should be as
void reverse(char *userarray) // no need of a second argument. Do not trust your users.
{
char temp;
int fromEnd,fromStart = 0; /
fromEnd = strlen(userarray)-1; // here the length of your string is assigned to fromEnd.
while (fromStart < fromEnd)
{
temp = userArray[fromStart];
userArray[fromStart] = userArray[fromEnd];
userArray[fromEnd] = temp;
fromStart++;
fromEnd--;
}
userarray[strlen(userarray)-1]='\0'; //You missed this line (very important)
}
And chek your printf statement.
It should be
printf("Your reversed string is %s \n",string);
not
printf("Your reversed string is %s \n"),string;
I belive this will work. Check it and let me know if it works for you.
Incorrect code. The needed string for the printf() is not in the function. #M Oehm
/// printf("Reversed string is: %s\n"), string;
printf("Reversed string is: %s\n", string);
Also original code can easily wipe out the string terminating null character '\0'. Better to use strlen(string) rather than ask the user for the length.
Likely should use - 1 as commented by #WalterM. It is unclear what values OP is using.
// fromEnd = numberOfChars;
if (numberOfChars <= 0) return;
fromEnd = numberOfChars - 1;
Answers I have seen so far depend on int well addressing all elements of a string. size_t is the right approach as int may be too small.
Many answers would fail on a string such as "".
So here is another contribution without those restrictions.
#include <string.h>
#include <stdio.h>
char *str_revese_inplace(char *s) {
char *left = s;
char *right = s + strlen(s);
while (right > left) {
right--;
char t = *right;
*right = *left;
*left = t;
left++;
}
return s;
}
void stest(const char *s) {
char t[strlen(s) + 1];
// or char t[100];
strcpy(t, s);
printf("'%s' --> '%s'\n", s, str_revese_inplace(t));
}
int main(void) {
stest("123");
stest("12");
stest("1");
stest("");
return 0;
}
Output
'123' --> '321'
'12' --> '21'
'1' --> '1'
'' --> ''

How to transform a block of strings to an array of strings

I've got a block of strings, say "aaa\0bbbb\0ccccccc\0"
and I want to turn them into an array of strings.
I've tried to do so using the following code:
void parsePath(char* pathString){
char *pathS = malloc(strlen(pathString));
strcpy(pathS, pathString);
printf(1,"33333\n");
pathCount = 0;
int i,charIndex;
printf(1,"44444\n");
for(i=0; i<strlen(pathString) ; i++){
if(pathS[i]=='\0')
{
char* ith = malloc(charIndex);
strcpy(ith,pathS+i-charIndex);
printf(1,"parsed string %s\n",ith);
exportPathList[pathCount] = ith;
pathCount++;
charIndex=0;
}
else{
charIndex++;
}
}
return;
}
exportPathList is a global variable defined earlier in the code by
char* exportPathList[32];
when using that function exportPathList[i] contains garbage.
What am I doing wrong?
The answer to this SO question:
Parse string into argv/argc
deals with a similar issue, you might have a look.
You need to know how many strings are there or agree for an "end of strings". The simplest would be to have an empty string at the end:
aaa\0bbbb\0ccccccc\0\0
^^
P.S. is this homework?
First of all, since your strings are delimited by a null char, '\0', strlen will only report the size of the string up to the first '\0'. strcpy will copy until the first null character as well.
Further, you cannot know where the input string ends with this information. You either need to pass in the whole size or, for example, end the input with double null characters:
#include <stdio.h>
#include <string.h>
void parsePath(const char* pathString){
char buf[256]; // some limit
while (1) {
strcpy(buf, pathString);
pathString+=strlen(buf) + 1;
if (strlen(buf) == 0)
break;
printf("%s\n", buf);
}
}
int main()
{
const char *str = "aaa\0bbbb\0ccccccc\0\0";
parsePath(str);
return 0;
}
And you need some realloc's to actually create the array.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 16
char* exportPathList[MAXSIZE] = {0};
size_t pathCount = 0;
void parsePath(char* pathString){
char *ptop, *pend;
ptop=pend=pathString;
while(*ptop){
while(*pend)++pend;
exportPathList[pathCount++]=strdup(ptop);
pend=ptop=pend+1;
}
}
int main(){
char textBlock[]= "aaa\0bbbb\0ccccccc\0";
//size_t size = sizeof(textBlock)/sizeof(char);
int i;
parsePath(textBlock);
for(i=0;i<pathCount;++i)
printf("%s\n", exportPathList[i]);
return 0;
}
The solution I've implemented was indeed adding double '\0' at the end of the string and using that in order to calculate the number of strings.
My new implementation (paths is the number of strings):
void parsePath(char* pathString,int paths){
int i=0;
while (i<paths) {
exportPathList[i] = malloc(strlen(pathString)+1);
strcpy(exportPathList[i], pathString);
pathString+=strlen(pathString);
i++;
}
}
I'd like to thank everyone that contributed.
My Implementation looks like this -> it follows the idea of argv and argc in a main funtion:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char **args = (char**)malloc(100*sizeof(char));
char buff[100], input_string[100], letter;
for(int i = 0; i < 100; i++){
buff[i] = '\0';
input_string[i] = '\0';
}
for(int i = 0; (letter = getchar())!='\n'; i++){
input_string[i] = letter;
}
int args_num = 0;
for(int i = 0, j = 0; i < 100;i++){
if((input_string[i] == ' ')||(input_string[i]=='\0')){
//reset j = 0
j = 0;
args[args_num] = malloc(strlen(buff+1));
strcpy(args[args_num++],buff);
for(int i = 0; i < 100; i++)buff[i] = '\0';
}else buff[j++] = input_string[i];
}
for(int i = 0; i < args_num; i++){
printf("%s ",args[i]);
}
}
-> Every single word in your string can then be accessed with args[i]

Printing Array of Strings

I'm parsing a text file:
Hello, this is a text file.
and creating by turning the file into a char[]. Now I want to take the array, iterate through it, and create an array of arrays that splits the file into words:
string[0] = Hello
string[1] = this
string[2] = is
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "TextReader.h"
#include <ctype.h>
void printWord(char *string) {
int i;
for (i = 0; i < strlen(string); i ++)
printf("%c", string[i]);
printf("\n");
}
void getWord(char *string) {
char sentences[5][4];
int i;
int letter_counter = 0;
int word_counter = 0;
for (i = 0; i < strlen(string); i ++) {
// Checks if the character is a letter
if (isalpha(string[i])) {
sentences[word_counter][letter_counter] = string[i];
letter_counter++;
} else {
sentences[word_counter][letter_counter + 1] = '\0';
word_counter++;
letter_counter = 0;
}
}
// This is the code to see what it returns:
i = 0;
for (i; i < 5; i ++) {
int a = 0;
for (a; a < 4; a++) {
printf("%c", sentences[i][a]);
}
printf("\n");
}
}
int main() {
// This just returns the character array. No errors or problems here.
char *string = readFile("test.txt");
getWord(string);
return 0;
}
This is what it returns:
Hell
o
this
is
a) w
I suspect this has something to do with pointers and stuff. I come from a strong Java background so I'm still getting used to C.
With sentences[5][4] you're limiting the number of sentences to 5 and the length of each word to 4. You'll need to make it bigger in order to process more and longer words. Try sentences[10][10]. You're also not checking if your input words aren't longer than what sentences can handle. With bigger inputs this can lead to heap-overflows & acces violations, remember that C does not check your pointers for you!
Of course, if you're going to use this method for bigger files with bigger words you'll need to make it bigger or allocate it dymanically.
sample that do not use strtok:
void getWord(char *string){
char buff[32];
int letter_counter = 0;
int word_counter = 0;
int i=0;
char ch;
while(!isalpha(string[i]))++i;//skip
while(ch=string[i]){
if(isalpha(ch)){
buff[letter_counter++] = ch;
++i;
} else {
buff[letter_counter] = '\0';
printf("string[%d] = %s\n", word_counter++, buff);//copy to dynamic allocate array
letter_counter = 0;
while(string[++i] && !isalpha(string[i]));//skip
}
}
}
use strtok version:
void getWord(const char *string){
char buff[1024];//Unnecessary if possible change
char *p;
int word_counter = 0;
strcpy(buff, string);
for(p=buff;NULL!=(p=strtok(p, " ,."));p=NULL){//delimiter != (not isaplha(ch))
printf("string[%d] = %s\n", word_counter++, p);//copy to dynamic allocate array
}
}

Replacing character in a string [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the function to replace string in C?
I am trying to replace a certain character in my string with multiple characters. Here is an example of what I am trying to do.
Say I have the string "aaabaa"
I want to replace all occurrences of the character "b" with 5 "c"s.
So when I am done, "aaabaa" becomes "aaacccccaa"
I have written the following code:
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
int i, j;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
s[i+j] = 'c';
}
}
}
printf("%s\n", s);
}
My output from this function is "aaaccccc". It appears that it just overwrites the last two a's with the c's. Is there any way I would have it so that these last couple of a's dont get overwritten?
If you want to do this in general, without worrying about trying to size your buffers, you should malloc a new string just large enough to hold the result:
/* return a new string with every instance of ch replaced by repl */
char *replace(const char *s, char ch, const char *repl) {
int count = 0;
const char *t;
for(t=s; *t; t++)
count += (*t == ch);
size_t rlen = strlen(repl);
char *res = malloc(strlen(s) + (rlen-1)*count + 1);
char *ptr = res;
for(t=s; *t; t++) {
if(*t == ch) {
memcpy(ptr, repl, rlen);
ptr += rlen;
} else {
*ptr++ = *t;
}
}
*ptr = 0;
return res;
}
Usage:
int main() {
char *s = replace("aaabaa", 'b', "ccccc");
printf("%s\n", s);
free(s);
return 0;
}
Your problem is that you replace the "ccccc" into the original string thus overwriting the remaining characters after what you wish to replace... You should copy into a new string and keep track of two indices - one in each.
And be happy that you declared char s[20] larger than the size of your original string plus the replace values, as otherwise you'd have created a buffer overflow vulnerability in your critical login system :-)
Cheers,
It is necessary to declare a second char array. In below code it just copies content of array s to s1 when condition fails.
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
char s1[1024];
int i, j, n;
for (i=0, n = 0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
s1[n] = 'c';
n++;
}
}
else
{
s1[n] = s[i];
n++;
}
}
s1[n] = '\0';
printf("%s\n", s1);
}
You can use a different variable
#include <stdio.h>
#include <string.h>
int main(void)
{
char s[20] = "aaabaa";
char temp[20]="";
int i, j,k;
k=0;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
for (j=0; j<5; j++)
{
temp[k] = 'c';
k++;
}
}
else
{
temp[k]=s[i];
k++
}
}
printf("%s\n", temp);
}
#include <stdio.h>
#include <string.h>
int main(void)
{
char temp[20];
char s[20] = "aaabaa";
int i, j;
for (i=0; s[i]!= '\0'; i++)
{
if (s[i] == 'b')
{
strcpy(temp,s[i+1]); //copy rest of the string in this case 'aa'
for (j=0; j<5; j++)
{
s[i+j] = 'c';
}
s[i+j] = '\0'; // here we get s = "aaaccccc"
strcat(s,temp); // concat rest of the string (temp = "aa") after job is done.
// to this point s becomes s = "aaacccccaa"
}
}
printf("%s\n", s); //s = "aaacccccaa".
}
here we are using a buffer (temp) to store the rest of the string after our to be replaced character.
after the replacement is done we append it to the end.
so we get s = "aaacccccaa"
Well, if you're going to dynamically allocate the array, you will probably have to allocate a second array. This is necessary because your string s only has a fixed amount of memory allocated.
So, instead of tryig to overwrite the characters in your for loop, I would suggest incrementing a counter that told you how big your new array has to be. Your counter should start off as the size of your original string and increment by 4 each time an instance of 'b' is found. You should then be able to write a function that appropriately copies the modified string over to a new char buffer of size[counter], inserting 5 c's every time a 'b' is being found.
Use this function :
char *replace(char *st, char *orig, char *repl) {
static char buffer[4096];
char *ch;
if (!(ch = strstr(st, orig)))
return st;
strncpy(buffer, st, ch-st);
buffer[ch-st] = 0;
sprintf(buffer+(ch-st), "%s%s", repl, ch+strlen(orig));
return buffer;
}
for your case : printf("%s\n", replace(s,"b","ccccc"));

Help with reversing a string in C

I am trying to reverse a character string in C
Here is what I have
void reverse(char str[]) {
int i = 0;
int length;
// Get string length
for (i = 0; str[i] != '\0' ; ++i) {
length = i;
}
char reversed[1000];
int j;
j = 0;
// Reverse it
for (j = 0; j < length ; ++j) {
reversed[j] = str[length - j];
}
}
I know that reversed contains the string reversed, but I'm not sure how to modify the original str without throwing away data I need.
I also don't know how to set strto reversed without looping again.
Would it be acceptable to do another...
int m;
m = 0;
for (m = 0; m < length ; ++m) {
str[j] = reversed[j];
}
Usually I'd say this many loops smells, but I'm also still quite unfamiliar with the language so I'm not sure...
Update
Thanks for all the answers guys, and I appreciate the edits too!
I ended up going with this...
int main() {
char str[] = "Reverse me!";
int length;
for (length = 0; str[length] != '\0'; length++) {
}
printf("length => %d chars\n", length);
int j, k;
char c;
for (j = 0, k = length - 1; j < k; j++, k--) {
c = str[k];
str[k] = str[j];
str[j] = c;
}
printf("reversed => %s\n", str);
return 0;
}
Some things I now know...
There is a strlen() like in PHP. However, it has not been discussed in the book yet, plus I need to get familiar with null terminated strings.
A for loop can assign and do multiple things that are comma separated. I never knew this!
So asking was worthwhile :)
You want to do an in-place reversal. Here's a standard algorithm:
// taken from The C Programming Language
// by Brian Kernighan and Dennis Ritchie (K&R)
void reverse(char s[])
{
int c, i, j;
for (i = 0, j = strlen(s)-1; i < j; i++, j--) {
c = s[i];
s[i] = s[j];
s[j] = c;
}
}
Note that strlen pretty much replaces your original first loop. It's one of the many standard string manipulation routines available from string.h.
See also
Wikipedia/In-place algorithm
Wikipedia/string.h
Wikipedia/C Standard Library
You can use either of the two methods below, depending on whether you're comfortable with pointers or not. It will also be worthwhile looking at them side-by-side when you satrt learning about pointers so you can better understand how they map to each other.
This is a full program for testing purposes:
#include <stdio.h>
#include <string.h>
// The pointer version.
void reverse1 (char *str) {
char t; // Temporary char for swapping.
char *s = str; // First character of string.
char *e = &(s[strlen(s)-1]); // Last character of string.
// Swap first and last character the move both pointers
// towards each other. Stop when they meet or cross.
while (s < e) {
t = *s;
*s++ = *e;
*e-- = t;
}
}
// The array version.
void reverse2 (char *str) {
char t; // Temporary char for swapping.
int s = 0; // First character of string.
int e = strlen(str)-1; // Last character of string.
// Swap first and last character the move both pointers
// towards each other. Stop when they meet or cross.
while (s < e) {
t = str[s];
str[s++] = str[e];
str[e--] = t;
}
}
int main (void) {
char x[] = "This is a string for reversing.";
printf ("Original: [%s]\n", x);
reverse1 (x);
printf ("Reversed: [%s]\n", x);
reverse2 (x);
printf (" Again: [%s]\n", x);
return 0;
}
and the output is:
Original: [This is a string for reversing.]
Reversed: [.gnisrever rof gnirts a si sihT]
Again: [This is a string for reversing.]
Comments on your code:
void reverse(char str[]) {
int i = 0;
int length;
// Get string length
for (i = 0; str[i] != '\0' ; ++i) {
length = i;
}
Rather than copying the i to length every time you could just wait until the end.
size_t len = 0; // size_t is an unsigned integer that is large enough to hold the sizes
// of the biggest things you can have (32 bits on 32 bit computer,
// 64 bits on a 64 bit computer)
char * s = str;
while (*s) {
len++;
s++;
}
Though the compiler would probably be able to make this optimization for you.
You should know, though, that there is a standard string function strlen ( #include <string.h> )which will measure the length of a char string using the same general algorithm (look for the end) but is usually optimized for the target processor.
len = strlen(str);
Your code again:
char reversed[1000];
Using big arrays are good for learning and simple examples, but you can also allocate memory dynamically based on the size you now know you need. The standard function for doing this is malloc which is in stdlib.h (also in malloc.h). Memory allocated with this function should also be freed, though.
int * p = malloc( 8 * sizeof(int) ); // allocate an array of 8 ints
/* ... work on p ... */
free(p);
/* ... don't access the memory pointed to by p anymore ... */
p = 0;
There are also other functions in the malloc family. There's calloc, which allocates memory and clears sets it to 0. There is also a function called strdup (which isn't in standard C, but is very widely available in string.h) which takes a string and allocates a duplicate of it. It is really just:
char * strdup(const char * str) {
size_t len = strlen(str);
char * s = malloc(len+1);
if (!s) {
return s;
}
return strcpy(s,str); // This could have been memcpy since you know the size
// and memcpy might have been faster on many processors
}
Another useful memory allocation function is alloca (not in the C standard, but widely available and similar functionality is available with variable length arrays in C99). It is great, but works differently from malloc. It allocates memory that is only useable until the current function returns because this memory is allocated in the same way as memory for local variables (from the stack).
More of your code:
int j;
j = 0;
// Reverse it
for (j = 0; j < length ; ++j) {
reversed[j] = str[length - j];
}
The code:
void reverse_in_place(char * str, size_t len) {
size_t i, j;
for (i = 0, j = len - 1; i < j ; i++, j--) {
char a = str[i];
char z = str[j];
str[i] = z;
str[j] = a;
}
}
should swap the order of the string without making a copy of it. For strings with odd length it won't try to swap the middle char with itself.
Reversing a string in C using pointers
#include<stdio.h>
char *srcptr = "Hello!";
char *destptr;
unsigned int length = 0;
void main(void)
{
while(*(ptr++) != '\0')
{
length++;
}
//at the end of while loop, pointer points to end of string
while(length--)
{
*destptr++ = *ptr--;
}
//append null at the end
*destptr = '\0';
printf("%s",ptr);
}

Resources