#include<stdio.h>
#include<memory.h>
#define MAX_ROW 20
#define MAX_COLUMN 10
typedef struct nstTestTable //定義一個儲存文件各種參數的結構體
{
int ROW_COUNT; //保存行數
int COLUMN; //保存列數
char ROW_COUNR_NAME[MAX_ROW ][MAX_COLUMN]; //保存行的名字
char COLUMN_NAME[MAX_ROW][MAX_COLUMN]; //保存列的名字
int nuiTableData[MAX_ROW][MAX_COLUMN]; //儲存數據的值
int compress[MAX_ROW]; //記錄壓縮數據的標號
}STableContext;
STableContext MyTable; //實例化一個結構體
/****************************************************************************/
//名稱: OpenFile
//描述: 打開一個指定文件名的文件
//參數: filename char*
//返回值類型: FILE*
//做成日期: 2007-6-16
/***************************************************************************/
FILE *OpenFile(char *filename)
{
FILE *fp = 0;
if( (fp = fopen(filename,"r")) == NULL) //以只讀的方式打開
{
printf("Read file error!");
exit(0);
}
return fp;
}
/****************************************************************************/
//名稱: CountRow
//描述: 計算文件的行數
//參數: temp FILE*
//返回值類型: void
//做成日期: 2007-6-16
/***************************************************************************/
void CountRow(FILE *temp)
{
int i = 0; //定義一個記錄行數的變量
char ch = 0; //暫存從文件讀取的字符
ch = fgetc(temp);
while( ch != EOF)
{
if( ch == '/n') //沒讀到一個'/n'換,i自加一次
{
i++;
}
ch = fgetc(temp);
}
MyTable.ROW_COUNT = i;
}
/****************************************************************************/
//名稱: CountColumnName
//描述: 統計文件的列名
//參數: temp FILE*
//返回值類型: void
//做成日期: 2007-6-16
/***************************************************************************/
void CountColumnName(FILE *temp)
{
int index = 0; //定義一個文件的下標,用來說明是第幾列
char ch = 0;
ch = fgetc(temp);
while( ch != '/n')
{
while( ch == '/t') //如果讀取的字符爲tab那麼就跳過它
{
ch = fgetc(temp);
}
fseek(temp, -1L,1); //由於已經讀取了tab後的下一個字符
//所以要使文件指針退回一位
fscanf( temp, "%s", &MyTable.COLUMN_NAME[index][0] );
//從文件中讀取字符串保存的到二維數組中
index++;
ch = fgetc(temp);
}
}
/****************************************************************************/
//名稱: CountRowName
//描述: 統計文件的行名
//參數: temp FILE*
//返回值類型: void
//做成日期: 2007-6-16
/***************************************************************************/
void CountRowName(FILE *temp)
{
char ch = 0;
int index = 0;
ch = fgetc(temp);
while(ch != EOF)
{
if(ch == '/n') //由於每個換行符後面正好保存的是列名
//如果遇到換行符,那麼換行符後面的
//字符串將被讀入二維數組
{
fscanf( temp, "%s", &MyTable.ROW_COUNR_NAME[index][0] );
index++;
}
ch = fgetc(temp);
}
}
/****************************************************************************/
//名稱: CountColumn
//描述: 計算文件的列數
//參數: temp FILE*
//返回值類型: void
//做成日期: 2007-6-16
/***************************************************************************/
void CountColumn(FILE *temp)
{
int i = 0;
char ch =0;
ch = fgetc(temp);
while(ch != '/n') //指導讀取到'/n'時停止
{
if( ch == '/t') //列數是和tab的個數對應的,每讀到一個tab,i自增
{
i++;
}
ch = fgetc(temp);
}
MyTable.COLUMN = i;
}
/************************************************************************************/
//名稱: CompressRowData
//描述: 壓縮輸出數據
//參數: void
//返回值類型: void
//做成日期: 2007-6-16
/************************************************************************************/
void CompressRowData()
{
int comparedata[10]; //定義一個用於比較的緩存數組
int i = 0, j = 0, k = 0, m = 0;
for(m = 0; m < MyTable.ROW_COUNT; m++) //依次把二維數組MyTable.nuiTableData[][]
{ //中的內容複製到緩存數組中
for(j = 0; j < MyTable.COLUMN; j++)
{
comparedata[j] = MyTable.nuiTableData[m][j];
}
for(i = m + 1; i < MyTable.ROW_COUNT; i++)//將緩存數組中的內容依次與
{ //原二維數組中的內容進行比較
k = 0;
while(k < MyTable.COLUMN)
{
if(comparedata[k] == MyTable.nuiTableData[i][k])//如果相等下標k自增
{
k++;
}
else //否則退出循環體
break;
}
if(k >= MyTable.COLUMN) //如果完全相等
{
MyTable.compress[i] = m; //進行記錄第i行與第m行相等
}
}
}
}
/****************************************************************************/
//名稱: WriteData
//描述: 向一個指定的文件中寫入數據
//參數: temp char*
//返回值類型: void
//做成日期: 2007-6-16
/***************************************************************************/
void WriteData(char *temp)
{
FILE *fp = 0;
int i = 0;
int j = 0;
int m = 0;
int n = 0;
int find = 0;
int row_number = 0;
if( (fp = fopen(temp,"w")) == NULL)
{
printf("Read file error!");
exit(0);
}
CompressRowData(); //調用壓縮函數
while(MyTable.ROW_COUNR_NAME[i][0] != 0) //如果二維數組裏面的值不空
{
fprintf(fp, "#define ROW_%s", MyTable.ROW_COUNR_NAME[i]);//那麼向文件裏面輸出字符串
//也就是行的名字
if(MyTable.compress[i] == -1)
{
fprintf(fp, " %d/n", row_number);//輸出行號
row_number++;//行號自加
}
else
{
find = MyTable.compress[i];
fprintf(fp, " ROW_%s/n", MyTable.ROW_COUNR_NAME[find]);
}
i++;
}
fprintf(fp, "define ROW_COUNT %d/n/n", row_number); //輸出總共的行數
while(MyTable.COLUMN_NAME[j][0] != 0)
{
fprintf(fp, "#define COLUMN_%s", MyTable.COLUMN_NAME[j]);//向文件輸出列名
fprintf(fp, " %d/n", j);
j++;
}
fprintf(fp, "define COLUMN_COUNT %d/n", j);//向文件輸出總共的列數
fprintf(fp, "/nstatic int nuiTableData_a[][COLUMN_COUNT] = {/n");
for(m = 0; m < MyTable.ROW_COUNT; m++ )//向文件打印數據的值
{
for(n = 0; n < MyTable.COLUMN; n++)
{
fprintf(fp, "%d, ", MyTable.nuiTableData[m][n]);
}
fprintf(fp,"/n");
}
fprintf(fp, "}");
}
/****************************************************************************/
//名稱: ReadData
//描述: 從文件中讀取數據到結構體中保存數據值的二維數組
//參數: temp FILE*
//返回值類型: void
//做成日期: 2007-6-17
/***************************************************************************/
void ReadData(FILE *temp)
{
char ch = 0;
int i = 0;
int j = 0;
ch = fgetc(temp);
while(ch != '/n') //跳躍過第一行的列名
{
ch = fgetc(temp);
}
while(ch != EOF)
{
if(ch < 58 && ch > 47)//如果asic碼值爲0~9之間的數
{
MyTable.nuiTableData[i][j] = ch - '0';//減去'0'的asic碼值保存到二維數組
j++;
}
ch =fgetc(temp);
if(ch == '/n')//如果遇到'/n',那麼行下標自增
{
j = 0;
i++;
}
}
}
int main()
{
char readfile[10] = "file.txt"; //定義打開的文件
char writefile[15] = "newfile.txt"; //定義寫入的文件
FILE *fp = OpenFile(readfile); //調用OpenFile函數打開文件
memset(MyTable.compress, -1, MAX_ROW*4);
CountRow(fp); //計算行數
fseek(fp, 0, 0); //文件指針歸位
CountColumn(fp); //計算列數
fseek(fp, 0, 0);
CountColumnName(fp); //統計列名
fseek(fp, 0, 0);
CountRowName(fp); //統計行名
fseek(fp, 0, 0);
ReadData(fp); //讀取數據
printf("%d %d", MyTable.ROW_COUNT,MyTable.COLUMN);
WriteData(writefile); //向文件中寫入各種數據
}