Reverse string function in C? - c

Here's a C source I tried to test:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
main()
{
char c[81];
gets(c);
str_inv(c);
puts(c);
}
void str_inv(char *s[])
{
int i, j;
char *temp;
temp=calloc(1 ,strlen(s)*sizeof(char));
if(temp==NULL)
{
fprintf(stderr, "Error: Memory not allocated.");
exit(1);
}
for(i=0, j=strlen(s)-1; i<strlen(s); i++, j--)
{
temp[i]=s[j];
}
for(i=0; i<strlen(s); i++)
{
s[i]=temp[i];
}
free(temp);
}
An output of the program looks like this:
**abc**
**Process returned 0 (0x0) execution time : 2.262 s**
**Press any key to continue.**
The code in function str_inv works fine while in main() function, but not in separate function.
What is the problem with function?

char *s[] is an array of pointer to char
char s[] is an array of char
Change the function to
void str_inv(char s[])
As a side note. gets() is deprecated, please do not use it. Use fgets() instead.

Related

Allocating dinamicaly memory problems and VLA with characters

I know I should not use c and c++ at the same time.
Can someone say why the above code are working using new?
the purpose is to remove the central character of an word given by keyboard ex: "abcde" to "abde"
I was asking if the creation of VLA is correct or not... apparently it returns what I want BUT the same main code without the other functions crashes.
I searched throw internet and i discovered that i should initialize the size ('n' in my case)of the VLA's.
Code using functions and new:
#include <stdio.h>
#include <string.h>
int citirea_sirului(char *s1, char *s2)
{
int d;
printf("Cuvantul: ");
gets(s1);
d=strlen(s1);
for(int i=0;i<d;i+=1)
{
*(s2+i)=*(s1+i);
}
return d;
}
void prelucrarea_afis_siruluiC(char *b, int d, char *a){
strcpy(a,b+(d/2)+1);
strcpy(b+(d/2),"");
strcat(b,a);
puts(b);
}
int main(){
int n;
char *cuv,*ccuv;
cuv=new char[n];
ccuv=new char[n];
n=citirea_sirului(cuv,ccuv);
printf("Dimensiunea Cuvantului: %d\n",n);
printf("\nSir prelucrat: \n");
prelucrarea_afis_siruluiC(ccuv,n,cuv);
delete[] ccuv;
delete[] cuv;
return 0;
}
Code without functions:
#include <stdio.h>
#include <string.h>
int main(){
int n;
char cuv[n], ccuv[n];
printf("Cuvantul: ");
gets(cuv);
n=strlen(cuv);
printf("Dimensiunea Cuvantului: %d",n);
for(int i=0;i<n;i++)
{
ccuv[i]=cuv[i];
}
strcpy(cuv,cuv+(n/2)+1);
strcpy(ccuv+(n/2),"");
strcat(ccuv,cuv);
printf("\nCuvantul prelucrat: %s",ccuv);
return 0;
}

Stack smashing detected in C - why does this happen?

I have the following function, which, given a string, should find the most recurrent couple of letters in it and store the result in a different string.
For example - for the string "ababa", the most recurrent couple would be "ba", and for "excxexd" it would be "ex". This is the code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void printError(){
printf("Error: please check your input\n");
}
bool isLexicographicallyPreceding(char couple1[], char couple2[])
{
if (strcmp(couple1, couple2)>=0) return true;
return false;
}
void coupleDetector(int length, char word[], char result[])
{
char couples[length-1][2];
for (int i=0; i<length-1; i++)
{
char couple[2] = {word[i], word[i+1]};
strcpy(couples[i], couple);
}
char element[]="";
int count=0;
for (int j=0; j<length-1; j++)
{
char tempElement[2];
strcpy(tempElement,couples[j]);
int tempCount=0;
for (int p=0; p<length-1; p++)
{
if (couples[p]==tempElement) tempCount++;
}
if (tempCount>count)
{
strcpy(element, tempElement);
count=tempCount;
}
if (tempCount==count)
{
if (isLexicographicallyPreceding(tempElement,element) == true) strcpy(element, tempElement);
}
}
strcpy(result,element);
}
int main() {
//Supposed to print "ba" but instead presents "stack smashing detected".
int length=5;
char arr[] = "ababa";
char mostCommonCouple[2];
coupleDetector(length,arr,mostCommonCouple);
printf("%s", mostCommonCouple);
return 0;
}
The code compiles without errors, but for some reason does not work as intended but prints out "stack smashing detected". Why would that be? Advices would be very helpful.
Thanks.
In trying out your program, I found a few of your character arrays undersized. Character arrays (strings) need to be sized large enough to also include the null terminator value in the array. So in many locations, having a two-character array size is not sufficient and was the cause of the stack smashing. With that in mind, following is a refactored version of your program.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>
void printError()
{
printf("Error: please check your input\n");
}
bool isLexicographicallyPreceding(char couple1[], char couple2[])
{
if (strcmp(couple1, couple2)>=0) return true;
return false;
}
void coupleDetector(int length, char word[], char result[])
{
char couples[length-1][3];
for (int i=0; i<length-1; i++)
{
char couple[3] = {word[i], word[i+1], '\0'};
strcpy(couples[i], couple);
}
char element[3]; /* Define the character array */
strcpy(element, ""); /* Then initialize it if need be */
int count=0;
for (int j=0; j<length-1; j++)
{
char tempElement[3];
strcpy(tempElement,couples[j]);
int tempCount=0;
for (int p=0; p<length-1; p++)
{
if (couples[p]==tempElement) tempCount++;
}
if (tempCount>count)
{
strcpy(element, tempElement);
count=tempCount;
}
if (tempCount==count)
{
if (isLexicographicallyPreceding(tempElement,element)) strcpy(element, tempElement);
}
}
strcpy(result,element);
}
int main()
{
//Supposed to print "ba" but instead presents "stack smashing detected".
int length=5;
char arr[] = "ababa";
char mostCommonCouple[3]; /* Notice size requirement to also contain the '\0' terminator */
coupleDetector(length,arr,mostCommonCouple);
printf("%s\n", mostCommonCouple);
return 0;
}
Here are some key points.
Viewing the code, most sizes for arrays was enlarged by one to accommodate storage of the null terminator.
Work fields such as "element" need to be defined to their proper size so that subsequent usage won't also result in stack smashing.
Testing out the refactored code resulted in the following terminal output.
#Vera:~/C_Programs/Console/Recurrent/bin/Release$ ./Recurrent
ba
So to reiterate, be cognizant that character arrays normally need to be defined to be large enough to contain the largest expected string plus one for the null terminator.
Give that a try and see if it meets the spirit of your project.

Error with the array returning through function

I need to read a word from main function and convert the characters in UCASE if the first character is LCASE and vice versa using the user defined function.I tried ways for returning the array from function but still I am lacking some core ideas. Please debug this program and explain the way it works.
#include <stdio.h>
#include <string.h>
int* low (char str)
{
int i;
for (i=1; i<strlen(str);i++)
{
if(str[i]<91)
{
str[i]=str[i]+32;
}
else
{
}
}
return &str;
}
int* high (char str[50])
{
int i;
for (i=0; i<strlen(str);i++)
{
if(str[i]>91)
{
str[i]=str[i]-32;
}
else
{
}
}
return &str;
}
void main()
{
char str[50];
char* strl;
printf("Enter any string....\n");
scanf("%s",str);
if (str[0]<91)
{
*strl=low(str);
}
else
{
*strl=high(str);
}
printf("Converted string is %s.",*strl);
}
There is already a problem here:
So if you are saying this code is perfect and you want us to debug it and explain how (on earth) this works, then here you go.
In function int* low (char str), you have if(str[i]<91). Thats a problem right there. str is a char received as an argument, and hence str[i] is a straight compile-time error.
Another one to deal with is the return statement.
You have a statement:
return &str;
which would return the address of str, which by the way is a char, whereas function low is supposed to return a pointer to an int.
The same is applicable to high function as well.
Suggestion: Leave aside this bad code and get a beginner level C programming book first. Read it and the try some codes out of it.
A few inputs for improvement: (Which you may not comprehend)
change
void main()
to
int main(void)
Why? Refer this legendary post: What should main() return in C and C++?
Secondly, int both functions you are using strlen() in loop which will always return a fixed value. So, instead of
for (i=0; i<strlen(str);i++)
I'd suggest,
size_t strlength = strlen(str);
for (i=0; i < strlength; i++)
You can try the code and method as below:
#include <stdio.h>
#include <string.h>
char* caseConverter (char *str)
{
int i;
for (i=0; i<strlen(str);i++)
{
if(str[i]>=65 && str[i]<=90)
{
str[i]=str[i]+32; //To lower case
}
else if((str[i]>=97 && str[i]<=122))
{
str[i]=str[i]-32; //To upper case
}
else
printf("%c is not an alphabet \n",str[i]);
}
return str;
}
void main()
{
char inputStr[50]= "Stubborn";
char* opStr= caseConverter(inputStr);
printf("Converted string is %s",opStr);
}

Using string as parameter for function

I am trying to use a function with a string as a parameter. I am running into a couple of error messages. First, it says that string[i] is not an array, pointer, or vector, despite the fact that string is a character array. Secondly, it says that I am doing a pointer to integer conversion. Here is my code:
#include <stdio.h>
#include <string.h>
void example (char string) {
int i;
for (i = 0; i < strlen(string); i++) {
printf (string[i]);
}
}
int main (void) {
example("I like pie");
return 0;
}
void example(char string) should be void example(char *string). You declared it to take a character, you want it to take a character pointer or array.
Also, you need to tell printf you are giving it a character: printf("%c", string[i]);.
Your API is wrong it should be
void example (char *string) { // string is a pointer
int i;
size_t n = strlen(string);
for (i = 0; i < n; i++) {
printf ("%c",string[i]); // print character using %c
}
}
Calculate the string length before the loop , calling strlen() in each iteration is not a good idea.
PS: what string points to is read-only you can't modify it
You should use void example(char *string) instead of void example (char string).
#include <stdio.h>
#include <string.h>
void example (char *string) {
int i;
for (i = 0; i < strlen(string); i++) {
printf ("%c",string[i]);
}
printf("\n");
}
int main (void) {
example("I like pie");
return 0;
}
Your function example just receives a character. To get a string you can use a pointer. Also you can use "%s" format specifier in printf instead of using the for loop and strlen() function.
#include <stdio.h>
#include <string.h>
void example (char *string) {
int i;
printf ("%s\n",string);
}

Error while executing: Segmentation fault

I'm a beginner in C language. After reading the initial chapters of Ritchie's book, I wrote a program to generate random numbers and alphabets.
The program compiles fine with gcc. However on running it, it gives an error "Segmentation fault", which is incomprehensible to my limited knowledge. I'd be glad to understand what I've written wrong.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
long int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
long int genrandom(int mino,int maxo) {
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1);
return val;
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%s ,",text);
}
char letterize(int num) {
char letter='A'+num;
return letter;
}
printf("%s ,",text); is wrong - it says that text is a nul-terminated array of chars. Use
printf("%c ,", text);
instead to print your single char.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
int genrandom(int mino,int maxo) {//changed function return type to int
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1); //Be careful when you are using '/' operator with integers
return val; //returning int here why set return type to long int?
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%c ,",text);//Replace %s with %c
}
char letterize(int num) { //No bound checking on num eh?
char letter='A'+num;
return letter;
}
That's all I had to say. :)
Why use %s when text is char. You dont need a string type in the function. Just a char would do. Change in the function : void randAlph ()
printf("%s ,",text);
to
printf("%c ,", text);

Resources