Implement CSV export function
This commit is contained in:
@@ -11,6 +11,7 @@ CSV_Table::CSV_Table()
|
||||
{
|
||||
this->column_count = 0;
|
||||
this->mem_use = 0;
|
||||
this->max_element_depth = 0;
|
||||
this->Column_List_End = this->Column_List_Head = nullptr;
|
||||
}
|
||||
|
||||
@@ -23,6 +24,7 @@ void CSV_Table::reset()
|
||||
{
|
||||
// 清理尾指针
|
||||
this->Column_List_End = nullptr;
|
||||
this->max_element_depth = 0;
|
||||
this->column_count = 0;
|
||||
this->mem_use = 0;
|
||||
|
||||
@@ -304,6 +306,10 @@ CSV_Type::CSV_Err CSV_Table::append_cell(size_t target_column_position, const ch
|
||||
}
|
||||
|
||||
p_target_column->element_count++;
|
||||
|
||||
if (p_target_column->element_count > this->max_element_depth)
|
||||
this->max_element_depth = p_target_column->element_count;
|
||||
|
||||
return CSV_Type::CSV_ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -372,5 +378,158 @@ CSV_Type::CSV_Err CSV_Table::insert_cell_after(size_t target_column_position, si
|
||||
}
|
||||
|
||||
p_target_column->element_count++;
|
||||
|
||||
if (p_target_column->element_count > this->max_element_depth)
|
||||
this->max_element_depth = p_target_column->element_count;
|
||||
|
||||
return CSV_Type::CSV_ERROR_NONE;
|
||||
}
|
||||
|
||||
CSV_Type::CSV_Err CSV_Table::insert_cell_before(const char *target_column_title_str, size_t target_cell_position, const char *cell_content_str)
|
||||
{
|
||||
size_t count = 0;
|
||||
decltype(this->Column_List_Head) p_target_column = this->Column_List_Head;
|
||||
while (p_target_column != nullptr)
|
||||
{
|
||||
if (!strcmp(p_target_column->column_title_str, target_column_title_str))
|
||||
return this->insert_cell_before(count, target_cell_position, cell_content_str);
|
||||
|
||||
p_target_column = p_target_column->p_next_column;
|
||||
count++;
|
||||
}
|
||||
return CSV_Type::CSV_ERROR_COLUMN_NOT_FOUND;
|
||||
}
|
||||
|
||||
CSV_Type::CSV_Err CSV_Table::insert_cell_before(size_t target_column_position, size_t target_cell_position, const char *cell_content_str)
|
||||
{
|
||||
if ((target_column_position + 1) > this->column_count)
|
||||
return CSV_Type::CSV_ERROR_ILLEGAL_COLUMN_POSITION;
|
||||
decltype(this->Column_List_Head) p_target_column = this->Column_List_Head;
|
||||
for (size_t count = 0; count < target_column_position; count++)
|
||||
p_target_column = p_target_column->p_next_column;
|
||||
|
||||
if (!(((target_cell_position + 1) <= p_target_column->element_count) || ((target_cell_position == 0) && (p_target_column->element_count == 0))))
|
||||
return CSV_Type::CSV_ERROR_ILLEGAL_CELL_POSITION;
|
||||
|
||||
decltype(p_target_column->Cell_List_Head) p_new_cell = (decltype(p_target_column->Cell_List_Head))malloc(sizeof(*(p_target_column->Cell_List_Head)));
|
||||
if (p_new_cell == nullptr)
|
||||
return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED;
|
||||
this->mem_use += sizeof(*p_new_cell);
|
||||
|
||||
if (cell_content_str != nullptr)
|
||||
{
|
||||
char *p_content = (char *)malloc(strlen(cell_content_str) + 1); // +1 for '\0'
|
||||
if (p_content == nullptr)
|
||||
{
|
||||
free(p_new_cell);
|
||||
return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED;
|
||||
}
|
||||
|
||||
this->mem_use += strlen(cell_content_str) + 1;
|
||||
strcpy(p_content, cell_content_str);
|
||||
p_new_cell->content_str = p_content;
|
||||
}
|
||||
else
|
||||
p_new_cell->content_str = nullptr;
|
||||
|
||||
if (p_target_column->element_count == 0)
|
||||
{
|
||||
p_new_cell->p_next_cell = nullptr;
|
||||
p_target_column->Cell_List_Head = p_target_column->Cell_List_End = p_new_cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (target_cell_position == 0)
|
||||
{
|
||||
p_new_cell->p_next_cell = p_target_column->Cell_List_Head;
|
||||
p_target_column->Cell_List_Head = p_new_cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
decltype(p_new_cell) p_pre_target_cell = p_target_column->Cell_List_Head;
|
||||
for (size_t count = 0; count < target_cell_position - 1; count++)
|
||||
p_pre_target_cell = p_pre_target_cell->p_next_cell;
|
||||
|
||||
p_new_cell->p_next_cell = p_pre_target_cell->p_next_cell;
|
||||
p_pre_target_cell->p_next_cell = p_new_cell;
|
||||
}
|
||||
}
|
||||
|
||||
p_target_column->element_count++;
|
||||
|
||||
if (p_target_column->element_count > this->max_element_depth)
|
||||
this->max_element_depth = p_target_column->element_count;
|
||||
|
||||
return CSV_Type::CSV_ERROR_NONE;
|
||||
}
|
||||
|
||||
CSV_Type::CSV_Err CSV_Table::export_to_file(const char *file_name_str)
|
||||
{
|
||||
// 打开文件
|
||||
FILE *p_file = fopen(file_name_str, "wb");
|
||||
if (p_file == nullptr)
|
||||
return CSV_Type::CSV_ERROR_FILE_CREATE_FAILED;
|
||||
|
||||
// 横向元素表
|
||||
decltype(this->Column_List_Head->Cell_List_Head) *p_parallel_cell_list = nullptr;
|
||||
|
||||
// 输出内容
|
||||
if (this->column_count != 0)
|
||||
{
|
||||
p_parallel_cell_list = (decltype(this->Column_List_Head->Cell_List_Head) *)malloc(sizeof(*this->Column_List_Head->Cell_List_Head) * this->column_count);
|
||||
if (p_parallel_cell_list == nullptr)
|
||||
return CSV_Type::CSV_ERROR_MEM_ALLOCATE_FAILED;
|
||||
|
||||
// 输出标题及填充横向列表
|
||||
{
|
||||
size_t count = 0;
|
||||
for (decltype(this->Column_List_Head) p_target_column = this->Column_List_Head; p_target_column != nullptr; p_target_column = p_target_column->p_next_column)
|
||||
{
|
||||
if (fprintf(p_file, "%s,", p_target_column->column_title_str) < 0)
|
||||
goto file_write_error;
|
||||
p_parallel_cell_list[count] = p_target_column->Cell_List_Head;
|
||||
count++;
|
||||
}
|
||||
fseek(p_file, -1, SEEK_CUR);
|
||||
if (fprintf(p_file, "\r\n") < 0)
|
||||
goto file_write_error;
|
||||
}
|
||||
|
||||
// 输出横向行内容
|
||||
{
|
||||
for (size_t row_count = 0; row_count < this->max_element_depth; row_count++)
|
||||
{
|
||||
for (size_t column_count = 0; column_count < this->column_count; column_count++)
|
||||
{
|
||||
if (p_parallel_cell_list[column_count] != nullptr)
|
||||
{
|
||||
if (fprintf(p_file, strstr(p_parallel_cell_list[column_count]->content_str, ",") ? "\"%s\"," : "%s,", p_parallel_cell_list[column_count]->content_str) < 0)
|
||||
goto file_write_error;
|
||||
p_parallel_cell_list[column_count] = p_parallel_cell_list[column_count]->p_next_cell;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (fprintf(p_file, ",") < 0)
|
||||
goto file_write_error;
|
||||
}
|
||||
}
|
||||
fseek(p_file, -1, SEEK_CUR);
|
||||
if (fprintf(p_file, "\r\n") < 0)
|
||||
goto file_write_error;
|
||||
}
|
||||
}
|
||||
|
||||
free(p_parallel_cell_list);
|
||||
}
|
||||
|
||||
fclose(p_file);
|
||||
return CSV_Type::CSV_ERROR_NONE;
|
||||
|
||||
// 写入错误处理
|
||||
file_write_error:
|
||||
if (p_parallel_cell_list != nullptr)
|
||||
free(p_parallel_cell_list);
|
||||
fclose(p_file);
|
||||
return CSV_Type::CSV_ERROR_FILE_WRITE_FAILED;
|
||||
}
|
||||
@@ -23,12 +23,16 @@ void Pre_Command_Solve(void)
|
||||
CSV.insert_column_before("Test column", "Test insert column before Head");
|
||||
CSV.insert_column_before("Test column", "Test insert column before Origin");
|
||||
|
||||
CSV.insert_cell_before("Test column 2", 0, "0");
|
||||
CSV.append_cell("Test column 2", "1");
|
||||
CSV.insert_cell_before("Test column 2", 0, "Insert");
|
||||
CSV.insert_cell_after("Test column 3", (unsigned)0, "Insert Cell");
|
||||
CSV.append_cell("Test column 3", "1");
|
||||
CSV.append_cell("Test column 3", "2");
|
||||
CSV.append_cell("Test column 3", "MyWawwww,dwadawdawd");
|
||||
CSV.append_cell("Test column 3", "3");
|
||||
|
||||
CSV.export_to_file("new.csv");
|
||||
|
||||
// 获取命令行
|
||||
int argc;
|
||||
LPWSTR *argv;
|
||||
|
||||
Reference in New Issue
Block a user