#!/bin/bash # 文本文件转C头文件脚本 # 支持中文和特殊字符 # 用法: ./text_to_header.sh <输入文件> <输出头文件> <变量名> set -e # 显示颜色输出 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # 显示用法信息 show_usage() { echo -e "${GREEN}用法: $0 <输入文件> <输出头文件> <变量名>${NC}" echo -e "${GREEN}示例: $0 input.txt text_data.h my_text${NC}" exit 1 } # 检查工具是否安装 check_tools() { local tools=("hexdump" "sed" "awk" "basename" "wc" "file") for tool in "${tools[@]}"; do if ! command -v "$tool" &> /dev/null; then echo -e "${RED}错误: 未找到工具 $tool${NC}" exit 1 fi done } # 检查参数 if [ $# -ne 3 ]; then show_usage fi INPUT_FILE="$1" OUTPUT_FILE="$2" VAR_NAME="$3" # 检查输入文件 if [ ! -f "$INPUT_FILE" ]; then echo -e "${RED}错误: 输入文件 '$INPUT_FILE' 不存在!${NC}" exit 1 fi # 检查文件编码 FILE_ENCODING=$(file -b --mime-encoding "$INPUT_FILE") if [[ "$FILE_ENCODING" != "utf-8" && "$FILE_ENCODING" != "us-ascii" ]]; then echo -e "${YELLOW}警告: 文件编码为 $FILE_ENCODING,建议使用UTF-8编码${NC}" fi # 获取文件信息 FILENAME=$(basename "$INPUT_FILE") FILE_SIZE=$(wc -c < "$INPUT_FILE") TEXT_SIZE=$(wc -m < "$INPUT_FILE") echo -e "${GREEN}正在处理文件: $INPUT_FILE${NC}" echo -e "文件大小: $FILE_SIZE 字节" echo -e "文本长度: $TEXT_SIZE 字符" echo -e "编码: $FILE_ENCODING" # 创建头文件 create_header() { # 创建头文件头部 cat > "$OUTPUT_FILE" << EOF /* 自动生成的文本数据头文件 */ /* 源文件: $FILENAME */ /* 文件大小: $FILE_SIZE 字节 */ /* 生成时间: $(date +"%Y-%m-%d %H:%M:%S") */ /* 编码: $FILE_ENCODING */ #ifndef ${VAR_NAME^^}_H #define ${VAR_NAME^^}_H #include // 文本数据(UTF-8编码) const char *${VAR_NAME} = EOF # 使用hexdump处理文件内容 echo "正在转换文本内容..." # 临时文件用于处理转义 TEMP_FILE=$(mktemp) # 读取文件并处理转义字符 while IFS= read -r line || [ -n "$line" ]; do # 转义特殊字符 line=$(printf "%s" "$line" | sed 's/\\/\\\\/g' | sed 's/"/\\"/g' | sed 's/^/"/' | sed 's/$/\\n"/') echo " $line" >> "$TEMP_FILE" done < "$INPUT_FILE" # 移除最后一行的换行符 sed -i '$ s/\\n"$/"/' "$TEMP_FILE" # 将处理后的内容添加到头文件 cat "$TEMP_FILE" >> "$OUTPUT_FILE" # 清理临时文件 rm -f "$TEMP_FILE" # 完成头文件 cat >> "$OUTPUT_FILE" << EOF ; // 文本数据大小(包括null终止符) const size_t ${VAR_NAME}_size = $((FILE_SIZE + 1)); // 文本长度(字符数) const size_t ${VAR_NAME}_length = $TEXT_SIZE; #endif /* ${VAR_NAME^^}_H */ EOF echo -e "${GREEN}成功生成头文件: $OUTPUT_FILE${NC}" } # 创建示例C文件 create_example_c() { local example_file="${OUTPUT_FILE%.h}_example.c" local base_header=$(basename "$OUTPUT_FILE") cat > "$example_file" << EOF #include #include #include #include "$base_header" int main() { // 设置locale以支持中文输出 setlocale(LC_ALL, "zh_CN.UTF-8"); printf("=== 文本数据测试程序 ===\\n"); printf("文件: %s\\n", "$FILENAME"); printf("编码: %s\\n", "$FILE_ENCODING"); printf("\\n"); printf("文本内容:\\n"); printf("----------------------------------------\\n"); printf("%s", ${VAR_NAME}); printf("----------------------------------------\\n"); printf("\\n"); printf("统计信息:\\n"); printf("数组大小: %zu 字节\\n", ${VAR_NAME}_size); printf("文本长度: %zu 字符\\n", ${VAR_NAME}_length); printf("字符串长度: %zu 字节\\n", strlen(${VAR_NAME})); printf("\\n"); printf("十六进制查看(前64字节):\\n"); for (size_t i = 0; i < ${VAR_NAME}_size && i < 64; i++) { printf("%02x ", (unsigned char)${VAR_NAME}[i]); if ((i + 1) % 16 == 0) printf("\\n"); } printf("\\n"); return 0; } EOF echo -e "${GREEN}创建示例C文件: $example_file${NC}" } # 创建编译脚本 create_build_script() { local build_script="build_${VAR_NAME}.sh" local program_name="${VAR_NAME}_program" cat > "$build_script" << EOF #!/bin/bash # 自动编译脚本 echo -e "\033[0;32m编译程序...\033[0m" gcc -Wall -std=c99 -o "$program_name" "${OUTPUT_FILE%.h}_example.c" if [ \$? -eq 0 ]; then echo -e "\033[0;32m编译成功!\033[0m" echo -e "\033[0;33m运行程序: ./$program_name\033[0m" else echo -e "\033[0;31m编译失败!\033[0m" exit 1 fi EOF chmod +x "$build_script" echo -e "${GREEN}创建编译脚本: $build_script${NC}" } # 显示文件预览 show_preview() { echo -e "${YELLOW}文件预览(前10行):${NC}" head -10 "$INPUT_FILE" echo -e "${YELLOW}...${NC}" } # 主执行流程 main() { check_tools show_preview create_header create_example_c create_build_script echo -e "${GREEN}========================================${NC}" echo -e "${GREEN}完成! 接下来可以:${NC}" echo -e "1. 查看头文件: ${YELLOW}cat $OUTPUT_FILE${NC}" echo -e "2. 编译程序: ${YELLOW}./build_${VAR_NAME}.sh${NC}" echo -e "3. 运行程序: ${YELLOW}./${VAR_NAME}_program${NC}" echo -e "${GREEN}========================================${NC}" } # 执行主函数 main