finding substring from a main string - c

My assignment is to find a substring from main string and return the pointer to the first character of the substring that is in mainstring and it needs to stop searching after "?" and the code has to be done without string.h . My code to me is working perfectly but the automatic checker says otherwise, checker says this
test_source.c:195:F:test_es_strstr:test_es_strstr:0: [07_altstring.d] Wrong return value with string "Foobarbaz?asd:w" and substring "baz?": Got 0x72, expected 0x7ffeb8b8a306
So the checker says that my pointer isn't in the right place.. but for me it is, need help.
My code =
const char *es_strstr(const char *str1, const char *str2) {
int i = 0;
int j = 0;
while (str1[j] != '?') ///function has to stop the search to
/// a question mark
{
if (*str1 == str2[i]) ///comparing main string first character
/// to substring first character
{
i++;
++str1;
if (*str1 == str2[i]) ///if first ones are match then look
/// for the next character matching
{
i++;
++str1;
if (*str1 == str2[i]) /// finally if 2nd is match then 3rd
{
--str1;
--str1;
printf("%c\n", *str1);
return *str1;
}
}
}
j++;
i = 0;
++str1;
}
return NULL; ///if nothing matches need to return NULL
int main(void) {
char *main = "Foobarbaz?asd:w";
char *sub = "baz?";
es_strstr(main, sub);
}

I think you should return pointer, i.e.
return str1;
instead of
return *str1;
*str means character pointed by str1

Related

String in C: replace characters with each other

For example, I choose a string "sdoeoeeoasd". I should replace all the 'o' with 'e' and vice versa: "sdeoeooeasd". I intend to do this with the string lib.
I found a pretty similar question (Standard function to replace character or substring in a char array?), but I don't get how to make the code work according to my condition. It happens that the first occurence of the character is replaced, and then the only one character replaces:
char* replace_char(char* str, char find, char replace){
char temp = find;
char *current_pos = strchr(str,find);
char *current_posc2 = strchr(str,replace);
while (current_pos) {
*current_pos = replace;
current_pos = strchr(current_pos,find);
}
while (current_posc2) {
*current_posc2 = find;
current_posc2 = strchr(current_posc2, replace);
}
return str;
}
With c1='e' and c2='o' I get:
I have a thought about adding the third temp variable, but my suggestions of its implementation were wrong and didn't work.
Another solution:
int i=0;
while(ch[i])
{
if(ch[i] == 'e')
ch[i]='o';
else if(ch[i] == 'o')
ch[i]='e';
i++;
}
Do one loop:
char *replace_char(char *str, char find, char replace) {
char *str2 = str; // save str for return value
while (*str2) {
if (*str2 == find) *str2 = replace;
else if (*str2 == replace) *str2 = find;
str2++;
}
return str;
}
Your code doesn't work because it replaces all of the first character with the second character, then replaces all of the second character with the first character. It completely undoes the work of the first step in the second step. It's much simpler to just iterate through the string one character at a time, like in Bouraoui Al-Moez L.A's code.
there is no need to use two loops
char *replace_char(char *str, char find, char replace) {
char *ptr = str;
while (*ptr) {
if (*ptr == find) *ptr = replace;
else if (*ptr == replace) *ptr = find;
ptr++;
}
return str;
}
also you can use syntax array
int j=0;
while(str[j] !='\0') // will loop on your string till the end of it
{
if(str[j] == 'e') // if char=e will be o
str[j]='o';
else if(str[j] == 'o') // if char=o will be e
str[j]='e';
j++;
}
```````````````````````

Finding an index of array in C

i wanted to write a code which would allow me to find a position of a fist occurence of a letter, this is what i have come up so far. As you can see, what the function returns is actually a value and not the index. Is there a way to find it without simply giving the initial value of index as in the code no.2?
char *recFirstPosition(char * source, int letter)
{
if(*source == letter)
return *source;
if (*source =='\0')
return 0;
recFirstPosition(++source, letter);
}
char *recFirstPosition(char * source, int letter, int index)
{
if(*(source+index) == letter)
return index;
if (*(source+index) =='\0')
return 0;
recFirstPosition(source, letter, ++index);
}
Simply detach * from the first return and add return for the recursive call of your first version.
char *recFirstPosition(char * source, int letter)
{
if(*source == letter)
return source;
if (*source =='\0')
return 0;
return recFirstPosition(++source, letter);
}
It will make the code work. Your first version causes a type error.
The following is more readable version than the above:
char *recFirstPosition(char *source, char letter)
{
if (*source == '\0')
return NULL;
else if (*source == letter)
return source;
else
return recFirstPosition(++source, letter);
}
The above code also changed the type of the second parameter, but is written mostly inspired by several comments (Special thanks to Yuli and Dmitri).
And you may use the function as follows:
int main()
{
char *s = "Hello";
char *p = recFirstPosition(s, 'l');
if (p != NULL) {
int index = p - s;
printf("%s[%d] = %c\n", s, index, *p);
}
return 0;
}
Here is what I think could work. Please test it more since I did not have enough time to work with it
Edit: This return the position of the last occurrence but should give you enough to work with.
Edit2: Updated the function so now it works for
#include <stdio.h>
char *recFirstPosition(const char *s, int c, char *find){
if(s==NULL) return NULL;
if(*s == '\0') return (c == '\0') ? (char*)s : find;
if(*s == c) return (char*) s;
return recFirstPosition(s + 1, c, *s == c ? (char*)s : find);
}
int main ()
{
char str[] = "This is a sample string";
char * pch;
printf ("Looking for the 's' character in \"%s\"...\n",str);
pch=recFirstPosition(str,'s', NULL);
// Uncomment the while loop to get all instances positions
//while (pch!=NULL)
//{
printf ("found at %d\n",pch-str+1);
// pch=recFirstPosition(pch+1,'s',NULL);
//}
return 0;
}
output
Looking for the 's' character in "This is a sample string"...
found at 4

strchr implementation in c is it possible to make this work?

please help me out , I'm trying to implement strchr and I still get Null when I run this code... what is it wrong with it?
char *ft_strchr(const char *str, int c)
{
int i;
char *temp;
i = 0;
while (str[i])
{
if (str[i] == c)
{
*temp = str[i];
return (temp);
}
else
return (NULL);
i++;
}
return (str);
}
char* ft_strchr(const char *str, int c){
size_t i;
char *temp;
i = 0;
while (str[i])
{
if (str[i] == c)
{
temp = &str[i];
return temp;
}
i++;
}
if(str[i]==c)
{
return &str[i];
}
return NULL;
// You need to return NULL after scanning whole line..
// Or it will send NULL checking after 1st character
}
strchr is supposed to return a pointer to the matching character in the string. You're returning a pointer, but it doesn't point into the string. You never initialized it, so it doesn't point anywhere.
Change
*temp = str[i];
to:
temp = &str[i];
the following code:
makes use of the fact the C passes by value rather than by reference
eliminates the code clutter,
uses a for() statement so the compiler handles all the loop details,
eliminates all the code clutter
Note: this kind of expression: *str evaluates to true, except when the char pointed at is '\0'.
So the below code walks through the passed in char string, terminating on either of two conditions.
1) a matching char is found in the string or
2) end of string is encountered.
The return statement returns NULL if end of string is encountered, else returns the address of where the matching char is first found in the string.
char *ft_strchr(const char *str, int c)
{
for( ; *str && (*str != c); str++ ) ;
return ( *str? str : NULL);
}

How can I check if an element of an array is the terminating element and return a new line?

I need to check an array like 'Hello' and check when the terminating element is and then return a new line due to it. I've been trying code like this:
char * my_strchr(const char * string, int ch)
{
int count;
int length = strlen(string);
for(count = 0; count < length; count++)
{
if(string[count] == '\0')
{
return '\n' ;
}
}
My compiler does not like when I use these for some reason. In the function declaration for string it reads const char * string
The strlen function returns the string length without the NULL terminator. What this means is that your function does not return a char pointer, because your code will never get to the condition string[count] == '\0'.
Further, even if you did reach that condition, you are returning a char, not a char *, which is an error. Your function agreed to return a char * so some kind of char * needs to be returned, even if it points to NULL.
It also isn't clear from your function code, because it lacks a terminating bracket, but your function may never return anything.
Kind of guessing from your description, but perhaps something like this?
char * my_strchr(const char * string, int ch) {
int i;
int c;
for (i = 0; (c = string[i]) != '\0'; ++i) {
if (c == ch) return string + i; /* aka &string[i] */
}
return "\n"; /* got to the end w/o finding ch in string */
}
char *my_strchr(const char *string, int ch){
if(*string == '\0')
putchar('\n');//side effect
while(*string){
if(*string == ch)
return (char*)string;
++string;
}
return *string == ch ? (char*)string : NULL;
}

Function To Match The Last Character Of A String

So this is a problem : Write the function strend(s,t), which returns 1 if the char t occurs at the end of the string s, and zero otherwise.
This is my code:
int strend(char*, char);
int main()
{
int n = -1;
char str1[6] = "Hello", char1;
printf("Enter a character: ");
char1 = getchar();
n = strend(str1, char1);
printf("n = %d", n);
return 0;
}
int strend(char* str1, char str2)
{
while(*str1 != '\0')
{
str1++;
}
if(*str1 == str2)
{
return 1;
}
else
{
return 0;
}
}
However the character matching does not perform as intended. Where the mistake?
Thanks.
You're comparing the character to the \0 string terminator.
int strend(char* str1, char str2)
{
if (*str1 == '\0') {
return 0;
}
while(*str1 != '\0') /* removed ; that shouldn't be there */
{
str1++;
}
/* at this point, str1 is pointing to the 0-terminator */
str1--; /* pointer now points to last character of the string, not 0-terminator */
if(*str1 == str2)
{
return 1;
}
else
{
return 0;
}
}
I'll try my own explanation.
Suppose your while() loop has reached the last non-zero character of your string str1.
In this case, the line while( *str1 != '\0' ) is "asking" if this character is zero or not.
Since it is the character that you are looking for, logically it cannot be '\0'.
Then the comparison expressión is "true", and the increment str1++; is performed.
Now *str1 is the character '\0', and the immediate next iteration gives "false" when evaluating *str1 != '\0'.
Then the while() block is finished, and the program continues in the line if(*str1 == str2).
Here, the value *str1, which is '\0', is compared against str2, giving always the result "false".
However, the desired character is still in the immediate previous memory position of str1.
So, you can decrement str1 and then comparing, or well you can compare str2 against (str1 - 1).
// Option 1
str1--;
if(*str1 == str2)
//Option 2
if ((str1 - 1) == str2)
Without any error checking, (you can do that) here is a one liner that will check that the last character is matched:
int strend(char* str1, char str2)
{
return ((str1[strlen(str1)-1]) == str2)?(1):(0);
}
Or in a more readable form:
int strend(char* str1, char str2)
{
return ((str1[strlen(str1)-1]) == str2);
}

Resources