Reverse a string of any length using pointers in C [duplicate] - c

This question already has answers here:
How do you reverse a string in place in C or C++?
(21 answers)
How to read unlimited characters in C
(3 answers)
Closed 9 years ago.
I was just browsing through some interview questions and found this code to reverse a string using pointers. But I see that here they have defined char string[100] which limits the string length. I am not so good at C. How do I modify the same to make it a string of any length?
#include<stdio.h>
int string_length(char*);
void reverse(char*);
main()
{
char string[100];
printf("Enter a string\n");
gets(string);
reverse(string);
printf("Reverse of entered string is \"%s\".\n", string);
return 0;
}
void reverse(char *string)
{
int length, c;
char *begin, *end, temp;
length = string_length(string);
begin = string;
end = string;
for ( c = 0 ; c < ( length - 1 ) ; c++ )
end++;
for ( c = 0 ; c < length/2 ; c++ )
{
temp = *end;
*end = *begin;
*begin = temp;
begin++;
end--;
}
}
int string_length(char *pointer)
{
int c = 0;
while( *(pointer+c) != '\0' )
c++;
return c;
}

Instead of static array use dynamic memory allocation: char *tab = malloc(n * sizeof(char)) where n is some variable representing desired length.

You can use malloc() for this purpose if you want the size to be decided/inputted by the user at runtime.
malloc()

Dynamic memory allocation is the solution..
Take a pointer to the string and allocate the memory dynamically.. this allocates at run time..
This will solve your problem..
char *str;
str = (char*)malloc(n *sizeof(char));
NOTE: typecasting is optional in C and 'n' here is the required length.(can be user input).

Related

Allocating memory to user input using malloc [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I am trying to dynamically allocate memory for this C program I have constructed which takes a single string input and reverses it then prints the reversed output. I am very new to C and am unsure on how to use malloc to allocate memory for specified user input. This is the current code I have, we are running these programs in linux, using gcc code.c -o code to compile. Where the file is named code.c
int main(void)
{
char input[256];
char temp;
int i = 0, j = 0;
scanf("%s", input);
j = strlen(input) - 1;
while (i < j)
{
temp = input[j];
input[j] = input[i];
input[i] = temp;
i++;
j--;
}
printf("Reverse = %s", input);
return 0;
}
For a malloc implementation you just need to replace
char input[256];
with
char* input = malloc(256);
if(input == NULL){
//uppon bad allocation NULL will be returned by malloc
perror("malloc");
return EXIT_FAILURE;
}
Since malloc needs the allocated space in bytes normally you would multiply the needed space by the type of variable:
char *input = malloc(256 * sizeof *input);
but, since the size of a char is always 1 byte, in this case you won't need it.
The rest of the code can be the same, then after you use input you can/should free the allocated memory:
free(input);
You will need to #include <stdlib.h>.
Side note:
To avoid buffer overflow it's recommmended that you define a maximum size for scanf specifier which sould be at most the size of the buffer:
scanf("%255s", input);
or to also parse spaces:
scanf("%255[^\n]", input);
Notice that there is one less space, which is reserved for the null terminator, automatically added by scanf and mandatory for the char array to be treated as a string.
Once you get a string from user, you can allocate memory like this.
malloc() returns a pointer to allocated memory, or NULL if it failed.
size_t input_len = strlen(input);
char* mem_data = malloc(input_len + 1); // +1 for null-terminate
if(!mem_data)
{
// failed to allocate memory. do dome error process
}
Following code is copying input reversely to the allocated memory.
int i;
for (i = 0; i < input_len; ++i)
{
mem_data[i] = input[input_len - i - 1];
}
mem_data[input_len] = 0; // null terminate
printf("Reverse = %s", mem_data);
Remember, dynamically allocated memory should be free()d after use.
free(mem_data); // never forget to free memory when you finished using.
To dynamically allocate space in c you need to know beforehand exactly how much space you want to allocate. So, allocate space exactly same size as input string, you need to take length of the string as input.
Sample code will be like below:
int n;
char* input;
int main(){
scanf("%d",&n);
input= (char*)malloc((n+1)*sizeof(char));
scanf("%s",input);
return 0;
}
You can read about dynamic memory allocation here https://www.geeksforgeeks.org/dynamic-memory-allocation-in-c-using-malloc-calloc-free-and-realloc/
The approach that is more often used in books on C for beginners is writing a function that reads character by character from the input stream and reallocates memory dynamically when a new character is read.
Something like the function shown in this demonstrative program below
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * getline( size_t n )
{
char *s = NULL;
if ( n != 0 )
{
s = malloc( sizeof( char ) );
size_t i = 0;
for ( int c; i < n - 1 && ( c = getchar() ) != EOF && c != '\n'; ++i )
{
s = realloc( s, i + 2 );
if ( s == NULL ) break;
s[i] = c;
}
if ( s ) s[i] = '\0';
}
return s;
}
char * reverse( char *s )
{
if ( *s != '\0' )
{
for ( size_t i = 0, j = strlen( s ); i < --j; i++ )
{
char c = s[i];
s[i] = s[j];
s[j] = c;
}
}
return s;
}
int main(void)
{
const size_t N = 256;
printf( "Enter a string (no more than %zu symbols): ", N );
char *s = getline( N );
if ( s ) printf( "The reversed string is \"%s\"\n", reverse( s ) );
free( s );
return 0;
}
The program output might look like
Enter a string (no more than 256 symbols): Hello Mgert33
The reversed string is "33tregM olleH"

compiler does not allow me to edit the passed string [duplicate]

This question already has answers here:
Why do I get a segmentation fault when writing to a "char *s" initialized with a string literal, but not "char s[]"?
(19 answers)
Closed 5 years ago.
I looked around and I could not find a solution of my problems in other question. For some reason, then I get segmentation fault when I run my program and it seems to be because i am changing the give string. I tried passing a pointer to a char pointer and edit that, but to no avail.
what I get:
before: juanpablo
Segmentation fault (core dumped)
My code:
void rm_char(char* word, int pos){
printf("before: %s\n", word);
int len = strlen(word);
int i;
i = pos;
while(word[i+1] != '\0'){
word[i] = word[i+1];
i++;
}
word[i] = '\0';
printf("after: %s\n", word);
}
int main(void){
rm_char("juanpablo", 2);
}
From the C Standard (6.4.5 String literals)
7 It is unspecified whether these arrays are distinct provided their
elements have the appropriate values. If the program attempts to
modify such an array, the behavior is undefined.
To escape the error you could call the function like
char s[] = "juanpablo";
rm_char( s, 2 );
Take into account that it is better to use type size_t instead of the type int for the second parameter and the variable len declared like
int len = strlen(word);
is not used in the function.
The function should be declared like
char * rm_char(char* word, size_t pos);
Here is a demonstrative program
#include <stdio.h>
#include <string.h>
char * rm_char(char *word, size_t pos)
{
size_t n = strlen( word );
if ( pos < n )
{
//memmove( word + pos, word + pos + 1, n - pos );
do
{
word[pos] = word[pos+1];
} while ( word[pos++] );
}
return word;
}
int main(void)
{
char word[] = "juanpablo";
puts( word );
puts( rm_char( word, 2 ) );
return 0;
}
Its output is
juanpablo
junpablo

How to dynamically allocate a string using function?

I am trying to allocate a dynamic string by accepting it from user. I want to do it using a function. I am trying to implement the following code, but it is not working properly.
#include<stdio.h>
#include<stdlib.h>
int string(char *str)
{
char c;
int i=0,j=1;
str = (char*)malloc(sizeof(char));
printf("Enter String : ");
while(c!='\n')
{
c = getc(stdin); //read the input from keyboard standard input
//re-allocate (resize) memory for character read to be stored
*str = (char*)realloc(str,j*sizeof(char));
*str[i] = c; //store read character by making pointer point to c
i++;
j++;
}
str[i]='\0'; //at the end append null character to mark end of string
printf("\nThe entered string is : %s",str);
return j;
}
int main()
{
int len;
char *str=NULL;
len=string(str);
printf("\nThe entered string is : %s and it is of %d length.",str,len);
free(str);
return 0;
}
A number of issues:
memory size is one too small.
while(c!='\n') first test c even though it is uninitialized.
string() should pass the address of a char * as in string(char **)
Better to use size_t rather than int when working with strlen().
Minor:
EOF is not detected. Use int c rather than char c to aid in detection.
Certainly inefficient to realloc() each loop.
Casting of malloc()/realloc() unnecessary.
Good to check for out-of-memory.
Use int main(void) rather than int main() for portability.
size_t string(char **str) {
assert(str);
int c;
size_t i = 0;
size_t size = 0;
*str = NULL;
printf("Enter String : ");
while((c = getc(stdin)) !='\n' && c != EOF) {
if (i == size) {
size *= 2 + 1; // double the size each time
*str = realloc(*str, size);
assert(*str);
}
(*str)[i] = c; // store read character by making pointer point to c
i++;
}
*str = realloc(*str, i+1); // right-size the string
assert(*str);
(*str)[i] = '\0'; // at the end append null character to mark end
printf("\nThe entered string is : %s",*str);
return i;
}
You need to pass a referejce to a pointer (int string(char **str)) because you're changing the value of str inside the function.
In main you should call string(&str)

C reversing a String [duplicate]

This question already has answers here:
Segmentation fault occurring when modifying a string using pointers?
(8 answers)
Closed 9 years ago.
help me.. why this C program doesnt reverse the string ?
it crashes... but when i use a character array the code seems to work fine..but the moment i use a pointer to a string..its giving goosebumps...help me solve this..
#include<stdio.h>
#include<conio.h>
#include<string.h>
int main(){
char *String="gokul";
char *Begin =String;
char *End = String + strlen(String) - 1;
char TempChar = '\0';
while (Begin < End)
{
TempChar = *Begin;
*Begin = *End;
*End = TempChar;
Begin++;
End--;
}
puts(String);
}
The problem is that String is pointing to a string literal, which is in read-only memory. You can still use a pointer for String, but it has to point to memory that can be modified.
char gokul[] = "gokul";
char *String = gokul;
Edit to address some minor issues.
There is no need to include the non-standard header conio.h in your program.
Your code does not handle the case where String is NULL.
Your loop is technically incorrect if String is an empty string, since End would point before the string.
main() should return a value, since it is declared to do so. 0 indicates success. Newer C compilers will know that the latest C Standard allows a program to hit the end of main() without return to mean to implicitly return a 0 for you.
#include<stdio.h>
#include<string.h>
int main(){
char gokul[] = "gokul";
char *String=gokul;
if (String && *String) {
char *Begin =String;
char *End = String + strlen(String) - 1;
char TempChar = '\0';
while (Begin < End)
{
TempChar = *Begin;
*Begin = *End;
*End = TempChar;
Begin++;
End--;
}
puts(String);
}
return 0;
}

How can I find the length of a C string without using strlen?

If I want to know the length of the string without using standard libraries and the array in the program. How am I supposed to find the length?
You should iterate a C string until reaching to \0
#include <stdio.h>
int my_str_len(char *s)
{
int len;
char *ptr = s;
for (len = 0; *ptr; ptr++, len++)
// nothing
;
return len;
}
int main()
{
char str[] = "Hello";
printf("%i\n", my_str_len(str));
return 0;
}
print that string using printf
int count = printf("%s", str);
printf returns the number of characters printed.

Resources