替换字符串中的字符的问题

problem with replacing characters in a string

目前,我正在尝试编写一个代码,用字母 'A'.
替换字符串中的第 1、3、5 个字符...(奇数) E.x:'hello world' 将是 'AeAlA AoAlD'。
但是相反,我得到 'hAllA AArld' 这不是我想要的结果。
有人可以帮帮我吗?

编辑:问题是我检查了ASCII table,ASCII table中字母'e'、'o'、'w'的值是奇数,其他字母不是。所以我的程序正在检查字母的值是否为奇数或不替换为 'A' 而不是字符串中的第 1、3、5 个字符。

代码如下:

#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);
}

你有几个问题:

  1. strlen returns一个size_t类型,所以i最好匹配那个类型
  2. i 未初始化,应该从 0 开始,因为 C 中的数组是从 0 开始的(第一个元素从位置 0 开始,而不是 1)。
  3. str1[i]%2 是不正确的数学。你想对索引 i 取模,而不是字符串中的实际字符。

这是一个修复版本:

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

Demonstration

更新

正如@chux 在评论中所建议的那样,删除 strlen 并检查 NULL 字符作为循环中的终止条件会更有效。但是,对于像这样的迪克西杯程序,我怀疑是否会实现很多性能提升,最终建议使用您最清楚的 code/method:

方法一

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

此外,您可以完全绕过模数,每次在循环中将 i 前进 2,因为它是您想要的偶数数组位置(奇数字符计数):

方法二

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

沿着效率之路前进(并且知道您不会更改字符串的长度 in-loop),您还可以

方法三

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

或者,完全绕过 strlen

方法四

for (size_t i=0; str1[i]; i=i+2) {
   str1[i]='A';
   if (!str1[i+1]) break;
}

更新 2

在 Godbolt 上进行了一些试验后,@chux 是正确的。即使启用了优化,每次通过方法 2 的循环都会调用 strlen。实际上在我看来,方法 3 是最有效的。我不是汇编专家,但这完全绕过了 strlen 调用,看起来循环中的指令最少。我已经为任何感兴趣的人创建了 this playground here