1

我想了解为什么某些字符会在原始字符串中连接后消失。看,c = *sibl接收 的第一个字符*sibl*sibl = *inout接收 的内容,*inout但存储的字符c不在 中*inout。而且,*inout = c不会改变 的内容*inout,它c会连接到 的内容*inout。我不明白为什么会这样!

我的代码:

void Cripto (char *inout, int i) {
    char *sibl, c;
    while (*inout) {
        sibl = inout+1;
        if (!sibl)
            break;
        if (*inout >= 'A' && *inout <= 'Z'){
            *inout += i;
        }
        c = *sibl;
        printf("val c %c\n",c);
        printf("val inout after c %s\n",inout);
        printf("val sibl after c %s\n",sibl);
        *sibl = *inout;
        printf("val sibl after att %s\n",sibl);
        *inout = c;
        printf("val inout after att %s\n",inout);
    inout = sibl+1;
    }
}

int main() {
    char str[30];
    int i;
    scanf("%s %d", str, &i);
    Cripto(str, i);
    printf("%s\n", str);
    return 0;

}

"teste" 3 的结果:

val c: e  
val inout after c: teste  
val sibl after c: este  
val sibl after att: tste  
val inout after att: etste  
val c: t  
val inout after c: ste  
val sibl after c: te   
val sibl after att: se  
val inout after att: tse  
val c:  
val inout after c: e  
val sibl after c:    
val sibl after att: e  
val inout after att:  
4

3 回答 3

2

您需要注意的另一件事(除非您是故意这样做的)是以下两行:

sibl = inout+1;
*sibl = *inout;

您将 sibl 指向 inout + 1,然后通过 inout 的值分配 sibl 的值(本质上是指向 inout + 1 的指针)。这将改变 inout 本身的值。因此,如果 inout 是(“123”),那么 sibl 指向“23”,并且使用“*sibl = *inout”,您将使用第一个字符设置 inout 的第二个字符(即 sibl)。因此,inout 将变为“113”。

于 2013-09-03T17:57:01.003 回答
1

您的问题的原因是您在while()循环中以 2 的步骤进行迭代:

while(*inout) {
    sibl = inout+1;
    // ...
    inout = sibl+1;  // = (inout+1)+1 = inout+2
}

似乎想要做的是遍历指向的字符串inout并添加i(可能是一个小值)如果char是大写字母,那么为什么不使用类似的东西:

while(*inout) {
    if( *inout>='A' && *inout<='Z' ) {
        *inout += (char)i;
    }
    inout++;
}
于 2013-09-03T17:51:01.287 回答
1

此代码中没有进行串联。只有覆盖发生。这是代码的作用:

  1. 您在某个内存缓冲区中有一个字符串,用作输入和输出。该变量inout是一个从该字符串的开头开始的指针。但是,随着函数的进行,该指针被修改为指向该字符串中的其他字符。因此,当您稍后输出它指向的字符串时,只会打印字符串的后缀。前缀仍然存在,但 C 字符串总是从起始指针到终止空字符进行解释。

  2. 在第一次迭代中,inout是指向第一个字符的指针,sibl被指向输入数组中的第二个字符。如果任何一个指向终止空字符,则循环终止。

  3. 如果inout指向的字符是大写,则其 ASCII 值增加 i。作为旁注:此操作在编写时不可逆,因为'Z' + 3(或类似的)将映射到一些本身不会被修改的非字母数字字符。

  4. 该序列c = *inout; *inout = *sibl; *sibl = c交换了两个相邻的字符。

  5. inout = sibl + 1;自上次设置后有效地inout向前移动了两个字符siblinout + 1

  6. 第二次迭代对字符 3 和 4 的作用与第一次迭代对字符 1 和 2 的作用相同。您printf不再在输出中看到第一次迭代的结果,因为这两个字符现在位于两个指针的前面,并且在函数中基本上无法访问。然而,指针 inmain没有被修改,最后一个printf应该给你操作的整个结果。

于 2013-09-03T18:00:48.037 回答