3

I have to request a first word to compare it to a second word, and replace all occurrences with '*' working character by character without using the <string.h> library.

Exercise: Write a C program that receives two words entered from the keyboard as input. Consider that each word can contain a maximum of 30 characters. The program must be case sensitive, ie it must distinguish lowercase letters from uppercase letters and must also be able to analyze numbers, symbols and punctuation marks. The program must replace each occurrence of the second word in the first word with the '*' character. For example, enter the words

abchdfffchdchdtlchd

and

chd

the program should display the word

ab*fff**tl*
#include <stdio.h>
#include <stdlib.h>

#define MAX 30

int main()
{
    char string1 [MAX+1], string2 [MAX+1],replace = '*';
    int nChar1 = 0, nChar2 = 0, flag = 0, h=0;

    printf ("Enter a word (max 30 characters): ");

    scanf ("%[^\n ]", &string1);
    fflush (stdin);

    printf ("\nYou wrote this word: %s\n", string1);

    for (int i=0; i<(MAX+1); i++)
    {
        if (string1[i] == '\0')
            break;
        else
            nChar1++;
    }

    printf ("The characters are: %d\n", nChar1);

    printf ("\nEnter a word you want to change with '*' in the first string: ");

    scanf ("%[^\n ]", &string2);
    fflush (stdin);

    printf ("\nYou wrote this word: %s\n", string2);

    for (int j=0; j<(MAX+1); j++)
    {
        if (string2[j] == '\0')
            break;
        else
            nChar2++;
    }

    printf ("The characters are: %d\n", nChar2);

    for (int i=0, j=0, z=0; i<nChar1, j<nChar2; i++, j++)
    {
            if (string1[i] == string2[j])
            {
                for (int k=0; k<nChar2; k++)
                {
                    if (string1[i+k] == string2[j+k])
                        flag++;
                    else
                        flag=0;
                }
            }

            j=0;

            if (flag == nChar2)
            {
                string1[h] = replace;
                h++;
            }
            else
            {
                h++;
            }
            string1[z+1] = string1[h];
    }

    printf("\n%s", string1);

    return 0;
}
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
ilMichigan
  • 49
  • 5
  • OT: There are two unrelated problems in the code you show... First the expected argument for the `%[` format is a `char *`. Which you get from either `&string1[0]` or by letting the array decay as such using plain `string1`. The expression `&string1` is a pointer to the array itself, and will have the type `char (*)[31]` which is not expected. – Some programmer dude Nov 09 '20 at 13:43
  • (continued) Secondly, passing an input-only stream to `fflush` is explicitly mentioned in the C specification as leading to *undefined behavior*. There are better and more portable ways to skip leading white-space, like adding a single leading space in the format specifier, as in `" %[^\n]"`. – Some programmer dude Nov 09 '20 at 13:43
  • Make the list of all functions of `string.h` you need. Rewrite these functions. Use them. – Jabberwocky Nov 09 '20 at 13:44
  • Now for your actual problem and question: What *is* your problem? What *is* your question? Please take some time to read [ask], as well as [this question checklist](https://codeblog.jonskeet.uk/2012/11/24/stack-overflow-question-checklist/). Then [edit] your question to improve it. – Some programmer dude Nov 09 '20 at 13:45

1 Answers1

1

Decompose the task into several separate functions.

One function will calculate the length of the passed string. Another function will find a substring in a string. And the third function will do the replacement of the target substring with a character.

Here is a demonstrative program.

#include <stdio.h>

size_t length( const char *s )
{
    size_t n = 0;
    
    while ( *s++ ) ++n;
    
    return n;
}

char * find_substring( const char *s1, const char *s2 )
{
    size_t n1 = length( s1 );
    size_t n2 = length( s2 );

    const char *target = NULL;

    if ( ( *s2 != '\0' ) && !( n1 < n2 ) )
    {
        for ( size_t i = 0, n = n1 - n2 + 1; !target && i < n; i++ )
        {
            if ( s1[i] == s2[0] )
            {
                size_t j = 1;
                while ( j != n2 && s1[i+j] == s2[j] ) ++j;
                if ( j == n2 ) target = s1 + i;
            }
        }
    }
    
    return ( char * )target;
}

char * replace( char *s1, const char *s2, char c )
{
    int done = 0;
    size_t n2 = length( s2 );
    
    for ( char *p = s1, *q = s1; !done; )
    {
        char *tmp = find_substring( q, s2 );
        
        if ( tmp == NULL )
        {
            if ( p != q )
            {
                while ( ( *p++ = *q++ ) );
            }
            done = 1;
        }
        else
        {
            if ( p == q ) 
            {
                p = tmp;
            }
            else
            {
                while ( q != tmp ) *p++ = *q++;
            }
            *p++ = c;
            q = tmp + n2;
        }
    }
    
    return s1;
}

int main(void) 
{
    {
        char s1[] = "abc";
        const char *s2 = "chd";
    
        puts( replace( s1, s2, '*' ) );
    }

    {
        char s1[] = "achd";
        const char *s2 = "chd";
    
        puts( replace( s1, s2, '*' ) );
    }

    {
        char s1[] = "chda";
        const char *s2 = "chd";
    
        puts( replace( s1, s2, '*' ) );
    }

    {
        char s1[] = "chd";
        const char *s2 = "chd";
    
        puts( replace( s1, s2, '*' ) );
    }
    
    {
        char s1[] = "abchdfffchdchdtlchd";
        const char *s2 = "chd";
    
        puts( replace( s1, s2, '*' ) );
    }
    
    return 0;
}

The program output is

abc
a*
*a
*
ab*fff**tl*
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335