Linux 编程,C 语言中的陷阱 - sizeof(字符串字面量)

本文介绍C语言中字符串字面量的处理方式,包括如何利用sizeof运算符计算字符串长度及注意事项,探讨不同工具对字符串末尾空字符的不同处理,并提供去除空字符的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录
  1. sizeof 运算符 / C 语言字符串字面量(计算字符串字面量长度时,会计入字符串结尾的空字符 ‘\0’)

1. sizeof 运算符
  • C 语言中的 字符串字面量作为字符数组来处理
  • 当 C 语言编译器在程序中遇到长度为 n 的字符串字面量时,会为字符串字面量分配长度为 n + 1 的内存空间。这块内存空间将用来存储字符串字面量中的字符,以及一个用来标志字符串末尾的额外字符(空字符,‘\0’)
  • 空字符是一个所有位都为 0 的字节,用转义字符 ‘\0’ 表示
  1. 实验代码如下(单目运算符 sizeof 在计算字符串长度时,会将字符串结尾的空字符(如果有的话)一并计入总长度):
#include <stdio.h>

void main(){
    char a[] = "a"; // 默认使用 2 个字节存储变量 a 的数据,即:['a']['\0']
    printf("a size is : %ld\n", sizeof(a)); //
    char b[4] = "4444";
    printf("b size is : %ld\n", sizeof(b)); // 打印数组 b 的长度,b 的声明长度为 4
    char c[8] = "8";
    printf("c size is : %ld\n", sizeof(c)); // 打印数组 c 的长度,c 的声明长度为 8
}

执行结果如下:

ubuntu@cuname:~/dev/beginning-linux-programming/test$ gcc -o test4 test4.c
ubuntu@cuname:~/dev/beginning-linux-programming/test$ ./test4
a size is : 2 //
b size is : 4
c size is : 8
  1. 写文件操作时,写入字符串字面量末尾的空字符会导致文件输出混乱。代码如下:
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

void main(){
    int de = open("error_code.txt", O_WRONLY | O_CREAT | O_TRUNC);
    char a[] = "hi\n";
    char b[] = "this world.\n";
    write(de, a, sizeof(a)); // 没有排除字符串字面量末尾的空字符
    write(de, b, sizeof(b)); // 没有排除字符串字面量末尾的空字符

    close(de);
}

使用 Linux 终端查看 error_code.txt 文件(显示正常,空字符被忽略了):
Linux 终端查看文件
使用 vscode 查看 error_code.txt 文件(异常输出):
使用 vscode 查看文本
使用 notepad++ 查看 error_code.txt 文件(异常输出):
使用 notepad++ 查看文件
使用 notepad 查看 error_code.txt 文件(非预期,notepad 将空字符解析为空格):
使用 notepad 查看文件
可以发现 使用不同的工具查看,会有不同的 ‘解释’
将上述程序代码修改为(写入时去掉字符串字面量末尾的空字符):

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <fcntl.h>

void main(){
    int de = open("error_code.txt", O_WRONLY | O_CREAT | O_TRUNC);
    char a[] = "hi\n";
    char b[] = "this world.\n";
    write(de, a, sizeof(a) - 1); // 去掉字符串字面量末尾的空字符
    write(de, b, sizeof(b) - 1); // 去掉字符串字面量末尾的空字符

    close(de);
}

执行后,输出结果正确(这才是我想要的呀: ):
输出结果


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值