Home > Software engineering >  problem with replacing characters in a string
problem with replacing characters in a string

Time:04-16

Currently, I'm trying to write a code that replaces the 1st, 3rd, 5th character, ...(odd numbers) in a string with the letter 'A'.
E.x: 'hello world' will be 'AeAlA AoAlD'.
But instead, I'm getting 'hAllA AArld' which is not the result what I wanted.
Can someone help me, please?

Edit: The problem is that I checked the ASCII table, the value of the letter 'e', 'o', 'w' in ASCII table is an odd number and the other letters are not. So my program is checking if the value of the letters is an odd number or not to replace with 'A' and not the 1st, 3rd, 5th character in the string.

Below is the code:

#include <stdio.h>
#include <string.h>
int main() {
    char str1[100];
    scanf("%[^\n]", str1);
    for (int i=0; i<strlen(str1); i  ) {
        if (str1[i]%2==1) {
            str1[i]='A';
            }
        }
    printf("%s", str1);
}

CodePudding user response:

You have a few problems:

  1. strlen returns a size_t type, so it's best for i to match that type
  2. i is uninitialized, and should begin at 0 because arrays in C are 0-based (first elements starts at position 0, not 1).
  3. str1[i]%2 is incorrect math.. you want to do modulo on the index i, not the actual character in the string.

This is a fixed up version:

for (size_t i=0; i<strlen(str1); i  ) {
    if (i%2==0) {
        str1[i]='A';
    }
}
printf("%s", str1);

Demonstration

Update

As recommended in the comments by @chux, it's more efficient to drop strlen and instead check for the NULL character as the terminating condition in the loop. However, for dixie cup programs like this, I'm dubious much performance gains would be realized, and ultimately recommend using whatever code/method is the most clear to you:

Method 1

for (size_t i=0; str1[i]!='\0'; i  ) {
//    or simply  str1[i];   since 0 will evaluate to false
   if (i%2==0) {
        str1[i]='A';
   }
}

Furthermore, you could bypass the modulus entirely, and just advance i by 2 each time in the loop, since it's the even array positions (odd character counts) that you want:

Method 2

for (size_t i=0; i<strlen(str1); i=i 2) {
   str1[i]='A';
}

Going down the road of efficiency (and knowing that you won't change the length of the string in-loop), you could also

Method 3

size_t len = strlen(str1);  // ensure strlen is only called once
for (size_t i=0; i<len; i=i 2) {
   str1[i]='A';
}

or, bypassing strlen entirely:

Method 4

// must have a string of length >= 2 for this to work
for (size_t i=0; str[i] && str[i 1]; i=i 2) {
   str1[i]='A';
}

Update 2

After some experimenting on godbolt, @chux is right. Even with optimizations turned up, strlen is called every time thru the loop for Method 2. It actually looks like to me that Method 3 is the most efficient. I'm no assembly expert, but this bypasses calling strlen at all, and looks like this has the fewest instructions in the loop. I've created this playground here for anyone interested.

  • Related