Search most right string in another string - in c [duplicate] - c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is there a reverse fn() for strstr
I wrote this main and function that get two string and check if the second string exist within the first one,
then return the most right index appear place.
If wasn't found return -1.
This is the code I wrote:
#include <stdio.h>
int strindex(char[], char[]);
int main()
{
char a[100];
char b[100];
int search;
printf("Enter two strings, To search the second one in the first one:\n");
printf("Enter the first string to search in:\n");
fgets(a,100,stdin);
printf("Enter the second string to search in the first:\n");
fgets(b,100,stdin);
printf("\n\n THE FIRST STRING IS:%s\n\n THE SEARCH STRING IS:%s",a, b);
printf("\n\n");
search = strindex(a, b);
if(search==-1)
printf("The second String didnt found in the first string\n");
else printf("The second string appear in the first string at most right at index:%d\n",search);
return 0;
}
int strindex(char s[], char t[])
{
int foundIndex = -1;
int tempFound, startNext;
int i,j;
i = j = 0;
while (s[i]!='\0')
{
if(s[i]==t[j])
{
startNext = i+1;
tempFound = i;
while(s[i]!='\0' && t[j]!='\0' && s[i]==t[j])
i++,j++;
if (t[j]=='\0') /**check if it null**/
{
printf("found match");
foundIndex = tempFound;
}
i = startNext;
j = 0;
}
else i++;
}
return foundIndex;
}
I think I have a problem in this line:
if (t[j]=='\0') /**check if it null**/
cause I tried put two string that the second one contain in the first but although t[j] is equal to null it doesn't perform the inside if statement.
I know there are many other ways of writing this program. But I know this one should work too and i am trying to make it work.

You're juggling with indexes, which is quite confusing. Use the indexes for one purpose only and don't set and reset at will. I would suggest to rewrite your function a bit and cleanup the used indexes
int strindex(char s[], char t[])
{
int foundIndex = -1;
int i,j;
for (i = 0; s[i]!='\0'; i++)
{
if(s[i]==t[0])
{
for(j = 1; s[i + j]!='\0' && t[j]!='\0' && s[i + j]==t[j]; j++)
;
if (t[j]=='\0') /**check if it null**/
{
printf("found match");
foundIndex = i;
}
}
}
return foundIndex;
}
You can replace the inner loop with strncmp of course.
And now to your question ;-). Your strindex works as intended. As #wildplasser already noted, fgets stores the final newline \n in the buffer. Since there's no newline in the string to be searched except at the end, you never get a match, if the string to search for is in the middle and not at the end.
When you either strip the newline from a[] and b[], you will see, that strindex works.
Another approach could be to give the strings on the command line instead of reading with fgets.
int main(int argc, char **argv)
{
int search;
printf("\n\n THE FIRST STRING IS:%s\n\n THE SEARCH STRING IS:%s", argv[1], argv[2]);
printf("\n\n");
search = strindex(argv[1], argv[2]);
if(search==-1)
printf("The second String didnt found in the first string\n");
else printf("The second string appear in the first string at most right at index:%d\n",search);
return 0;
}

OK friends. this is the solution that works:-):
thanks to Olaf Dietsche
#include <stdio.h>
int strindex(char[], char[]);
int main()
{
char a[100];
char b[100];
int search;
printf("Enter two strings, To search the second one in the first one:\n");
printf("Enter the first string to search in:\n");
fgets(a,100,stdin);
printf("Enter the second string to search in the first:\n");
fgets(b,100,stdin);
printf("\n\n THE FIRST STRING IS:%s\n\n THE SEARCH STRING IS:%s",a, b);
printf("\n\n");
search = strindex(a, b);
if(search==-1)
printf("The second String didnt found in the first string\n");
else printf("The second string appear in the first string at most right at index:%d\n",search);
return 0;
}
int strindex(char s[], char t[])
{
int foundIndex = -1;
int tempFound, startNext;
int i,j;
i = j = 0;
while (s[i]!='\n')
{
if(s[i]==t[j])
{
startNext = i+1;
tempFound = i;
while(s[i]!='\n' && t[j]!='\n' && s[i]==t[j])
i++,j++;
if (t[j]=='\n')
foundIndex = tempFound;
i = startNext;
j = 0;
}
else i++;
}
return foundIndex;
}

Related

How can I shift right after a certain point in the string?

My code provides the following parameters requested by the teacher:
But the teacher also wants this: "insertChar function should not overwrite any characters. It should insert the new character and offset remaining characters by one index."
how can I set this up? I mean how can I shift a string right from a certain point?
#include<stdio.h>
#include<string.h>
void insertChar(char string[], char c, int index) {
int len = 0;
int i;
for (i = 0; i > index; i--) {
string[i] = len;
string[i] = string[i-1];
string[i-1] = len;
}
string[index] = c;
}
int main() {
char string[100];
printf("Please input a string \n");
scanf ("%[^\n]%*c", string);
printf("Please input the character to be added to string.\n");
char c;
scanf ("%c", &c);
printf("Please input the index which the function will insert the character. \n");
int index;
scanf("%d", &index);
insertChar(string, c, index);
printf("%s", &string);
return 0;
}
How can I shift right after a certain point in the string?
(OP's insertChar() is too broken for repair.)
Watch out for 2 pitfalls: inserting well past the end of the string and exceeding the size of the buffer:
#include <string.h>
void insertChar(size_t buffer_size, char string[], char c, size_t index) {
size_t size_used = strlen(string) + 1;
if (size_used >= buffer_size) {
fprintf(stderr, "Buffer too small for insertion or existing string.");
} else if (index >= size_used) {
fprintf(stderr, "Inserting well past the end of the string.");
} else {
// Move the right portion of the string by 1 with memmove
// v----------------v Address one past the insertion point
memmove(&string[index + 1], &string[index], size_used - index);
// ^------------^ Insertion location
string[index] = c; // Insert
}
}
Usage
char string[100];
...
insertChar(sizeof string, string, c, index);

Issue with Strings in C

Here is a program with Strings where I am trying
Pig Latin translation is simply taking the first letter of a “word” and appending that letter to the end of the word with “ay” added to the end as well
I have issue with m1=m2+3 ( resetting the Initial Marker ).
Input that I am giving : "Alex, how are you right"
The output I am expecting is : lexay, owhay reay ouyay ightray
But
I am getting this : lex,Aay way ay ayo gayi
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
void initialize(char english[], char piglatin[]);
void readinput (char english[]);
int countwords(char english[]);
void convert ( int words, char english[], char piglatin[]);
void writeoutput( char piglatin[]);
int main()
{
char english[80], piglatin[80];
int words;
initialize(english, piglatin);
printf("enter the string\t");
fflush(stdin);
gets(english);
printf ("\nInput buffer contents: %s\n", english);
words = countwords(english);
convert(words,english,piglatin);
writeoutput(piglatin);
printf ("Have a nice day\n");
}
void initialize(char english[], char piglatin[])
{
int count;
for(count =0; count<80;++count)
{
english[count]=piglatin[count]=' ';
}
return;
}
/* Scan the english test and determine the number of words */
int countwords(char english[])
{
int count, words =1;
for ( count =0;count <79;++count)
{
if(english[count]==' ' && english[count+1]!=' ')
++words;
}
printf("%d\n",words);
return (words);
}
/* convert each words in to piglatin*/
void convert ( int words, char english[], char piglatin[])
{
int n, count;
int m1=0;
int m2;
/* convert each word */
for ( n=1;n<=words;++n)
{
/* locate the end of the current word*/
count = m1;
printf ("\ before conversion word contents: %d\n", count);
while ( english[count]!=' ')
{
m2=count++;
}
printf ("\ before conversion word contents: %d\n", m2);
/* transpose the first letter and add 'a', 'y'*/
for (count =m1;count<m2;++count)
{
piglatin[count+(n-1)]=english[count+1];
}
piglatin[m2+(n-1)] = english[m1];
piglatin[m2+1] = 'a';
piglatin[m2+2] = 'y';
m1=m2+3;
printf ("\ Converted word contents: %s\n", piglatin);
}
return;
}
void writeoutput( char piglatin[])
{
int count =0;
for (count =0; count <80; ++count)
{
putchar(piglatin[count]);
}
printf ("\n");
return;
}
I see various problems here:
Alex -> lex,Aay: You should check for punctuation marks when determining the end of the words, thus inserting the Aay part before the comma character
Alex -> lex,Aay: Every character from the start of a word should be converted to lowercase and the resulting first character should be converted to upper case respectively
Now the conversion function: I have changed it a bit to get you started; it should work now ( at least it does with your test string ) without taking 1 and 2 into account though
void convert(int words, char english[], char piglatin[])
{
int estart = 0;
int ppos = 0;
int m2;
for (int n = 0; n < words; n++)
{
//locate the start of the current word, to make
//sure something like this is converted:
//"Alex, how are you"
while (english[estart] == ' ')
{
//make sure we do not exceed the strings boundaries!
if (english[estart] == '\0')
{
return;
}
estart++;
}
//locate the end of the word
int eend = estart;
while (english[eend] != ' ')
{
//never forget to check for the end of the string
if (english[eend] == '\0')
{
break;
}
eend++;
}
/* transpose the first letter and add 'a', 'y'*/
for (int i = estart+1; i < eend; i++, ppos++)
{
piglatin[ppos] = english[i];
}
piglatin[ppos++] = english[estart];
piglatin[ppos++] = 'a';
piglatin[ppos++] = 'y';
//dont forget to add a whitespace or your string might behave
//very stangely!
piglatin[ppos++] = ' ';
estart = eend;
printf("\ Converted word contents: %s\n", piglatin);
}
}
I hope this gets you started in the right direction.
Please also check your array sizes for english and piglatin. The string for piglatin is alway longer than the english one but your array sizes are the same! Also i would advise you add some boundary checks to make sure you do not leave the array boundaries.

Program that checks if an array is a palindrome

I'm trying to create a program that checks if a given array/string is a palindrome or not and its not working. The program just prints "0" on every given array, even on palindromes.
int main()
{
char string[100]= {0};
char stringReverse[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
strcpy(stringReverse , string); // This function copies the scanned array to a new array called "stringReverse"
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// This while reverses the array and insert it to a new array called "stringReverse"
while(firstLetter < lastLetter)
{
temp = stringReverse[firstLetter];
stringReverse[firstLetter] = stringReverse[lastLetter];
stringReverse[lastLetter] = temp;
firstLetter++;
lastLetter--;
}
printf("%s %s", stringReverse, string);
if ( strcmp(stringReverse , string) == 0)
{
printf("1");
}
else
{
printf("0");
}
}
Lets say we implement a simple fun to do that
int check_palindrome (const char *s) {
int i,j;
for (i=0,j=strlen(s)-1 ; i<j ; ++i, --j) {
if (s[i] != s[j]) return 0; // Not palindrome
}
return 1; //Palindrome
}
I think this is far more simpler ;)
For the code posted in question:
Be aware of fgets(). It stops in the first '\n' or EOF and keeps the '\n' character.
So if you give radar for ex, the result string will be "radar\n", which doesn't match with "\nradar"
The Problem:
Let's say you enter the string RACECAR as input for your program and press enter, this puts a newline character or a '\n' in your buffer stream and this is also read as part of your string by fgets, and so your program effectively ends up checking if RACECAR\n is a palindrome, which it is not.
The Solution:
After you initialize lastLetter to strlen(string) - 1 check if the last character in your string (or the character at the lastLetter index is the newline character (\n) and if so, decrease lastLetter by one so that your program checks if the rest of your string (RACECAR) is a palindrome.
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
// Add these 2 lines to your code
// Checks if the last character of the string read by fgets is newline
if (string[lastLetter] == '\n')
lastLetter--;
fgets adds a '\n' at the end.
So if the user entered "aba", string contains "aba\n".
reverseString contains "\naba".
So it doesn't match.
After the fgets, add this code
int l = strlen(string) - 1;
string[l] = 0;
This will strip out the '\n' at the end before copying it to reverseString.
That aside, you can do this whole program inplace without the need of a second buffer or strcpy or strlen calls.
You have several issues in your code:
first you forgot the last closing brace };
then you forgot to remove the trailing \n (or maybe also \r under Windows) in string;
you don't need to revert the string into a new string; a one-pass check is enough:
Here is a working code:
#include <stdio.h>
#include <string.h>
int main()
{
char string[100]= {0};
int temp = 0;
int firstLetter = 0;
int lastLetter = 0;
printf("Please enter a word or a sentence: ");
fgets(string, 100, stdin);
firstLetter = 0;
lastLetter = strlen(string) - 1; //because in array, the last cell is NULL
while ((string[lastLetter]=='\n')||(string[lastLetter]=='\r')) {
lastLetter--;
}
// This while reverses the array and insert it to a new array called "stringReverse"
temp = 1;
while(firstLetter < lastLetter)
{
if (string[firstLetter] != string[lastLetter]) {
temp = 0;
break;
}
firstLetter++;
lastLetter--;
}
if ( temp )
{
printf("1");
}
else
{
printf("0");
}
}
You can do it by this simpleway also.
#include <stdio.h>
#include <string.h>
int main()
{
char string[10], revString[10];
printf("Enter string for reversing it...\n");
scanf("%s", string);
int stringLength = strlen(string);
for(int i = 0; string[i] != '\0'; i++, stringLength--)
{
revString[i] = string[stringLength - 1];
}
if(strcmp(string, revString) == 0)
printf("Given string is pelindrom\n");
else
printf("Given string is not pelindrom\n");
}
#include<stdio.h>
#include<string.h>`enter code here`
void fun(char *a);
int main ()
{
char p[100];
char *s=p;
printf("enter the string");
scanf("%[^\n]",s);
fun(s);
}
void fun(char *a)
{
if(*a && *a!='\n')
{
fun(a+1);
putchar(*a);
}
}
// use this approach better time complexity and easier work hope this helps

Logical error in recursive function

I'm writing a program to check whether a string is palindrome or not using recursion.Palindrome string is the one that can be read backwards just the same as reading it forward. However following is my code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int num;
printf("Enter the number of characters in your string\n");
scanf("%d",&num);
char string[num];
char string2[num];
int i;
printf("Enter your string\n");
for (i=0;i<num;i++)
{
scanf("%c",&string[i]);
}
fillString(string,string2,num);
int palin = isPalind(string,string2,num);
if (palin) printf("The string you entered is palindrome");
else printf("The string you entered is not palindrome");
return 0;
}
int isPalind(char string[],char string2[],int num)
{
int i=0;
while (i<num)
{
if (string[i]!=string2[i])
{
i++;
return 0;
}
else{
i++;
return 1*isPalind(string,string2,num);
}
}
}
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<num;i++)
string2[i-1]=string[num-i];
}
I have a logical error, the program compiles fine and executes but it always gives out "The string is not palindrome"
In the fillString the loop is iterating num-1 times (i is from 1 to num-1), so not the whole string is copied. The first character of the original string is omitted. You should do
for (i=1;i<=num;i++) ...
As for the recursive function, it is not really recursive. In recursive call modified input should be passed, but in your case exactly the same input is passed. So in case of true palindrome, it's likely you will get stack overflow due to non-termination. I would propose another approach, to work with single string recursively:
1) Base case: String is a palindrome if of length 0 or 1
2) Recursion step: String is a palindrome if the first character equals to the last and the string without first and last characters is palindrome.
Is your fillString() function reversing your string as expected? It looks like the first letter of string1 is not getting added into the last position of string2 because the for loop stops when i < num fails. Try switching it to i <= num and seeing if that helps.
Double-check this example:
Given: String1 = "Hello". String2 = null for now. num = 5.
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<num;i++)
string2[i-1]=string[num-i];
}
When i = 4, you have string2 = 'olle'. When i = 5, the for loop condition fails, so it doesn't populate string2[4] = 'H'.
updated:
void fillString(char string[],char string2[],int num)
{
int i;
for (i=1;i<=num;i++)
string2[i-1]=string[num-i];
}
The both functions are wrong. They can be written the following way
int isPalind( const char string[], const char string2[], int num )
{
return ( num == 0 ) ||
( string[0] == string[--num] && isPalind( string + 1, string2, num ) );
}
void fillString( const char string[], char string2[], int num )
{
int i;
for ( i = 0; i < num; i++ ) string2[i] = string[num-i-1];
}
If you need not necessary a recursive function then you could use simply standard function memcmp that to determine whether two strings are equal.

Problems with simple c task

So after a few years of inactivity after studying at uni, I'm trying to build up my c experience with a simple string reverser.
here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
*
*/
int main(int argc, char** argv) {
reverser();
return(0);
}
int reverser(){
printf("Please enter a String: ");
//return (0);
int len;
char input[10];
scanf("%s",&input);
int quit = strcmp(input,"quit");
if(quit == 0){
printf("%s\n","Program quitting");
return(0);
}
len = strlen(input);
printf("%i\n",len);
char reversed[len];
int count = 0;
while (count <= (len-1)){
//printf("%i\n",(len-count));
reversed[count] = input[(len-1)-count];
count++;
}
//printf("%s\n",input);
printf(reversed);
printf("\n");
reverser();
}
When I input "hello", you would expect "olleh" as the response, but I get "olleh:$a ca&#",
How do I just get the string input reversed and returned?
Bombalur
Add a '\0' at the end of the array. (as in, copy only chars until you reach '\0' - which is the point at array[strlen(array)], then when you're done, add a '\0' at the next character)
Strings are conventionally terminated by a zero byte. So it should be
char reversed[len+1];
And you should clear the last byte
reversed[len] = (char)0;
you forgot the \0 at the end of the string
This is because you are creating an array with size 10. When you take in some data into it (using scanf) and the array is not filled up completely, the printf from this array will give junk values in the memory. You should iterate for the length of the input by checking \n.
must have a size + 1 to string length so that you can have a \0 at the end of string that will solve your problem
The following is a (simple and minimal implementation of) string reverse program (obviously, error conditions, corner cases, blank spaces, wider character sets, etc has not been considered).
#include <stdio.h>
int strlen(char *s)
{
char *p = s;
while (*p)
p++;
return p - s;
}
char * strrev(char a[])
{
int i, j;
char temp;
for (i=0, j=strlen(a)-1 ; i<j ; i++, j--) {
temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
int main()
{
char str[100];
printf("Enter string: ");
scanf("%s", str);
printf("The reverse is %s \n", strrev(str));
return 0;
}
Hope this helps!

Resources