#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); //向文件中写入各种数据
}