我刚刚开始使用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的专家。
答案 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终止符来标记字符串的结尾。没有它,他们不知道何时停止。 。