Home > Back-end >  Swap characters in string using pointer
Swap characters in string using pointer

Time:06-13

I'm trying to create a program that receives a word and two chars to be replaced inside that word using pointers, but I cannot figure it out how.

my .h file:

typedef struct pointer{
    char message[100];
    char start;
    char end;
} tPointer;

tPointer readMsg();

my .c file:

tPointer readMsg(){
    tPointer nPointer;

    printf("Input word, char start and char end (between spaces): ");
    scanf("%s %c %c", nPointer.message, &nPointer.start, &nPointer.end);

    return(nPointer);
}

my main.c file:

int main(){

    tPointer pointer;

    pointer = readMsg();

    printf("%s, %c, %c\n", pointer.message, pointer.start, pointer.end);
    
    for (int i = 0; pointer.message[i] != '\0';   i) {
        if (pointer.start == pointer.message[i])
        {
            printf("tem: %c\n", pointer.message[i]);
        }
    }

    return 0;

}

The start input is the character inside message that I want to change, the end input is the character I will trade with start to create the new message

I have to swap the characters inside that for loop, right?

Example1:

message = stack
start = a
end = b

new message = stbck

Example2:

message = overflow
start = o
end = z

new message = zverflzw

CodePudding user response:

From your updated examples, it looks like you want to find the first occurrence of start and replace that character with end. Much of the confusion with your question stems from the fact that start and end have nothing to do with what it is you are attempting to do. Use descriptive names to help keep your logic straight, e.g.

#include <stdio.h>

#define MAXC 1024   /* if you need a constant, #define one (or more) */

typedef struct {
    char message[MAXC];     /* don't use magic-numbers, use a constant */
    char find;              /* use descriptive names */
    char replace;
} tPointer;

(note: the struct-tag pointer was unused and omitted)

With your tPointer readMsg() function, you have no way to tell if the input succeeded or if the string and two characters requested were actually entered. It is critical that you validate EVERY input and validate the input matches what was requested.

Rather than returning type tPointer (which if uninitialized provides no way to tell what was entered), pass a tPointer pointer as a parameter and return type int with 0 on failure and 1 on success (or vice-versa -- up to you). That way you can check the return in the caller and know whether readMsg() succeeded or failed, e.g.

/* choose return type that can indicate success/failure
 * of input operation.  Returns 1 on success, 0 otherwise
 */
int readMsg (tPointer *tp)
{
    char buf[MAXC];       /* buffer to hold line of input */
    
    /* read input into buf */
    fputs ("Input word, find char, replace char (between spaces): ", stdout);
    if (!fgets (buf, MAXC, stdin)) {  /* always validate EVERY input */
        puts ("(user canceled input)");
        return 0;
    }
    
    /* separate using sscanf() -- always validate correct input */
    if (sscanf (buf, "%s %c %c", tp->message, &tp->find, &tp->replace) != 3) {
        fputs ("error: invalid input.\n", stderr);
        return 0;
    }

    return 1;       /* return success */
}

(note: the user generating a manual EOF to cancel input by pressing Ctrl d (or Ctrl z on windows) is valid input by the user that should be handled)

Also note, that a larger buffer was used to read the entire line into buf and then separate the string and characters in buf using sscanf(). This insures that if any EXTRA characters are entered by the user they are read and discarded. Failure to do so would leave any extra characters in stdin (unread) just waiting to bite you on your next attempted read (such as if you were doing the read in a loop to let the user enter more than one set of data)

Since you wrote a function for readMsg(), you may as well write another for replaceChar(). The return type can be int again and you can pass your tPointer pointer as a parameter, returning 1 on success or 0 if the find character was not found in message, e.g.

/* replace 'find' char with 'replace' char.
 * returns 1 on success, 0 if find char not found.
 */
int replaceChar (tPointer *tp)
{
    for (int i = 0; tp->message[i]; i  ) {    /* loop over each char */
        if (tp->message[i] == tp->find) {     /* check if find char */
            tp->message[i] = tp->replace;     /* replace it */
            return 1;                         /* return success */
        }
    }
    
    return 0;       /* return failure - char not found */
}

Now in main() check the return of each function to ensure both succeed before outputting the results. On failure, handle the error. You can do something similar to:

int main (void) {
    
    tPointer ptr = { .message = "" };   /* initialize struct all zero */
    
    if (!readMsg (&ptr)) {              /* validate read */
        return 1;                       /* handle failure */
    }
    
    if (!replaceChar (&ptr)) {          /* validate replacement */
        fprintf (stderr, "error: char not found '%c'.\n", ptr.find);
        return 1;                       /* handle failure */
    }
    
    /* output results */
    printf ("find    = %c\nreplace = %c\nupdated string: %s\n", 
            ptr.find, ptr.replace, ptr.message);
}

(note: you can paste the 4-pieces of code together for the complete program)

Example Use/Output

A valid replacement:

$ ./bin/tpointer-find-replace
Input word, find char, replace char (between spaces): Overflow o E
find    = o
replace = E
updated string: OverflEw

Invalid input:

$ ./bin/tpointer-find-replace
Input word, find char, replace char (between spaces): Overflow o
error: invalid input.

Character Not Found:

$ ./bin/tpointer-find-replace
Input word, find char, replace char (between spaces): Overflow s y
error: char not found 's'.

User cancels input by generating manual EOF:

$ ./bin/tpointer-find-replace
Input word, find char, replace char (between spaces): (user canceled input)

Let me know if you have further questions.

  •  Tags:  
  • c
  • Related