'problem with replacing characters in a string
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);
}
Solution 1:[1]
You have a few problems:
strlenreturns asize_ttype, so it's best forito match that typeiis uninitialized, and should begin at 0 because arrays in C are 0-based (first elements starts at position 0, not 1).str1[i]%2is incorrect math.. you want to do modulo on the indexi, 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);
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
for (size_t i=0; str1[i]; i=i+2) {
str1[i]='A';
if (!str1[i+1]) break;
}
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
