c语言获取表格数据

任务

虽然数据处理拥有多种便捷语言支持,但课设需要使用c语言实现,因此学习如何将excel表格信息导入程序中进行处理

所需

  • c语言运行平台
  • 数据表格

步骤

1.查阅发现,通过处理csv(comma separated-values)文件,在python学习时接触到,为逗号分隔的文本格式,可以被和文本文件相同方式处理。
2.将表格另存为csv格式。
打开excel表格,点击另存为

3.读入文件

FILE* fp;
fp = fopen("oneturntask.csv", "r");

4.目标为写一个读文件的模板,可以通过修改简单的参数,灵活读入不同文件的数据,方便多次使用

  • 读入表头信息
#define HEADERMAXLEN 100 //表头最大字符总长
#define TITLEMAXLEN 100 //单个标题最大字符长度
#define TITLEMAXNUM 20 //标题最大数量
int colNum=0;//记录表格数据总列数
int lineCodeCol, leaveTimeCol, directionCol, actualTimeCol;//记录需要的数据所在列数
char csvHeader[HEADERMAXLEN];//存储表头信息
char title[TITLEMAXNUM][TITLEMAXLEN];//存储各个标题
int lineData[TITLEMAXNUM];//读入数据
int readAll = 0;//判断是否到文件结尾

char* pHeader;
char* pTitle;

fscanf(fp, "%s", &csvHeader);//读入表头信息
//cout << "表头全部信息如下:" << csvHeader << endl;

for (pHeader = csvHeader; *pHeader != '\0'; pHeader++)
 { 
  	colNum++;//空出0号存储位置,与实际列数相一致
  	pTitle = title[colNum];
  	while (*pHeader != ',' && *pHeader != '\0')
  	{   
   		*pTitle++ = *pHeader++; 
  	}
  	*pTitle = '\0';  
  	//  cout << "第"<<colNum<<"列:"<<title[colNum] << endl;
  	if (*pHeader == '\0')//读到表头末尾退出循环
   		break;  
 }
 //cout << "共有数据:" << colNum << "列" << endl;
  • 定位所需数据
#define LINECODE "LineCode"
#define LEAVETIME "LeaveTime0"
#define ACTUALTIME  "ActualTime"
#define DIRECTION "WorkDirection"//表头关键字预定义
for (int i = 1; i <= colNum; i++)
{ 
  if (strcmp(title[i], LINECODE) == 0)
  {
   	lineCodeCol = i;
   	//cout << "所需" << LINECODE << "位于第" << i << "列" << endl;
  }
   
  if (strcmp(title[i], LEAVETIME) == 0)
  {
   	leaveTimeCol = i;
   	//cout << "所需" << LEAVETIME << "位于第" << i << "列" << endl;
  }
   
  if (strcmp(title[i], DIRECTION) == 0)
  {
   	directionCol = i;
   	//cout << "所需" << DIRECTION << "位于第" << i << "列" << endl;
  }
   
  if (strcmp(title[i], ACTUALTIME) == 0)
  {
   	actualTimeCol = i;
   	//cout << "所需" << ACTUALTIME << "位于第" << i << "列" << endl;
  }   
  • 读入所需数据
while (readAll==0)
{
	for (int i = 1; i <= colNum; i++)
  	{
   		if (fscanf(fp, "%d", &lineData[i]) == EOF)//判断读到文件末尾
   		{
   			 readAll = 1;
    			 break;
  		}
    
   		fgetc(fp);
 	}
 	//打印文件信息
 	/*
 	if (readAll == 0)
  	{
  		for (int i = 1; i <= colNum; i++)
   		{
    			if (i == lineCodeCol)
     				cout << "lineCode:" << lineData[i] << " ";
   			if (i == leaveTimeCol)
     				cout << "leaveTime:" << lineData[i] << " ";
     			if (i == actualTimeCol)
     				cout << "actualTime:" << lineData[i] << " ";
    			if (i == directionCol)
     				cout << "direction:" << lineData[i] << " ";
   		}
   	}
   	*/
}

5.能够对文件信息在读取后进行处理,关闭文件

fclose(fp);

结果验证

在这里插入图片描述

在这里插入图片描述

写在后面

想读取其他文件做调整时发现,可移植性并不优秀,面对表格中的字符数据处理显出无力,只能手动删除所有包含字符单元列进行测试。

优化想法:

对单元格的读取函数做封装:一次读取一个单元格全部内容至字符数组保存,之后再进行处理。

要在C语言读取Excel数据并将其存储在数组中,可以使用以下步骤: 1. 包含必要的头文件和库: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <errno.h> #include <windows.h> #include <ole2.h> #include <olectl.h> #include <ocidl.h> ``` 2. 使用COM接口打开Excel文件,并获取工作簿和工作表对象: ```c // 打开Excel文件 CoInitialize(NULL); IDispatch* pXLApp = NULL; CLSID clsid; CLSIDFromProgID(L"Excel.Application", &clsid); HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pXLApp); if (FAILED(hr)) { printf("Failed to create Excel instance.\n"); return 1; } // 打开工作簿 VARIANT varFileName; VariantInit(&varFileName); varFileName.vt = VT_BSTR; varFileName.bstrVal = SysAllocString(L"example.xlsx"); // Excel文件名 IDispatch* pWorkbooks = NULL; hr = pXLApp->GetIDispatch(L"Workbooks", (void**)&pWorkbooks); if (FAILED(hr)) { printf("Failed to get Workbooks object.\n"); return 1; } IDispatch* pWorkbook = NULL; hr = pWorkbooks->Invoke(0x3ec, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get item(1) of Workbooks object.\n"); return 1; } // 获取工作表对象 VARIANT varWorksheetName; VariantInit(&varWorksheetName); varWorksheetName.vt = VT_BSTR; varWorksheetName.bstrVal = SysAllocString(L"Sheet1"); // 工作表名 IDispatch* pWorksheets = NULL; hr = pWorkbook->GetIDispatch(L"Worksheets", (void**)&pWorksheets); if (FAILED(hr)) { printf("Failed to get Worksheets object.\n"); return 1; } IDispatch* pWorksheet = NULL; hr = pWorksheets->Invoke(0x74, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get Item() of Worksheets object.\n"); return 1; } ``` 3. 获取Excel数据的范围,并确定数组的大小: ```c // 获取数据范围 VARIANT varRangeName; VariantInit(&varRangeName); varRangeName.vt = VT_BSTR; varRangeName.bstrVal = SysAllocString(L"A1:C10"); // 数据范围 IDispatch* pRange = NULL; hr = pWorksheet->GetIDsOfNames(IID_NULL, &varRangeName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pWorksheet->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get Range object.\n"); return 1; } pRange = varResult.pdispVal; // 获取数据大小 long numRows = 0; long numCols = 0; hr = pRange->GetIDsOfNames(IID_NULL, &dispidNumRows, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get number of rows.\n"); return 1; } numRows = varResult.lVal; hr = pRange->GetIDsOfNames(IID_NULL, &dispidNumCols, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get number of columns.\n"); return 1; } numCols = varResult.lVal; // 确定数组大小 int numRowsInt = (int)numRows; int numColsInt = (int)numCols; double** pData = (double**)malloc(numRowsInt * sizeof(double*)); for (int i = 0; i < numRowsInt; i++) { pData[i] = (double*)malloc(numColsInt * sizeof(double)); } ``` 4. 读取数据并存储在数组中: ```c // 读取数据 for (int i = 1; i <= numRowsInt; i++) { for (int j = 1; j <= numColsInt; j++) { VARIANT varValue; VariantInit(&varValue); IDispatch* pCell = NULL; hr = pRange->GetIDsOfNames(IID_NULL, &dispidItem, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } VARIANTARG vargIndex; VariantInit(&vargIndex); vargIndex.vt = VT_I4; vargIndex.lVal = i * pow(2, 16) + j; dispparams.rgvarg = &vargIndex; dispparams.cArgs = 1; hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get cell.\n"); return 1; } pCell = varResult.pdispVal; hr = pCell->GetIDsOfNames(IID_NULL, &dispidValue, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pCell->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varValue, NULL, NULL); if (FAILED(hr)) { printf("Failed to get cell value.\n"); return 1; } pData[i - 1][j - 1] = varValue.dblVal; } } ``` 5. 关闭Excel文件和COM接口: ```c // 关闭对象 pRange->Release(); pWorksheet->Release(); pWorksheets->Release(); pWorkbook->Release(); pWorkbooks->Release(); pXLApp->Release(); // 释放内存 for (int i = 0; i < numRowsInt; i++) { free(pData[i]); } free(pData); // 关闭COM接口 CoUninitialize(); ``` 完整的代码如下所示: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #include <math.h> #include <errno.h> #include <windows.h> #include <ole2.h> #include <olectl.h> #include <ocidl.h> int main() { // 打开Excel文件 CoInitialize(NULL); IDispatch* pXLApp = NULL; CLSID clsid; CLSIDFromProgID(L"Excel.Application", &clsid); HRESULT hr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IDispatch, (void**)&pXLApp); if (FAILED(hr)) { printf("Failed to create Excel instance.\n"); return 1; } // 打开工作簿 VARIANT varFileName; VariantInit(&varFileName); varFileName.vt = VT_BSTR; varFileName.bstrVal = SysAllocString(L"example.xlsx"); // Excel文件名 DISPPARAMS dispparamsNoArgs = { NULL, NULL, 0, 0 }; VARIANT varResult; IDispatch* pWorkbooks = NULL; hr = pXLApp->GetIDispatch(L"Workbooks", (void**)&pWorkbooks); if (FAILED(hr)) { printf("Failed to get Workbooks object.\n"); return 1; } DISPID dispid = 0; hr = pWorkbooks->GetIDsOfNames(IID_NULL, &L"Open", 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } VARIANTARG dispparamsOpen[4]; dispparamsOpen[3].vt = VT_BOOL; dispparamsOpen[3].boolVal = FALSE; dispparamsOpen[2].vt = VT_BOOL; dispparamsOpen[2].boolVal = FALSE; dispparamsOpen[1].vt = VT_BOOL; dispparamsOpen[1].boolVal = FALSE; dispparamsOpen[0].vt = VT_BSTR; dispparamsOpen[0].bstrVal = varFileName.bstrVal; dispparams.cArgs = 4; dispparams.rgvarg = dispparamsOpen; hr = pWorkbooks->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dispparams, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to open workbook.\n"); return 1; } IDispatch* pWorkbook = NULL; hr = pWorkbooks->Invoke(0x3ec, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get item(1) of Workbooks object.\n"); return 1; } pWorkbook = varResult.pdispVal; // 获取工作表对象 VARIANT varWorksheetName; VariantInit(&varWorksheetName); varWorksheetName.vt = VT_BSTR; varWorksheetName.bstrVal = SysAllocString(L"Sheet1"); // 工作表名 IDispatch* pWorksheets = NULL; hr = pWorkbook->GetIDispatch(L"Worksheets", (void**)&pWorksheets); if (FAILED(hr)) { printf("Failed to get Worksheets object.\n"); return 1; } IDispatch* pWorksheet = NULL; hr = pWorksheets->Invoke(0x74, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get Item() of Worksheets object.\n"); return 1; } // 获取数据范围 VARIANT varRangeName; VariantInit(&varRangeName); varRangeName.vt = VT_BSTR; varRangeName.bstrVal = SysAllocString(L"A1:C10"); // 数据范围 DISPID dispidNumRows = 0; DISPID dispidNumCols = 0; DISPID dispidItem = 0; DISPID dispidValue = 0; IDispatch* pRange = NULL; hr = pWorksheet->GetIDsOfNames(IID_NULL, &varRangeName.bstrVal, 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pWorksheet->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get Range object.\n"); return 1; } pRange = varResult.pdispVal; // 获取数据大小 long numRows = 0; long numCols = 0; hr = pRange->GetIDsOfNames(IID_NULL, &L"Rows", 1, LOCALE_USER_DEFAULT, &dispidNumRows); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pRange->Invoke(dispidNumRows, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get number of rows.\n"); return 1; } numRows = varResult.lVal; hr = pRange->GetIDsOfNames(IID_NULL, &L"Columns", 1, LOCALE_USER_DEFAULT, &dispidNumCols); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pRange->Invoke(dispidNumCols, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get number of columns.\n"); return 1; } numCols = varResult.lVal; // 确定数组大小 int numRowsInt = (int)numRows; int numColsInt = (int)numCols; double** pData = (double**)malloc(numRowsInt * sizeof(double*)); for (int i = 0; i < numRowsInt; i++) { pData[i] = (double*)malloc(numColsInt * sizeof(double)); } // 读取数据 for (int i = 1; i <= numRowsInt; i++) { for (int j = 1; j <= numColsInt; j++) { VARIANT varValue; VariantInit(&varValue); IDispatch* pCell = NULL; hr = pRange->GetIDsOfNames(IID_NULL, &L"Item", 1, LOCALE_USER_DEFAULT, &dispid); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } VARIANTARG dispparamsItem[1]; dispparamsItem[0].vt = VT_I4; dispparamsItem[0].lVal = i * pow(2, 16) + j; DISPPARAMS dispparams = { dispparamsItem, NULL, 1, 0 }; hr = pRange->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparams, &varResult, NULL, NULL); if (FAILED(hr)) { printf("Failed to get cell.\n"); return 1; } pCell = varResult.pdispVal; hr = pCell->GetIDsOfNames(IID_NULL, &L"Value", 1, LOCALE_USER_DEFAULT, &dispidValue); if (FAILED(hr)) { printf("Failed to get IDs of names.\n"); return 1; } hr = pCell->Invoke(dispidValue, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dispparamsNoArgs, &varValue, NULL, NULL); if (FAILED(hr)) { printf("Failed to get cell value.\n"); return 1; } pData[i - 1][j - 1] = varValue.dblVal; } } // 关闭对象 pRange->Release(); pWorksheet->Release(); pWorksheets->Release(); pWorkbook->Release(); pWorkbooks->Release(); pXLApp->Release(); // 释放内存 for (int i = 0; i < numRowsInt; i++) { free(pData[i]); } free(pData); // 关闭COM接口 CoUninitialize(); return 0; } ```
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值