Checking whether string is palindrome or not using Functions in C - c

I want to check whether a string entered by the user is palindrome or not. Without using functions I have done this problem but when I use functions for this problem I am always getting the same output:
The Entered String Is Not Palindrome!
Even if the string entered by the user is palindrome I get the same output. Here is my code:
#include <stdio.h>
#include <string.h>
void reverse(char [],int);
int main() {
char a[100];int len, i = 0;
printf("Please enter the string to check: \n");
fgets(a,100,stdin);
//Loop to replace the '\n' inserted at the end of string due to fgets() with '\0'
for (int i = 0; i < strlen(a); ++i)
{
if (a[i] == '\n')
{
a[i] = '\0';
}
}
len = strlen(a);
reverse(a,len);
return 0;
}
void reverse(char b[100], int n) {
char c[100];int k=0;
//Read characters from b[] from the end and store them into c[]
for (int i = n-1; i >= 0; i--)
{
c[k] +=b[i];
k++;
}
c[k] = '\0';
//Check if the reversed string c[] and the actual string b[] are equal
if(strcmp(c,b) == 0)
printf("The Entered String Is Palindrome!\n");
else
printf("The Entered String Is Not Palindrome!\n");
}
The code in the reverse() function is the same as the one I used to solve the same problem without functions(and that program worked perfectly fine). But still it isn't giving the correct output. What am I doing wrong here?
EDIT: Okay, so I have removed the c[k] += b[i] according to an users suggestion and now it works perfectly fine. But I still don't get it. I mean I used the same line in the same program, the only difference being I didn't use the functions concept there and it worked perfectly fine. Here is the code:
#include <stdio.h>
#include <string.h>
int main() {
char a[100], b[100];
int k=0;
printf("Please enter the string: \n");
fgets(a,100,stdin);
//To replace the '\n' at the end of the string inserted by fgets()
for (int i = 0; i < strlen(a); ++i)
{
if(a[i] == '\n')
a[i] = '\0';
}
for (int i = strlen(a)-1; i >=0 ; i--)
{
b[k] += a[i];
k++;
}
if (strcmp(a,b) == 0)
{
printf("The entered string is palindrome!\n");
}
else
printf("The entered string is not palindrome! \n");
return 0;
}
Is there some concept behind it that I am unaware of? If so then please enlighten me.

You invoked undefined behavior by using values of an uninitialized variable having automatic storage duration, which is indeterminate.
Instead of adding in c[k] +=b[i];, just assign value from b as c[k] = b[i];.

Related

comparing a char to a string in C

I'm quite new to C and I'm wondering why in the code below, the char I'm comparing to each letter of the string word is showing that it's equal everytime.
For example
If I've inputted the word
apple
and I'm looking for any repeating char in "apple" my function. I pass in to the function each char of apple such as a, p, p etc. It should return 1 when I pass in p since it's repeated, but instead, for every char of apple, my function says a == word[0], a == word[1] even though word[1] for "apple" is 'p'.
I know char is ASCII, so each char has a number value, but I'm not sure why this is not working. Perhaps, I'm using the pointer *word in the functions arguments incorrectly?
My code is below for my function, rpt_letter:
int rpt_letter(char *word, char c)
{
int i;
int count = 0;
i = 0;
printf("This is the WORD %s\n", word);
while(count < 2)
{
if(word[i] == c)
{
count++;
printf("the count is %d\n the char is %c and the string is %c\n", count, c, word[i]);
}
i++;
}
if (count<2)
{
// printf("letter %c was not found in the array. \n", c);
return 0;
}
else
{
//printf("letter %c was found at index %d in the array.\n", c, mid);
repeats[rpt_counter] = c;
rpt_counter++;
return 1;
}
return 0;
}
I'll include the main method just in case -- but I believe the main method is working well
int main(void)
{
//! showArray(list, cursors=[ia, ib, mid])
//int n = 51;
char word[51];
scanf("%s", word);
//length of string
for (n=0; word[n] != '\0'; n++); //calculate length of String
printf("Length of the string: %i\n", n);
int count = 0;
//sort words
int i;
char swap = ' ';
for(int k = 0; k < n; k++)
{
for (i=0; i<n-1; i++)
{
//if prev char bigger then next char
if (word[i] > word[i+1])
{
//make swap = prev char
swap = word[i];
//switch prev char with next char
word[i] = word[i+1];
//make next letter char
word[i+1] = swap;
}
}
}
printf("%s\n", word);
for (i=0; i<n-1; i++)
{
int rpt = rpt_letter(word, word[i]);
if(rpt == 1)
{
count++;
}
}
printf("%d", count);
return 0;
}
I've tried a number of things such as using the operator !=, also <, > but it gives me the same result that each word[ia] == c.
You are getting this issue because in your code rpt_letter() the while loop has a terminating condition count >= 2. Now consider input apple and character a. As a appears in apple only once, the count after traversing the whole word remains 1. But the loop doesn't terminate. So, the index i becomes greater than the length of string and tries to check the character appearing after that.
The loop terminates eventually when it gets another a this way. You need to add a check for the terminating null character in your loop so that it doesn't cross the length of the string .
Change the while loop condition to something like -
while((count < 2) && (word[i] != '\0'))

Kochan InsertString segmentation fault

I am working through Kochan's programming in C book and I am working on an exercise which requires a function to insert one character string inside another string, with the function call including where the string is to be inserted.
I have written the below code but I receive a segmentation fault whenever I enter the inputs. I think it's because the 'input' string is defined to the length of the user's input and then the insertString function tries to add additional characters to this string. I just can't see a way of defining the string as large enough to be able to take in additional characters. Do you think that this is the reason I am receiving a segmentation fault? Are there any other ways to go about this problem?
#include<stdio.h>
#include <string.h>
insertString(char input[], const char insert[], int position)
{
int i, j;
char temp[81];
j = strlen(input);
for(i = 0; i < position - 1; i++)
{
temp[i] = input[i];
}
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
for(j = i - j; input != '\0'; i++, j++)
{
temp[i] = input[j];
}
for(i = 0; temp[i] != '\0'; i++)
{
input[i] = temp[i];
}
input[i] = '\0';
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}
There might be other reasons as well, but the following fragment will crash for sure:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
The reason is that - since insert will not be increased or manipulated - this is an endless loop writing "indefinitely" long into temp. Once exceeding its length 80 (or a bit later) it will crash. I suppose you meant for(j = 0; insert[j] != '\0'; i++, j++), right?
Check all for loop conditions in insertString function. For example:
for(j = 0; insert != '\0'; i++, j++)
{
temp[i] = insert[j];
}
is infinite loop. Because of it you access memory out of temp array bounds. It causes UB and segmentation fault. Looks like you need insert[j] != '\0' condition here.
I'm familiar with this book. The author, Stephen Kochan, has a website with answers to the odd-numbered end of chapter exercises.
The website is at classroomm.com but you'll need to look around some to find the information.
Here is the info from that site related to this exercise:
Programming in C, exercise 10-7 (3rd edition) and 9-7 (4th edition)
/* insert string s into string source starting at i
This function uses the stringLength function defined
in the chapter.
Note: this function assumes source is big enough
to store the inserted string (dangerous!) */
void insertString (char source[], char s[], int i)
{
int j, lenS, lenSource;
/* first, find out how big the two strings are */
lenSource = stringLength (source);
lenS = stringLength (s);
/* sanity check here -- note that i == lenSource
effectively concatenates s onto the end of source */
if (i > lenSource)
return;
/* now we have to move the characters in source
down from the insertion point to make room for s.
Note that we copy the string starting from the end
to avoid overwriting characters in source.
We also copy the terminating null (j starts at lenS)
as well since the final result must be null-terminated */
for ( j = lenSource; j >= i; --j )
source [lenS + j] = source [j];
/* we've made room, now copy s into source at the
insertion point */
for ( j = 0; j < lenS; ++j )
source [j + i] = s[j];
}
There's an error somewhere in your insertString function where it goes out of bounds. By the way your insertString function doesn't start with the word void.
If I substitute the insertString function which I wrote for the exercise then the program works.
#include<stdio.h>
#include <string.h>
void insertString (char source[], const char s[], int start)
{
int stringLength (const char s[]);
int lenSource = strlen (source);
int lenString = strlen (s);
int i;
if ( start > lenSource ) {
printf ("insertion point exceeds string length\n");
return;
}
// move the characters in the source string which are above the
// starting point (including the terminating null character) to make
// room for the new characters; to avoid overwriting characters the
// process begins at the end of the string
for ( i = lenSource; i >= start; --i )
source[i + lenString] = source[i];
// insert new characters
for ( i = 0; i < lenString; ++i )
source[start + i] = s[i];
}
void readLine(char buffer[])
{
char character;
int i = 0;
do
{
character = getchar();
buffer[i] = character;
i++;
}
while(character != '\n');
buffer[i - 1] = '\0';
}
int main(void)
{
char input[81];
char insert[81];
int position;
printf("Enter the first string: ");
readLine(input);
printf("Enter the insert string: ");
readLine(insert);
printf("Enter placement position int: ");
scanf("%i", &position);
insertString(input, insert, position);
printf("The adjusted string is %s\n", input);
return 0;
}

How to find number of times that a given word occurs in a sentence [C code]?

Here is my code. I need to find out the number of times a given word(a short string) occurs in a sentence(a long string).
Sample Input: the
the cat sat on the mat
Sample Output: 2
For some reason the string compare function is not working and my output is coming as zero. Kindly ignore the comments in the code as they have been put to debug the code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char word[50];
gets(word);
int len = strlen(word);
//printf("%d",len);
char nword[len];
char s[100];
strcpy(nword,word);
puts(nword);
printf("\n");
gets(s);
//printf("%d",strlen(s));
char a[50][50];
int i,j,k;
j = 0;
for(i=0;i<strlen(s);i++)
{
a[i][j] = s[i];
printf("%c",a[i][j]);
if(s[i] == ' ')
{
j++;
printf("\n");
}
}
printf("%d",j);
k = j;
//printf("\nk assigned\n");
j = 0;
//printf("j equal to zero\n");
int count = 0;
int temp = 0;
//printf("count initialized.\n");
for(i=0;i<k;i++)
{
if(strcmp(a[i],nword) == 0)
count++;
}
printf("\n%d",count);
return 0;
}
Your main problem is with this loop for numerous reasons
int i,j,k;
j = 0;
for(i=0;i<strlen(s);i++)
{
a[i][j] = s[i];
printf("%c",a[i][j]);
if(s[i] == ' ')
{
j++;
printf("\n");
}
}
Firstly you've got your indexes into a backwards - a[i][j] means the i-th string and the j-th character, but since you're incrementing j for each word you want it the other way around - a[j][i].
Secondly you can't use i for both indexing into s and a. Think about what happens when you are building the second string. In your example input the second word starts when i is 4 so the first character will be stored as a[1][4]=s[4] which leaves a[1][0] to a[1][3] uninitialised. So you have to use a 3rd variable to track where you are in the other string.
When you hit a space, you don't want to add it to your word as it won't match later on. You also need to add in a null-terminator character to the end of each string or else your code won't know where the end of the string is.
Putting the above together gives you something like this:
int i,j,k;
k = j = 0;
for(i=0;i<strlen(s);i++)
{
if(s[i] == ' ')
{
a[j][k] = '\0';
j++;
k=0;
printf("\n");
}
else
{
a[j][k] = s[i];
printf("%c",a[j][k]);
k++;
}
}
a[j][k]='\0';
The problem is that a is a two-dimentional array and you reference it as a one dimention. Maby you use a 2-dimentional array to represent i=line, j=character. If you keep this idea then you'll have to do this:
j=0;
for(i=0;i<k;i++)
{
if(strcmp(a[i][j],nword) == 0)
count++;
j++;
}
But then it will be difficult to detect words that are split in half. I'd recommend keeping a as a one dimentional array. Copy the contents of s[i] serially and when you want to distinguish lines use the \r\n operator.
I think you use your 2-dimensional array wrong. a[0][j] should be the first word from s[i]. But what you are doing is a[i][0] = s[i] which makes no sense to me.
Best regards
I would implement this using the functions strtok() and strcmp():
int main(void)
{
char word[] = "the"; /* the word you want to count*/
char sample[] = "the cat sat on the mat"; /* the string in which you want to count*/
char delimiters[] = " ,;.";
int counter;
char* currentWordPtr;
/* tokenize the string */
currentWordPtr = strtok(sample, delimiters);
while(currentWordPtr != NULL)
{
if(strcmp(word, currentWordPtr) == 0)
{
counter++;
}
/* get the next token (word) */
currentWordPtr = strtok(NULL, delimiters);
}
printf("Number of occurences of \"%s\" is %i\n", word, counter);
return 0;
}

end of line character is not detected

A simple program, a static string which is used to read the input, then pass it to the function. Just wondering why it can not find the '\0' character using the while(*string!='\0') expression.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int is_palindrome(char *string)
{
int length, mid, end, i;
length=0;
if (string == NULL)
return 0;
while (string[length] != '\0')
{
printf("%c\n", string[length]);
length++;
}
//Not working version
/*
while(*string!='\0')
length++;
*/
end = length - 1;
mid = length / 2;
printf(" end=%d, mid=%d\n", end, mid);
for (i = 0; i < mid; i++) {
if (string[i] != string[end]) {
printf("It's not palindrome\n");
return 0;
}
end--;
}
if (i == mid) {
printf("It's palindrome\n");
return 1;
}
return 0;
}
int main(void)
{
char string[100];
printf("Enter a string to test for the parlindrome\n");
gets(string);
int length = strlen(string);
printf("You entered %s,length is %d\n", string, length);
if (is_palindrome(string))
;
printf("Enter to Quit\n");
char x;
scanf("%c", &x);
return 0;
}
Instead of
while(*string!='\0')
length++;
write
char* p = string;
while( *p++ )
length++;
otherwise the pointer will not move and you become stuck in an infinite loop (if the string is not empty). Use p to avoid changing the original pointer.
Also initialize all variables before using them, good rule of thumb.
Initialize length to 0 before using its value in the while loop.
Or you could use the standard library function strlen().
Also, in the palindrome check, you should probably decrease end at the same you increase i. As it is, you're comparing the characters in the first half each with the same char at the end. This will match strings like "aaaabfa" but not "abcdcba".

Can't get a function call in a function to work properly

I'm writing a program to generate a string of random uppercase letters, then take user input of uppercase letters, along with a character form the user. For any instance of the user input letter in the random string, it replaces that letter with the character entered by the user.
For example, s1 = {BDHFKYL} s2 = {YEIGH} c = '*'
Output = BD*FK*L
The program was working correctly until I added the feature to ask the user to enter what character they would like to replace the letters.
The output is:
Please enter at least 2 capital letters and a maximum of 20.
HDJSHDSHDDS
HDJSHDSHDDS
Enter a character to replace occuring letters.
*
NWLRBBMQB
Would you like to enter another string?
Here's the code:
void fillS1(char x[]);
void fillS2(char x[], char y[], char z);
void strFilter(char a[], char b[], char c);
int main(int argc, const char * argv[])
{
char s1[42];
char s2[22];
char x = 0;
fillS2(s2, s1, x);
return 0;
}
void fillS1(char x[])
{
for (int i = 0; i < 40; i++)
x[i] = 'A' + random() % 26;
x[40] = (char)0;
}
void fillS2(char x[], char y[], char z){
char loopContinue = 0;
do {
int i = 0;
int capitalLetterCheck = 0;
printf("Please enter at least 2 capital letters and a maximum of 20.\n");
while (( x[i] = getchar()) != '\n' ) {
i++;
}
x[i] = '\0';
if (i < 3) {
printf("You need at least two letters\n");
}
else if (i > 21){
printf("You cannot have more than twenty letters\n");
}
for (i = 0; i < 20; i++) {
if ((x[i] >= 'a') && (x[i] <= 'z')) {
printf("You many only have capital letters.\n");
capitalLetterCheck = 2;
}
}
if (capitalLetterCheck != 2) {
for (i = 0; i < 20; i++) {
if ((x[i] >= 'A') && (x[i] <= 'Z')) {
puts(x);
fillS1(y);
printf("Enter a character to replace occuring letters.\n");
while ((z = getchar() != '\n')) {
}
strFilter(y, x, z);
break;
}
}
}
printf("Would you like to enter another string?\n");
gets(&loopContinue);
} while (loopContinue != 'n');
}
void strFilter(char a[], char b[], char c){
int i = 0;
int n = 0;
while (n < 20) {
for (i = 0; i < 40; i++) {
if (a[i] == b[n]){
a[i] = c;
}
}
i = 0;
n++;
}
puts(a);
}
Thank you.
first of all please try to make your code a little easier to read, and I'm not talking about indenting but about its flow.
Also, your example output seems to work fine since there was nothing to change in any string here...?
There are a few things you should keep in mind when coding :
give your variables and functions explicit names, espcecially if you are going to have someone read your code at some point
try to keep the flow of your code simple by making small functions when you have a specifig task to execute (get the user's input, generate a random string, etc.) as opposed to just writing most of it in imbricated loops
You could also have a look at scanf (man scanf) to get the user's input
Try allocating a buffer when you get the user's input instead of having a static one that may not be of the right size
It's very easy to write some pseudo-code and then translate it into C :
WHILE someCondition
Generate a random string
Get a string from the user
Get a character from the user
Find and replace
END
Here is an example of how you could have organised your code (don't use it though - no frees, no getting the user's input, etc.) :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* generateString(void)
{
return "AEIOUYAEIOUY"; // In your implementation, this is where you'd generate the random string
}
char* getStringInput(void)
{
return "HELLO"; // In your implementation, this is where you'd get the user's string
}
char getCharInput(void)
{
return '*'; // In your implementation, this is where you'd get the user's character
}
char* findAndReplace(char* randomString, char* userString, char userChar)
{
int l1;
int l2;
int i;
int j;
char* output;
l1 = strlen(randomString);
l2 = strlen(userString);
output = (char*)malloc(sizeof(*output) * l1);
strcpy(output, randomString);
for (i = 0; i < l1; ++i)
{
for (j = 0; j < l2; ++j)
if (randomString[i] == userString[j])
output[i] = userChar;
}
return (output);
}
int main(int ac, char** av)
{
char* randomString;
char* userString;
char userChar;
char* outputString;
randomString = generateString();
userString = getStringInput();
userChar = getCharInput();
outputString = findAndReplace(randomString, userString, userChar);
printf("Result: %s\n", outputString);
// don't forget to free any allocated buffer
return (1);
}
How much debugging have you done? Try putting some printfs in your code to see what happens - when functions are called, what are your variable's values, etc.
Example :
void fillS1(char x[])
{
printf("-- entering fillS1, buffer value: %s\n", x);
for (int i = 0; i < 40; i++)
x[i] = 'A' + random() % 26;
x[40] = (char)0;
printf("-- leaving fillS1, buffer value: %s\n", x);
}
(be careful about what's in your buffer before you use printf)
This should tell you pretty quickly what's going wrong.
For example, try checking the value of "c" in strFilter when it's called, and have a second look at how you get the user's input.

Resources