为什么要写这篇
起因大概是一篇定时关机的实现吧,实际测试之后并不理想就不放链接了,但另一点儿收获是用C语言执行cmd命令,后来又因此接触了一点儿批处理文件,最终发现几条语句很有意思,经过一段时间的摸索,有了如今的将数据表输出到文本文档。
最终效果图如下,通过传入数组首地址,数组大小,以及列数,实现以下输出。
此函数因使用windows.h头文件,不能在菜鸟C在线工具中运行,若运行需要先搭建环境,我放在了这篇文章里:##使代码可读且提高封装性 。建议在VScode中运行,生成的test文本文档会和源文件在同一目录,若使用Notepad++,生成的文本文档会在Notepad++.exe的目录下。
#include <stdio.h> /* 用来使用输出函数 printf sprintf */
#include <stdint.h> /* 用来使用数据类型, uint8_t, uint16_t */
#include <windows.h> /* 用来支持cmd命令 */
#include <string.h> /* 用来使用字符串函数 strchr */
#include <stdlib.h> /* 用来使用malloc free 函数 */
#define DEBUG_OUTPUT 0
#define ARRAY_SIZE 101
const uint16_t motor_ntc_mV_array[ARRAY_SIZE] =
{
453, 472, 492, 513, 534, 556, 579, 602, 626, 651,
676, 701, 728, 754, 782, 809, 838, 867, 896, 926,
956, 987, 1018, 1049, 1081, 1114, 1146, 1179, 1212, 1245,
1278, 1312, 1346, 1379, 1413, 1447, 1481, 1515, 1549, 1582,
1616, 1649, 1682, 1715, 1748, 1781, 1813, 1845, 1877, 1908,
1939, 1970, 2000, 2030, 2059, 2088, 2116, 2145, 2172, 2200,
2226, 2252, 2278, 2303, 2328, 2352, 2376, 2399, 2422, 2444,
2466, 2488, 2508, 2529, 2549, 2568, 2587, 2606, 2624, 2642,
2659, 2676, 2692, 2708, 2723, 2738, 2753, 2768, 2782, 2795,
2809, 2821, 2834, 2847, 2858, 2870, 2881, 2892, 2903, 2913,
2923
};
void eliminate_zero(char* arr);
void array_process_to_space(char* temp_array, uint16_t num);
void table_to_txt_file(uint16_t* array, uint16_t num, uint8_t column);
/**
* eliminate_zero
* @brief 消除字符数组',' 后面的 '\0'
* @param arr字符数组首地址
* @note 每调用一次sprintf函数都会有一个字符串结束标志,为输出多个数据,必须清除
*/
void
eliminate_zero(char* arr)
{
if(arr == NULL)
{
return;
}
char *ptr = arr; //不能初始化为NULL,否则不满足while的执行条件
char *pts = arr;
while(ptr != NULL)
{ //strchr只能返回查找到首个匹配字符的位置
ptr = strchr(pts,','); //指针只能执行相减操作,不能执行相加操作
if(ptr != NULL) //可以用相对位置来查找,绝对位置来赋值
{
uint8_t index_1 = pts - arr;
uint8_t index_2 = ptr - pts;
#if DEBUG_OUTPUT
printf("index_1 is %d, index_2 is %d",index_1, index_2);
#endif
pts = arr + index_1 + index_2 + 1;
*pts = ' ';
}
}
}
/**
* array_process_to_space
* @brief 将数组清为空格,因数组中的0即'\0',会导致输出结束
* @param temp_array 参数描述: 数组首地址
* @param num 参数描述: 数组大小
*/
void
array_process_to_space(char* temp_array, uint16_t num)
{
for(uint8_t j=0; j<num -1; j++)
{
temp_array[j] = ' ';
}
temp_array[num-1] = '\0';
}
/**
* table_to_txt_file
* @brief 将数据表输出到文本文档
* @remarks 函数中有两行可发生更改
* @param array 数组首地址
* @param num 数组元素个数
* @param column 要输出为几列
* @note 数组的数据类型根据个人理解可更改为其它类型,如int8_t, int32_t,但整数位数不能超过9位
* @note 因为用10字节将一个整数存放在字符数组中,格式也比较统一
*/
void
table_to_txt_file(uint16_t* array, uint16_t num, uint8_t column)
{
char *temp1 = NULL;
char *buffer = NULL;
temp1 = (char*)malloc((column * 10) * sizeof(char));
if(temp1 == NULL)
{
printf("temp1_array : no memory space allocated! \n");
return;
}
buffer = (char*)malloc((column * 10 + 30) * sizeof(char)); ///< buffer数组要比temp1数组大一些来存放cmd命令字符
if(buffer == NULL)
{
printf("buffer_array : no memory space allocated! \n");
free(temp1);
return;
}
array_process_to_space(temp1, column*10);
system("echo hello"); ///< 此句为验证程序执行
system("echo const uint16_t motor_ntc_mV_array[101] = >test.txt"); ///< 此句需更改
system("echo { >>test.txt");
for(uint8_t i=0; i<num - 1; i++)
{
sprintf(&temp1[(i % column) * 10],"\t%d,", array[i]); //用10个字节将整数存入字符数组
if(i % column == (column -1))
{
eliminate_zero(temp1);
#if DEBUG_OUTPUT
for(uint8_t k=0; k<column; k++)
{
printf(" %d ",temp1[k]);
if(k == (column-1))
{
printf("\n");
}
}
#endif
sprintf(buffer,"echo %s >>test.txt",temp1); ///< 结束标志是\0
system(buffer);
array_process_to_space(temp1, column*10);
}
}
eliminate_zero(temp1);
sprintf(&temp1[((num-1) % column) * 10],"\t%d", array[num - 1]);
sprintf(buffer,"echo %s >>test.txt",temp1); ///< 结束标志是\0
system(buffer);
system("echo }; >>test.txt");
free(temp1);
free(buffer);
temp1 = NULL;
buffer = NULL;
}
int main(void)
{
table_to_txt_file(motor_ntc_mV_array, sizeof(motor_ntc_mV_array)/sizeof(motor_ntc_mV_array[0]), 7);
return 0;
}