I have to make a function, that will code my sentence like this: I want to code all words with an o
, so for example I love ice cream
becomes I **** ice cream
.
But my function ignores the result of strchr
. And I don't know why.
This is my code:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define LEN 1000
char *Shift(char *str, char *let) {
const char *limits = " ,-; .";
char copy[LEN];
strcpy(copy, str);
char *p;
char *ptr;
ptr = strtok(copy, limits);
for (int j = 0; ptr != NULL; ptr = strtok(NULL, limits), j) {
int len = 0;
if (strchr(ptr, let) != NULL) {
p = strstr(str, ptr);
for (int i = 0; i < strlen(ptr); i ) {
p[i] = "*";
}
}
}
return str;
}
int main() {
char *s = Shift("I love my cocktail", "o");
puts(s);
}
Expected output is: I **** my ********
but I've got just printed the original string
CodePudding user response:
For starters the function strchr
is declared like
char *strchr(const char *s, int c);
that is its second parameter has the type int
and the expected argument must represent a character. While you are calling the function passing an object of the type char *
that results in undefined behavior
if (strchr(ptr, let) != NULL) {
It seems you mean
if (strchr(ptr, *let) != NULL) {
Also you may not change a string literal. Any attempt to change a string literal results in undefined behavior and this code snippet
p = strstr(str, ptr);
for (int i = 0; i < strlen(ptr); i ) {
p[i] = "*";
}
tries to change the string literal passed to the function
char *s = Shift("I love my cocktail", "o");
And moreover in this statement
p[i] = "*";
you are trying to assign a pointer of the type char *
to a character. At least you should write
p[i] = '*';
If you want to change an original string you need to store it in an array and pass to the function the array instead of a string literal. For example
char s[] = "I love my cocktail";
puts( Shift( s, "o" ) );
Pay attention to that there is no great sense to declare the second parameter as having the type char *. Declare its type as char.
Also the function name Shift
is confusing. You could name it for example like Hide
or something else.
Here is a demonstration program.
#include <stdio.h>
#include <string.h>
char * Hide( char *s, char c )
{
const char *delim = " ,-; .";
for ( char *p = s = strspn( s, delim ); *p; p = strspn( p, delim ) )
{
char *q = p;
p = strcspn( p, delim );
char *tmp = q;
while ( tmp != p && *tmp != c ) tmp;
if ( tmp != p )
{
for ( ; q != p; q ) *q = '*';
}
}
return s;
}
int main( void )
{
char s[] = "I love my cocktail";
puts(s);
puts( Hide( s, 'o' ) );
}
The program output is
I love my cocktail
I **** my ********
The for loop
for ( ; q != p; q ) *q = '*';
within the function can be rewritten as a call of memset
memset( q, '*', p - q );
CodePudding user response:
Here is a simpler alternative:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
char *Shift(char *str, char *let) {
size_t pos = 0, pos1, pos2;
for (;;) {
pos = strcspn(str pos, let);
if (str[pos] == '\0')
break;
for (pos1 = pos; pos1 > 0 && isalpha((unsigned char)str[pos1 - 1]))
str[--pos1] = '*';
while (isalpha((unsigned char)str[pos])
str[pos ] = '*';
}
return str;
}
int main() {
char s[] = "I love my cocktail";
puts(Shift(s, "o"));
return 0;
}