reverse string in c incorrect output - c

I was writing a program to reverse an entered string in C and my code is :
#include<stdio.h>
#include<string.h>
void main()
{
int sz;
printf("Enter the size of the string : ");
scanf("%d",&sz);
char str[sz];
gets(str);
printf("Enter the string : \n");
gets(str);
char str1[sz];
int i =0;
--sz;
for(i=0;i<=sz;i++)
{
str1[sz-i]=str[i];
}
printf("%s",str1);
}
well this program is giving an weird output for string sizes 8,9 and 10
for size 8 the reversed string is being printed followed by a space and 2 garbage characters,for size 9 the reversed string is being printed followed by 2 garbage characters and for size 10 the reversed string is being printed by a garbage character and for other string sizes the program is running properly. why is this happening?

Note:
It is not smart to try to limit the input string by asking the user, the user can still write string with length greater/ less
Reading string from console does by default not allow spaces
First option:
Read a string of a static size:
char original[5];
scanf("%5s", original); // String containing 5 chars
Second option:
Read a string of variable size:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
// Length of String
unsigned expected;
printf("Enter the length of the string: ");
scanf("%u", &expected);
char *temp; // Warning: Uninitialized
// Get string
printf("Enter the string: ");
scanf("%s", temp);
unsigned actual = strlen(temp);
unsigned length = actual > expected ? expected : actual;
char *string = (char *) malloc(length * sizeof(char));
char *reverse = (char *) malloc(length * sizeof(char));
// Trim string to proper size
for (int i = 0; i < length; i++) {
string[i] = temp[i];
}
// Reverse string
for (int i = 0, j = length - 1; i <= j; i++) {
reverse[i] = string[j - i];
}
// Print Strings
printf("%s", string);
printf("\n%s", reverse);

Related

My ouput for C differs from compiler to compiler

I am writing a function longestStrInAr() that takes in an array of strings str and size (>0) as parameters, and returns the longest string and also the length of the longest string.
If two or more strings have the same longest string length, then the first appeared string will be
returned to the calling function.
This is the main function:
#include <stdio.h>
#include <string.h>
#define N 20
char *longestStrInAr(char str[N][40], int size, int *length);
int main()
{
int i, size, length;
char str[N][40], first[40], last[40], *p, *result;
char dummychar;
printf("Enter array size: \n");
scanf("%d", &size);
scanf("%c", &dummychar);
for (i=0; i<size; i++) {
printf("Enter string %d: \n", i+1);
fgets(str[i], 40, stdin);
if (p=strchr(str[i],'\n')) *p = '\0';
}
result = longestStrInAr(str, size, &length);
printf("longest: %s \nlength: %d\n", result, length);
return 0;
}
This is the function I have to write:
char *longestStrInAr(char str[N][40], int size, int *length)
{
int i,j, len;
*length =0;
char *longstr;
for (i = 0; i< size; i++){
j = 0;
len = 0;
while (str[i][j]!='\0'){
len++;
j++;
if (len > *length){
*length = len;
longstr = str[i];
}
}
}
return longstr;
}
My test input is
Enter array size:
4
Enter string 1:
Kenny
Enter string 2:
Mary
Enter string 3:
Peter
Enter string 4:
Sun
In XCode, I am able to receive the correct output:
longest: Kenny
length: 5
But using 2 different online compilers, I get the output below on both occasions:
longest: Kenny
length: 6
Why does my length differ?
Thank you.
probably one of them is a windows based compiler.
there "\n" is tread as two characters \r and \n
\r is called as carriage return
\n is called as line feed.
with this you get a byte extra there.

Making a string of usergiven_character*usergiven_repeatsinthestring(number of repeats)

I think that the problem is with allocating the memory for the string, but probably there is more to it
What i have to do is get a character and a number from the user
And print a string that has the character appear in it number times
Like i give character: $ and number: 8
I need to make a string :$$$$$$$$
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *ptr;
char *string;
//Space for number
ptr = (int *) calloc(1,sizeof(int));
//Get number
printf("Give any number: \n");
scanf("%i",ptr);
fflush(stdin);
//Space for string(+1 for \0)
string = (char *) calloc(*ptr+1,sizeof(char));
//Get string
printf("Give any character: \n");
gets(string);
//They dont give the *ptr+1 memory that i give to string
printf("Size of string is: %i\n",sizeof(string));
printf("Size of string is: %i\n",strlen(string));
//I put the character *ptr times in the string
for ( char *x = string; x-string<*ptr; x++)
strcpy(x,string);
//I print it
printf("String is: ");
puts(string);
free(string);
free(ptr);
return 0;
}
This works-----------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
int *ptr;
char *string,*x,*c;
//Space for number
ptr = (int *) calloc(1,sizeof(int));
//Get number
printf("Give any number: \n");
scanf("%i",ptr);
//Space for string(+1 for \0)
string = (char *) calloc(*ptr+1,sizeof(char));
//Get string
printf("Give any character: \n");
scanf(" %c",string);
//This was the problem
c = (char *) calloc(1,sizeof(char));
*c = *string;
//I put the character *ptr times in the string
for ( x = string; x-string<*ptr; x++)
strcpy(x,c);
//Just checking
printf("Size of string is: %i\n\n",strlen(string));
//I print it
printf("String is: %s\n\n",string);
free(string);
free(ptr);
return 0;
}
Suggest at a minimum the following changes/suggestions: (read comments as well.)
//Space for number
// ptr = (int *) calloc(1,sizeof(int));
// ^^^^^^^
ptr = calloc(1,sizeof(int)); //No need to cast return of calloc in C.
// However,
int val = 0;
// would be a better choice of creating space for an integer.
// (unless this is an assignment.)
//Get number
printf("Give any number: \n");
scanf("%i",ptr);
// or, if using val
scanf("%i", &val); //needs the address of operator for non pointer variable
//fflush(stdin); // undefined behavior to do this
//Space for string(+1 for \0)
//string = (char *) calloc(*ptr+1,sizeof(char));
char string[12] = {0}; //simplify, define a char array and use it instead
//note the largest likely length of an integer is
//represented in a string is 11: "-2147483648"
// plus the nul character, thus string size is 12.
char c = 0;
//Get string - not really getting a string from user, but a char.
//get char (more accurate description on what you are actually doing
printf("Give any character: \n");
//gets(string);
// place user input into a string
scanf(" %c"m &c); //note the space in front of %c. It consumes newline character.
If you have a character and a number, say variables c and ptr, then the sprintf statement becomes:
sprintf(string, "%c%d", c, ptr);
Given c == $ and ptr == 5, the loop to produce $$$$$ could be:
memset(string, 0, strlen(string)+1);
for(int i = 0; i<ptr; i++)
{
string[i] = c;
}
strcat(string[i] = 0; // terminate with nul character
string is now ready to print by any of these methods:
printf(string); or
printf("%s", string); or
fputs(string, stdout); or
puts(string);

Reversing a string using two pointers in C

I'm trying to reverse a string using pointers sptr1 and sptr2, The len gives the correct length of the entered string but the string is not reversed and str1 is not displaying on my terminal. Please provide some insights
#include<stdio.h>
void main()
{
char str1[10];
char temp;
char *sptr1;
char *sptr2;
int len;
printf("Enter a string:");
scanf("%s",&str1);
sptr1=str1;
sptr2=str1;
while(*sptr1!='\0')
{
sptr1++;
}
len=sptr1-str1;
printf("Length of the string:%d",len);
while(len!=0)
{
temp=*sptr1;
*sptr1=*sptr2;
*sptr2=temp;
sptr1--;
sptr2++;
len=len-1;
}
printf("%s",str1);
}
After while(*sptr1!='\0')... sptr points to the null-terminator of the string and then you are switching this null terminator with the first character. E.g. you move the null terminator to index 0. You have to decrement sptr before starting the reverse.
You should also decrement len by 2, otherwise you would iterate over the whole array and switch the already switched characters back.
Some other small mistakes:
main should return int, not void.
scanf("%s", &str1); should be scanf("%s", str1);, str1 already decays to a pointer.
You should add \n in your printf statements to have the output in different lines instead of 1 long line.
#include<stdio.h>
int main() {
char str1[10];
char temp;
char *sptr1;
char *sptr2;
int len;
printf("Enter a string:\n");
scanf("%s", str1);
sptr1 = str1;
sptr2 = str1;
while ( *sptr1 != '\0') {
sptr1++;
}
len = sptr1 - str1;
printf("Length of the string:%d\n", len);
sptr1--;
while (len > 0) {
temp = *sptr1;
*sptr1 = *sptr2;
*sptr2 = temp;
sptr1--;
sptr2++;
len = len-2;
}
printf("%s\n", str1);
}
See it live: https://ideone.com/WAnQLi
#include<stdio.h>
#include<string.h>
int main(int argc, const char * argv[])
{
char s[]="hello";
strrev(s);
puts(s);
return 0;
}
try strrev function:
char *strrev(char *str);
there is only one mistake #mch's code in
len = len - 2;
because of this, program won’t work for string which length is even number correctly.
I write to code because of more readability.
#include <stdio.h>
int main()
{
char str[10];
printf("Enter a string:\n");
scanf("%s", str);
char *ptr1, *ptr2;
ptr1 = ptr2 = str;
size_t len = 0;
while (*ptr1) {
++ptr1, ++len;
}
printf("Length of the string:%u\n", len);
for (int k = 0; k < len / 2; ++k) {
char temp = *(--ptr1);
*ptr1 = *ptr2;
*ptr2++ = temp;
}
printf("%s\n", str);
}
Just an additional answer, be very careful with buffer overflow issues. Also a minor detail, you don't really need a len variable.
Below a commented code showing a way to deal carefully with memory writing.
#include <stdio.h>
// Here a way to use constants both as integer and strings
// See https://stackoverflow.com/questions/5459868
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
// Let's define a max length
#define MAX_STRING_LENGTH 10
void main()
{
char sptr[MAX_STRING_LENGTH + 1];
char *sptr1=sptr,*sptr2=sptr;
char swap;
printf("Enter a string (" STR(MAX_STRING_LENGTH) " at most): ");
// Here, limit the input to sptr size - 1
// (let the last index for the null character)
// Example : "%10s" means "at most 10 characters, additional ones
// will be removed."
scanf("%" STR(MAX_STRING_LENGTH) "s",&sptr);
// Finding the last character BEFORE the NULL character
while(*(sptr2+1) != '\0') sptr2++;
// Swaping
while (sptr2 > sptr1)
{
printf("\t-> swaping %c <-> %c\n", *sptr1, *sptr2);
swap=*sptr1;
*sptr1=*sptr2;
*sptr2=swap;
sptr1++,sptr2--;
}
printf("Result : [%s]\n",sptr);
}
Examples (strings with odd and even length):
user:~$ ./a.out
Enter a string (10 at most): abc
-> swaping a <-> c
Result : [cba]
user:~$ ./a.out
Enter a string (10 at most): abcd
-> swaping a <-> d
-> swaping b <-> c
Result : [dcba]
user:~$ ./a.out
Enter a string (10 at most): abcdefghijklmnopqrstuvwxyz
-> swaping a <-> j
-> swaping b <-> i
-> swaping c <-> h
-> swaping d <-> g
-> swaping e <-> f
Result : [jihgfedcba]

Defining size for string using a variable not working properly in for loop in C

I'm trying to reverse the string input entered by user, the problem here is in function *rev, when I use size = strlen(STR); to get the length of the string and pass it into the size of the revS[size] the program outputs some garbage value for reverse string! if I pass some value instead if size in revS[10] and run the program it works as expected. I Have checked the value of size as
printf("\nlength of string is: %d\n",size);
and it gives the correct value. I'm not getting where is it going wrong!
#include<stdio.h>
#include<string.h>
char *rev(char *);
int main()
{
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
printf("You entered string : %s\n Reversed string is: %s", string, rev(string));
}
char *rev(char *STR)
{
int size, i, j = 0;
size = strlen(STR);
printf("\nlength of string is: %d\n", size);
char revS[size];
for(i = size-1; i >= 0; i--)
{
revS[j] = STR[i];
j = j + 1;
}
revS[j] = '\0';
return (revS);
}
OUTPUT:
Enter the string to reverse: mahaveer
length of string is: 8
You entered string : mahaveer
Reversed string is: ╚²b
--------------------------------
Process exited after 28.7 seconds with return value 0
Press any key to continue . . .
The issue is that your reversed string is allocated on the stack rather than the heap. When your rev function returns, all of the variables in that scope will be garbage collected. You can use malloc() to allocate memory dynamically on the heap. Note that the caller is responsible for calling free() on the string to avoid a memory leak.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *rev(char *);
int main() {
char string[100];
printf("Enter the string to reverse: ");
scanf("%s", string);
char *r = rev(string);
printf("You entered string: %s\nReversed string is: %s\n", string, r);
free(r);
}
char *rev(char *str) {
int i, j;
int size = strlen(str);
char *rev = malloc(sizeof(*rev) * (size + 1));
for (i = size - 1, j = 0; i >= 0; i--, j++) {
rev[j] = str[i];
}
rev[size] = '\0';
return rev;
}
Note that this code is susceptible to buffer overflows.
You have tho major UBs here. First you allocate local storage array which is not available after the function return. The second one - the size is too small to accomodate the string plus terminating zero

Would does this function which converts a char array to an int array not work?

This program is supposed to convert the array of chars (string) into an array of ints by subtracting 97 from their ascii value (the input should be lower case cause a has an ascii value of 97). So if i enter the string abcd i should get 0123 but instead I somehow get this: 012134513789. I can't figure out where the problem is.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void userEnter(int*pattern, int n);
int main(void)
{
int n, i;
printf("What is the length of the array: ");
scanf("%d",&n);
int pattern[n];
printf("Enter the char array: ");
userEnter(pattern, n);
printf("The int array is: ");
for(i=0;i<n;i++)
{
printf("%d",pattern[i]);
}
printf("\n");
}
void userEnter(int*pattern, int n)
{
char input[n];
scanf("%s", input);
int i;
for(i = 0; i < n-1; i++)
{
pattern[i] = input[i]-97;
}
}
char input[n];
scanf("%s", &input);
should be
char input[n+1];
scanf("%s", input);
input is equivalent to &input[0]
You should also exit the for loop in userEnter when you encounter the nul character that ends the user-entered string. e.g. with something like
char* p = input;
while (*p != '\0') {
*pattern = (*p) - 'a';
p++;
pattern++;
}
As KingsIndian points out, you also need to increase the size of your input buffer. At present, you overflow that buffer and overwrite the loop counter i;
The length parameter n includes one character for null as well. So, if you input length for n 4 then you can only input 3 characters, for example abc because the 4th is for the null.
So you should change the declaration accordingly:
Change:
char input[n];
to:
char input[n+1];
Note that variable length arrays are allowed only since C99.

Resources