我改寫的二分法XML轉CSV文件程序速度追上了張澤鵬先生的

以下是美團龍貓初稿,我改正,DeepSeek重新格式化的代碼。
重要改正點:
1.二分查找用goto控制迭代,返回<row的正確位置
2.在緩沖區頭填上父標簽使expat能連續解析不報錯

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <expat.h>#define MAX_CELL_CONTENT 256typedef struct {int start_row;int end_row;char start_col;char end_col;
} ParseRange;typedef struct {ParseRange range;FILE *csv;FILE *xml_file;XML_Parser parser;int in_row;int current_row;char current_col;int value_started;char temp_value[MAX_CELL_CONTENT];int value_len;int skip_row;long row_start_pos;int first_row_processed;char first_row_max_col;
} ParserState;int parse_excel_range(const char *range_str, ParseRange *range) {if (sscanf(range_str, "%c%d:%c%d", &range->start_col, &range->start_row,&range->end_col, &range->end_row) != 4) {return -1;}if (range->start_col > range->end_col) return -1;if (range->start_row > range->end_row) return -1;return 0;
}long binary_search_row(FILE *file, int target_row) {long low = 0;fseek(file, 0, SEEK_END);long high = ftell(file);long mid = 0;char buffer[1024];int found_row = -1;long found_pos = 0;while (low <= high) {
A:mid = (low + high) / 2;fseek(file, mid, SEEK_SET);int c;while ((c = fgetc(file)) != EOF) { if (c == '<') {char tag[128] = {c};int tag_len = 1;while ((c = fgetc(file)) != EOF && c != '>' && tag_len < sizeof(tag) - 1) {tag[tag_len++] = c;}tag[tag_len] = '\0';int rt = (strncmp(tag, "<row", 4) == 0);if (rt) {long row_start_pos = mid + (tag_len);char *row_attr = strstr(tag, " r=\"");if (row_attr) {int row_num = atoi(row_attr + 4);found_pos = ftell(file) - tag_len - 1;found_row = row_num;if (row_num == target_row) {return found_pos;} else if (row_num < target_row) {low = mid + 1;goto A;} else {high = mid - 1;goto A;}}}}}if (c == EOF) break;}if (found_row < target_row) {return found_pos;}return 0;
}void XMLCALL start_element(void *user_data, const XML_Char *name, const XML_Char **attrs) {ParserState *state = (ParserState*)user_data;if (strcmp(name, "row") == 0) {state->row_start_pos = XML_GetCurrentByteIndex(state->parser);state->in_row = 1;state->current_row = -1;state->skip_row = 0;for (int i = 0; attrs[i]; i += 2) {if (strcmp(attrs[i], "r") == 0) {state->current_row = atoi(attrs[i+1]);break;}}if (state->current_row > state->range.end_row) {XML_StopParser(state->parser, 0);return;}        if (state->current_row < state->range.start_row) {state->skip_row = 1;return;}fprintf(state->csv, "%d", state->current_row);}else if (strcmp(name, "c") == 0 && state->in_row && !state->skip_row) {for (int i = 0; attrs[i]; i += 2) {if (strcmp(attrs[i], "r") == 0) {state->current_col = attrs[i+1][0];break;}}}else if ((strcmp(name, "v") == 0 || strcmp(name, "t") == 0) && state->in_row && !state->skip_row) {if (state->current_col >= state->range.start_col && state->current_col <= state->range.end_col) {state->value_started = 1;state->value_len = 0;state->temp_value[0] = '\0';}}
}void XMLCALL character_data(void *user_data, const XML_Char *s, int len) {ParserState *state = (ParserState*)user_data;if (state->value_started && state->value_len + len < MAX_CELL_CONTENT - 1) {memcpy(state->temp_value + state->value_len, s, len);state->value_len += len;state->temp_value[state->value_len] = '\0';}
}void XMLCALL end_element(void *user_data, const XML_Char *name) {ParserState *state = (ParserState*)user_data;if (strcmp(name, "row") == 0 && state->in_row && !state->skip_row) {for (char col = state->current_col + 1; col <= state->range.end_col; col++) {fprintf(state->csv, ",");}fprintf(state->csv, "\n");state->in_row = 0;}else if ((strcmp(name, "v") == 0 || strcmp(name, "t") == 0) && state->value_started) {if (state->current_col >= state->range.start_col && state->current_col <= state->range.end_col) {static char last_col = 0;if (last_col == 0) last_col = state->range.start_col;for (char col = last_col; col < state->current_col; col++) {fprintf(state->csv, ",");}fprintf(state->csv, ",%s", state->temp_value);last_col = state->current_col + 1;}state->value_started = 0;}
}int main(int argc, char *argv[]) {if (argc != 3) {printf("用法: %s <xml文件> <范圍(A1:Z100)>\n", argv[0]);return 1;}ParseRange range;if (parse_excel_range(argv[2], &range) != 0) {printf("錯誤: 無效范圍格式\n");return 1;}char csv_filename[256];strncpy(csv_filename, argv[1], sizeof(csv_filename) - 1);char *ext = strrchr(csv_filename, '.');if (ext) strcpy(ext, ".csv");else strncat(csv_filename, ".csv", sizeof(csv_filename) - strlen(csv_filename) - 1);FILE *csv = fopen(csv_filename, "w");if (!csv) {printf("錯誤: 無法創建CSV\n");return 1;}fprintf(csv, "Row");for (char col = range.start_col; col <= range.end_col; col++) {fprintf(csv, ",%c", col);}fprintf(csv, "\n");FILE *file = fopen(argv[1], "rb");if (!file) {printf("錯誤: 無法打開文件 %s\n", argv[1]);fclose(csv);return -1;}long start_pos = binary_search_row(file, range.start_row);if (start_pos > 0) {fseek(file, start_pos, SEEK_SET);} else {fseek(file, 0, SEEK_SET);}XML_Parser parser = XML_ParserCreate(NULL);ParserState state = {0};state.range = range;state.csv = csv;state.parser = parser;XML_SetUserData(parser, &state);XML_SetElementHandler(parser, start_element, end_element);XML_SetCharacterDataHandler(parser, character_data);fseek(file, start_pos, SEEK_SET);char buffer[8192] = "<sheetData>";int done;int i = 0;do {if (XML_GetErrorCode(parser) == XML_ERROR_FINISHED) break;size_t len = fread(buffer + 11 * (i == 0), 1, sizeof(buffer) - 11 * (i == 0), file);done = (len < sizeof(buffer) - 11 * (i == 0));size_t actual_len = len;if (!done) {if (XML_Parse(parser, buffer, actual_len + 11 * (i == 0), done) == XML_STATUS_ERROR) {break;}i++;}} while (!done);fclose(file);fclose(csv);XML_ParserFree(parser);printf("CSV已保存到 %s\n", csv_filename);return 0;
}

編譯運行和比較

gcc expatfmt.c -o expatfmt -lexpat -O3
root@66d4e20ec1d7:/par# time ./expatfmt lineitem/xl/worksheets/sheet1.xml A500000:Z600000
CSV已保存到 lineitem/xl/worksheets/sheet1.csvreal	0m1.865s
user	0m1.836s
sys	0m0.028sroot@66d4e20ec1d7:/par# time ./aich2 lineitem/xl/worksheets/sheet1.xml A500000:Z600000 out.csvreal	0m2.870s
user	0m1.064s
sys	0m0.076s

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/921490.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/921490.shtml
英文地址,請注明出處:http://en.pswp.cn/news/921490.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用Docker安裝Stirling-PDF(PDF工具)

1、官方Web端 詳見&#xff1a;https://stirlingpdf.io/?langzh_CN 2、安裝Docker 合集&#xff1a;Docker安裝與使用 3、安裝Stirling-PDF 詳見&#xff1a; https://docs.stirlingpdf.com/Installation/Docker%20Install https://hub.docker.com/r/stirlingtools/stirli…

【開題答辯全過程】以 基于微信小程序的“XIN”學生組織管理系統為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

Iwip驅動8211FS項目——MPSOC實戰1

硬件設計采用RTL8211FS芯片&#xff0c;vitis默認的IWIP庫不支持此芯片。 網口相關知識可以翻看前期文章 以太網PHY_MDIO通信&#xff08;基于RTL8211&#xff09;--FPGA學習筆記22-CSDN博客 以太網ARP協議——FPGA學習筆記23_fpga以太網學習-CSDN博客 以太網ICMP協議(ping…

《Science》神經炎癥綜述思路套用:從機制到跨領域研究范式

2025 年 6 月首都醫科大學團隊在《Science》發表的綜述《Immunological dimensions of neurological disease: from mechanisms to therapeutics》(神經疾病的免疫維度:從機制到療法),系統性解析了神經炎癥的動態演變規律與雙面性,提出階段化、精準化治療新范式。本文基于…

嵌入式學習筆記--Linux系統編程階段--DAY07進程間通信--存儲映射和共享內存

1.存儲映射存儲映射 I/O (Memory-mapped I/O) 使一個磁盤文件與存儲空間中的一個緩沖區相映射。于是當從緩沖區中取數據&#xff0c;就相當于讀文件中的相應字節。于此類似&#xff0c;將數據存入緩沖區&#xff0c;則相應的字節就自動寫入文件。這樣&#xff0c;就可在不適用 …

.Net程序員就業現狀以及學習路線圖(四)

一、.Net程序員就業現狀分析 1. 市場需求與崗位分布 2025年數據顯示&#xff0c;.Net開發崗位在全國IT崗位中占比約0.009%&#xff0c;主要集中在一線城市如深圳、上海等地 2 4。行業分布呈現以下特點&#xff1a;?軟件行業?&#xff1a;占比43.3% ?研發領域?&#xff1a;占…

Monorepo 是什么?如何使用并寫自己的第三方庫

1. 什么是 Monorepo&#xff1f; Monorepo&#xff08;單倉庫&#xff09;指的是把多個項目/包放在一個代碼倉庫里統一管理。常見結構&#xff1a; /repo-root/packages/ui-lib/utils/apps/web-apppackage.jsonpnpm-workspace.yaml好處&#xff1a; 內部庫能直接共享&#xff0…

使用CI/CD部署后端項目(gin)

寫在前面&#xff1a;使用CI/CD部署gin項目到服務器中 前端可以參考&#xff1a;使用CI/CD部署nextjs項目 使用 GitHub Actions 配置后端 CI/CD&#xff08;含部署到服務器&#xff09; 本文檔介紹如何在 GitHub 倉庫中配置 CI/CD&#xff0c;將 PROJECT_NAME 項目自動構建并…

Coze添加知識庫解析的Embedding和PaddleOCR模型配置

1. Embedding模型配置 使用ollama模型&#xff0c;導入qwen3的embedding-8B模型&#xff0c;導入流程參考&#xff1a; Ollama離線部署模型 qwen3-Embedding模型文件可從魔塔社區下載&#xff1a; Qwen3-Embedding-8B 1.2 Coze配置 在coze_studio/docker目錄下輸入: vim .en…

02-Media-6-rtsp_server.py 使用RTSP服務器流式傳輸H264和H265編碼視頻和音頻的示例程序

rtsp_server.py 是使用k230的板載攝像頭和WIFI聯網功能,使用RTSP服務器流式傳輸視頻和音頻的程序示例。程序核心是創建了一個RtspServer類,該類用于初始化、啟動、停止RTSP服務器,并進行視頻和音頻的流傳輸。 一、首先,程序導入必要的模塊,包括視頻編碼、傳感器、媒體處理…

13-Java-面向對象-封裝和this關鍵字

文章目錄封裝this關鍵字封裝 告訴我們&#xff0c;如何正確設計對象的屬性和方法。原則&#xff1a;對象代表什么&#xff0c;就得封裝對應的數據&#xff0c;并提供數據對應的行為 package common;/*** Author: 大海* Date: 2025-09-06*/public class GirlFriend {/*private…

三高項目-緩存設計

三高項目-緩存設計 分流、并發 導流&#xff1a;將原本復雜操作的請求&#xff0c;引導到簡單的操作上。以后再來查&#xff0c;不需要經過復雜的計算。 成本&#xff1a;空間&#xff0c;收益&#xff1a;節省了時間。 不要以為僅僅是 redis&#xff0c;map等。 對應。kv…

happen-before原則

什么是 happen-before 原則&#xff1f; happen-before 是一個邏輯關系&#xff0c;用于描述兩個操作之間的 “先后順序”—— 如果操作 A happen-before 操作 B&#xff0c;那么 A 的執行結果必須對 B 可見&#xff0c;且 A 的執行順序在邏輯上先于 B。也就是保證指令有序性和…

4.1 機器學習 - 評估指標

模型評估是判斷 “模型是否有效” 的核心環節&#xff0c;需結合任務類型&#xff08;分類 / 回歸&#xff09;、數據分布&#xff08;如類別不平衡&#xff09;和商業目標選擇指標。本節聚焦分類任務的核心評估指標&#xff0c;從定義、計算邏輯到適用場景逐一拆解&#xff0c…

雅菲奧朗SRE知識墻分享(七):『可觀測性的定義與實踐』

在分布式系統日益復雜的當下&#xff0c;故障不再是“是否發生”&#xff0c;而是“何時爆發”。SRE可觀測性正是應對不確定性的“顯微鏡”與“導航儀”&#xff1a;通過指標、日志、追蹤三大數據血脈&#xff0c;實時外化系統黑盒&#xff0c;讓每一次抖動、每一行報錯、每一次…

C++ 詳細講解vector類

目錄 1. 什么是vector? 2. vector的使用 1. 構造函數---初始化 1. 默認構造函數(無參構造&#xff09; 2. 填充構造函數(指定數量和初始值&#xff09; 3. 范圍構造函數(通過迭代器拷貝其他容器元素&#xff09; 4. 拷貝構造函數(直接拷貝另一個vector&#xff09; 注…

Windows Server2012 R2 安裝.NET Framework 3.5

Windows Server2012 R2 安裝.NET Framework 3.5 虛擬機系統是Windowsserver 2012R2&#xff0c;在安裝SQlserver2012時候警告未安裝.NET Framework 3.5。于是找了個.NET Framework 3.5的安裝包&#xff0c;但是由于系統原因無法正常安裝。按照提示從控制面板-程序-啟動或關閉Wi…

IDEA中Transaction翻譯插件無法使用,重新配置Transaction插件方法

原因 由于Transaction默認的翻譯引擎為谷歌翻譯&#xff0c;由于一些原因&#xff0c;這個翻譯無法使用&#xff0c;因此導致插件無法使用。 解決辦法 更換Transaction插件翻譯引擎即可。 方法步驟 1.進入Idea的設置里&#xff0c;找到Tool下的Transaction選項2.更改翻譯引擎&a…

外置flash提示音打包腳本

批處理腳本說明文檔 - 音頻資源打包與分發 一、腳本功能概述 本批處理腳本&#xff08;.bat 文件&#xff09;用于將指定目錄下的多個音頻文件&#xff08;.wtg 和 .mp3 格式&#xff09;打包為音頻資源配置文件&#xff08;tone.cfg&#xff09;&#xff0c;進一步將配置文件與…

Go語言設計模式(三)抽象工廠模式

抽象工廠模式與工廠模式類似,被認為是工廠方法模式的另一層抽象.抽象工廠模式圍繞創建其他工廠的超級工廠工作.1.角色:1.1抽象產品:構成產品系列的一組不同但相關的產品的聲明接口.1.2具體產品:實現抽象產品接口的類,主要用于定義產品對象,由相應的具體工廠創建.1.3抽象工廠:創…