臭虫str?

时间:2018-11-30 15:11:35

标签: c string ubuntu gcc

我刚刚开始使用C,并且我刚开始尝试弄清楚 通过引用在函数中调用。我注意到我的输出结果奇怪 使用strlen()遍历字符串并修改其内容时。在这 例如,strlen()的结果为3,不包括空字符, 但是如果我没有明确检查空字符(或使用小于 在for循环中strlen()的结果而不是小于或等于),然后 它由于空字符而在输出中给出了我ASSUME是一个奇怪的位字符?

请帮助这个菜鸟了解这里发生的事情。

代码:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void f_test_s(char s[]);
void f_test_s2(char s[]);

int main(){
    char s_test[] = "abc";

    f_test_s(s_test);
    f_test_s2(s_test);

    puts("\nTest complete!");

    return 0;
}


void f_test_s(char s[]){

    puts("Test #1: ");
    printf("string before: %s\n", s);

    int len = strlen(s);
    printf("strlen() = %d\n", len); 
    int i=0;             
    for(i=0;i<=len;i++){
        if(s[i] != '\0'){
            s[i]++;
        }
    }

    printf("string after: %s\n", s);

}


void f_test_s2(char s[]){

    puts("\nTest #2: ");
    printf("string before: %s\n", s);

    int len = strlen(s);
    printf("strlen() = %d\n", len);
    int i=0;         
    for(i=0;i<=len;i++){
        s[i]++;
    }

    printf("string after: %s\n", s);

} 

输出:

Test #1: 
string before: abc
strlen() = 3
string after: bcd

Test #2: 
string before: bcd
strlen() = 3
string after: cde

Test complete!

如果有关系,我正在Ubuntu上使用gcc版本7.3.0。我绝对是 不是C,gcc或Ubuntu的专家。

2 个答案:

答案 0 :(得分:2)

这是问题所在

for (i = 0; i <= len; i++) {
    s[i]++;
}

应该是:

for (i = 0; i < len; i++) {
    s[i]++;
}

s[len]是空字符(0)。当您删除null char并将其替换为1时,数组的内容现在为{'a', 'b', 'c', 0x1}。当printf尝试打印s时,它将继续打印字符超过数组的值存储地址,直到遇到空字符为止。从技术上讲,这是未定义的行为。

答案 1 :(得分:1)

更改此:

for (i = 0; i <= len; i++) {

对此:

for (i = 0; i < len; i++) {

因为strlen()返回字符串的长度。 C字符串的长度与字符串开头和终止的空字符之间的字符数一样(不包括终止的空字符本身)。

由于超出范围,您的代码将调用未定义行为(UB)。标准字符串函数(如printf())依赖于NULL终止符来标记字符串的结尾。没有它,他们不知道何时停止。 。