暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

C语言批量删MYSQL表日志

212

初次尝试用C语言操纵MYSQL,还见海量!

上次初步使用C语言访问MYSQL 用C语言去操作MYSQL

这次就用C语言去完成实际功能, 很多的时候系统运行都有业务日志表,这些表的数量非常大,时间长了保留也没啥用,数据库的维护和数据的维护都丢给了DBA!  没办法DBA就是管数据库这事的,DBA职责就是维护数据库的稳定和性能的丝滑!

本来用了SHELL脚本,后来用了MYSQL 存储过程+事件调度器.

这些运维能看得懂,甚至想动手改, 存储过程开发也能看得懂! 

用C语言能看得懂的不多吧! 会维护就少了,尤其是指针不好整!

第一  程序目录架构

[deploy@AesygoDB=>DelBigTable]$pwd

/home/deploy/Project/DelBigTable

用户空间, 用户项目目录, 特定删除大表目录,具体项目

include: 头文件

lib: 静态库和动态库

bin:目标程序目录, 可能附带其它的工具

logs:主程序运行日志

conf:主程序配置文件

source:主程序源码目录

test.exe 编译后的主程序
makeC  编译命令集合

第二 编译说明

clear
gcc ./source/main.c -g -std=c11 -I./include -lmysqlclient -L./lib  -Wl,-rpath,'lib' -o test.exe

gcc 后面跟着是源码文件
-g             表示带上调试信息
-std=c11   使用C11语法
-I./include    告诉头文件目录
-lmysqlclient  表示使用MYSQLCLIENT动态库
-L./lib              表示从/lib下找动态库
-Wl,-rpath,'lib'  表示运行期间从程序运行当前目录下找 LIB目录下
-o test.exE      输出TEST.EXE

第三配置文件

#PASSWORD SIZE 35
#logfilename size 35
#SQL SIZE 2048-1
IPAD=192.168.0.227
USER=root
PROT=3306
PAWD=Sharkz@AESYGO
SCHM=lts
TOTAL_SQL=SELECT COUNT(*) as ALLROWS FROM lts.lts_job_log_po WHERE gmt_created< UNIX_TIMESTAMP(date_add(now(), interval -30 day))  *1000
LIMIT_ROWS=1000
DEL_SQL=DELETE FROM lts.lts_job_log_po WHERE gmt_created< UNIX_TIMESTAMP(date_add(now(), interval -30 day)) *1000
LOG_FILE_NAME=DelBigTableLog.txt

#号是注解, 
下面就是具体参数, 我们这里规定了参数大小写一致,参数名字要一致
这里TOTAL_SQL  SQL 没有双引号,没有分号. 长度限制为2048
另外参数要顶格
因为 程序判断 #号,换行符,回车符和 空格都会跳过

第四 主程序解读

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <stdint.h>

#include "../include/mysql/mysql.h"

//C99
typedef char       char1;
typedef wchar_t    varchar4;
typedef int8_t     int1;
typedef int16_t    int2;
typedef int32_t    int4;
typedef int64_t    int8;
typedef uint8_t    uint1;
typedef uint16_t   uint2;
typedef uint32_t   uint4;
typedef uint64_t   uint8;

typedef struct 
{

  char ip[35];
  char user[35];
  char port[5];
  char passwd[35];
  char schema[35];
  uint2  limit_rows;
  char TOTAL_SQL[2049];
  char DEL_SQL[2049];
  char logfile[35];

} Tparameter;

这的头文件都是有用的,另外还定义了整形方便形式.
还定义了个参数结构体类型.

2 函数说明

int ReadLine( FILE* pFileHandle,  char *Keys[],const int KeysLength,Tparameter* pParameter);  
int ReadKeyValue( FILE* pFileHandle,int* plast_row, char* pKey, char *pValue);
int GetFileRowNum( FILE* pFileHandle);
int GetTotal();
int ExecuteDel();

第一个函数ReadLine 是一次性访问配置文件,并把参数读到参数结构体里面
char *Keys[], const int KeysLength
这两个参数 是要 主函数 传递对比的参数名数组和长度. 否则怎么判断

第二个函数 

ReadKeyValue ( FILE* pFileHandle,int* plast_row, char* pKey, char *pValue);

也是读配置文件,不过这个就比较通用,它只要读到KEY=VALUE就返回给主函数去判断.
目前来说 重复读取CONF才能获取所有的参数,效率不高.
目前只通过上次读取的LAST_ROWS来进行定位,避免多次读取.
应该可以通过读取字节来重新定位,进一步提升效率.
后面两个参数是返回KEY VALUE的指针. 这里是要主函数提供接受标量的地址;

int GetFileRowNum( FILE* pFileHandle); 这个是获得配置文件总行数.

下面两个函数没有实现,另外写日志文件也没有实现.

3 读配置文件 主函数部分

int main(int argc, char const *argv[])
{

 Tparameter sParameter;
 FILE* fpFileHandle = NULL;  
 char *pFileName="./conf/DelLogTable.conf";                             //文件句柄
 char* Keys[9]={"IPAD","USER","PROT","PAWD","SCHM","TOTAL_SQL","LIMIT_ROWS","DEL_SQL","LOG_FILE_NAME"};

 int iReadLineStatus;


 fpFileHandle = fopen(pFileName,"r");                     //打开文件,读取模式,返回文件句柄

/*
 if(fpFileHandle !=NULL)
 { 
       fseek(fpFileHandle,0,0);                              //移动文件句柄到文件头部
       iReadLineStatus=ReadLine(fpFileHandle,Keys,9,&sParameter);  //调用上面函数
       if(iReadLineStatus==0)                               //读到真实内容就
       {
          printf("IP:%s\n",sParameter.ip);
          printf("USER:%s\n",sParameter.user);
          printf("PROT:%s\n",sParameter.port);
          printf("PAWD:%s\n",sParameter.passwd);
          printf("SCHM:%s\n",sParameter.schema);
          printf("TOTAL_SQL:%s\n",sParameter.TOTAL_SQL);
          printf("LIMIT_ROWS:%d\n",sParameter.limit_rows);
          printf("DEL_SQL:%s\n",sParameter.DEL_SQL);
          printf("LOG_FILE_NAME:%s\n",sParameter.logfile);
       }
 }
*/


 if(fpFileHandle !=NULL)
 { 
      int TotalRow =0;
      TotalRow = GetFileRowNum(fpFileHandle);

      int iReadKeyValue=1,last_row=1;
      char key[35];
      char value[2049];

      for (int i=1 ; i<=TotalRow; i++)
      {

        iReadKeyValue = ReadKeyValue(fpFileHandle,&last_row,key, value); 
        if ( iReadKeyValue == 0)
        {
            for (int f=0; f < 9; f++)
                 if ( strcmp(key,Keys[f]) == 0)
                 {
                     switch(f)   // char* Keys[9]={"IPAD","USER","PROT","PAWD","SCHM","TOTAL_SQL","LIMIT_ROWS","DEL_SQL","LOG_FILE_NAME"};
                    {
                         case 0 : strcpy(sParameter.ip,value);break;
                         case 1 : strcpy(sParameter.user,value);break;
                         case 2 : strcpy(sParameter.port,value);break;
                         case 3 : strcpy(sParameter.passwd,value);break;
                         case 4 : strcpy(sParameter.schema,value);break;
                         case 5 : strcpy(sParameter.TOTAL_SQL,value); break;
                         case 6 :        sParameter.limit_rows=atoi(value); break;                        
                         case 7 : strcpy(sParameter.DEL_SQL,value); break;
                         case 8 : strcpy(sParameter.logfile,value);break;
                         defaultbreak;
                    }//witch
                    break;
                 }//if
        }

      }


          printf("IP:%s\n",sParameter.ip);
          printf("USER:%s\n",sParameter.user);
          printf("PROT:%s\n",sParameter.port);
          printf("PAWD:%s\n",sParameter.passwd);
          printf("SCHM:%s\n",sParameter.schema);
          printf("TOTAL_SQL:%s\n",sParameter.TOTAL_SQL);
          printf("LIMIT_ROWS:%d\n",sParameter.limit_rows);
          printf("DEL_SQL:%s\n",sParameter.DEL_SQL);
          printf("LOG_FILE_NAME:%s\n",sParameter.logfile);

 }

注解那段函数也是有效的.

开始 定义了 参数变量, 文件句柄变量,文件名和路径,KEY数组
然后文件只读模式打开, 接着就是使用第一个函数读取配置文件
这段注解掉了, 代码比较简单. 判断读成功后就打印参数变量的值

iReadLineStatus=ReadLine(fpFileHandle,Keys,9,&sParameter); 


第二段 局部可以定义变量; 先读取配置文件中函数, 然后循环去读取,假设全部
都是参数,也就是13行. 那么就FOR循环13次就OK
我们定义函数返回执行状态变量, 上次读取行数,接受KEY VALUE的变量.

读取到了KEY 还要跟KEY数组里进行对比 这就要来一次FOR 循环for (int f=0; f < 9; f++)然后对比KEY  if ( strcmp(key,Keys[f]) == 0)
后面就是SWITCH(F)加载到对应的参数结构体变量中.

接下来就是 MYSQL操纵代码部分,跟上篇差不多!
MYSQL my_connection;
  int connect_flag = 0
  mysql_init(&my_connection);     //初始化链接

  char* pHost;
  char* pUser;
  char* pPassword;
  char* pSchema;
  pHost=sParameter.ip;
  pUser=sParameter.user;
  pPassword=sParameter.passwd;
  pSchema = sParameter.schema;

  if (mysql_real_connect(&my_connection,pHost,pUser,pPassword,pSchema,atoi(sParameter.port),NULL,CLIENT_FOUND_ROWS))
   {
     printf("Mysql Connect succent!\n");
     connect_flag = 1;
   }
  else
  {
     printf("Mysql Connect succent!\n");
     connect_flag = 0;
  }

 if ( connect_flag == 1)
 {
  MYSQL_RES* res_ptr;               //返回结果集指针
  MYSQL_ROW result_row;             //返回行
  int res,row,column;               //行列
  long  affected_rows = 0;

  uint8 Count_Rows = 0;

   mysql_query(&my_connection,"set names utf8mb4"); //设置字符集
   res =mysql_query(&my_connection,sParameter.TOTAL_SQL); //执行查询语句
   affected_rows = mysql_affected_rows(&my_connection);
   if(res) { printf("Query Faile %s\n",mysql_error(&my_connection)); } //返回错误
   else
   {
     res_ptr = mysql_store_result(&my_connection);      //获取这次结果集
     if (res_ptr)
     {
            row=mysql_num_rows(res_ptr);                 //获取行数
            column=mysql_num_fields(res_ptr);            //获取列数
            MYSQL_FIELD* FIELD_NAME_ARRY=mysql_fetch_fields(res_ptr);  //获取列名
            for (int c=0; c < column; c++)
            {
                printf("%s\t",FIELD_NAME_ARRY[c].name);
            }
            printf("\n");

            for(int i=1; i< row+1;i++)   //打印行内容
            {
                 result_row= mysql_fetch_row(res_ptr); //提取行到行变量 提取了 MYSQL服务器端就被清空,只能提取一次
                 for (int j=0; j < column;j++)
                   {
                     printf("%s\t",result_row[j]);  //从行变量 获取列的VALUE
                   }
               printf("\n");    
            }
            //result_row= mysql_fetch_row(res_ptr); //提取行到行变量
            Count_Rows = atoi(result_row[0]);
            printf("Count_Rows:%d\n",Count_Rows);
            printf("Count_times:%d\n",Count_Rows/sParameter.limit_rows+1);

       }

    }
    int iLoopTimes = Count_Rows/sParameter.limit_rows+1;

    strcat(sParameter.DEL_SQL," ");
    strcat(sParameter.DEL_SQL,"limit");
    strcat(sParameter.DEL_SQL," ");

    char sLimitRows[10];
    sprintf(sLimitRows,"%d",sParameter.limit_rows);
    strcat(sParameter.DEL_SQL,sLimitRows);

   for ( int i=0 ; i<iLoopTimes; i++)
   {


      res =mysql_query(&my_connection,sParameter.DEL_SQL);         //执行删除语句
      if(res) { printf("Delete Faile %s\n",mysql_error(&my_connection)); } 
      else
      {
       affected_rows = mysql_affected_rows(&my_connection);
       printf("Affected row:%d\n",affected_rows);
      } 

   }
 }



 mysql_close(&my_connection);

}


运行结果:
[deploy@AesygoDB=>DelBigTable]$./test.exe 
IP:192.168.0.227
USER:root
PROT:3306
PAWD:Sharkz@AESYGO
SCHM:lts
TOTAL_SQL:SELECT COUNT(*) as ALLROWS FROM lts.lts_job_log_po WHERE gmt_created< UNIX_TIMESTAMP(date_add(now(), interval -30 day))  *1000
LIMIT_ROWS:1000
DEL_SQL:DELETE FROM lts.lts_job_log_po WHERE gmt_created< UNIX_TIMESTAMP(date_add(now(), interval -30 day)) *1000
LOG_FILE_NAME:DelBigTableLog.txt
Mysql Connect succent!
ALLROWS
18
Count_Rows:18
Count_times:1
Affected row:18
[deploy@AesygoDB=>DelBigTable]$


下面是全部代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <wchar.h>
#include <stdint.h>

#include "../include/mysql/mysql.h"

//C99
typedef char       char1;
typedef wchar_t    varchar4;
typedef int8_t     int1;
typedef int16_t    int2;
typedef int32_t    int4;
typedef int64_t    int8;
typedef uint8_t    uint1;
typedef uint16_t   uint2;
typedef uint32_t   uint4;
typedef uint64_t   uint8;

typedef struct 
{

  char ip[35];
  char user[35];
  char port[5];
  char passwd[35];
  char schema[35];
  uint2  limit_rows;
  char TOTAL_SQL[2049];
  char DEL_SQL[2049];
  char logfile[35];

} Tparameter;
//---------------------------------------------------------------------------------------------------------------------

int ReadLine( FILE* pFileHandle,  char *Keys[],const int KeysLength,Tparameter* pParameter);  
int ReadKeyValue( FILE* pFileHandle,int* plast_row, char* pKey, char *pValue);
int GetFileRowNum( FILE* pFileHandle);
int GetTotal();
int ExecuteDel();




//---------------------------------------------------------------------------------------------------------------------
int main(int argc, char const *argv[])
{

 Tparameter sParameter;
 FILE* fpFileHandle = NULL;  
 char *pFileName="./conf/DelLogTable.conf";                             //文件句柄
 char* Keys[9]={"IPAD","USER","PROT","PAWD","SCHM","TOTAL_SQL","LIMIT_ROWS","DEL_SQL","LOG_FILE_NAME"};

 int iReadLineStatus;


 fpFileHandle = fopen(pFileName,"r");                     //打开文件,读取模式,返回文件句柄
 /*
 if(fpFileHandle !=NULL)
 { 
       fseek(fpFileHandle,0,0);                              //移动文件句柄到文件头部
       iReadLineStatus=ReadLine(fpFileHandle,Keys,9,&sParameter);  //调用上面函数
       if(iReadLineStatus==0)                               //读到真实内容就
       {
          printf("IP:%s\n",sParameter.ip);
          printf("USER:%s\n",sParameter.user);
          printf("PROT:%s\n",sParameter.port);
          printf("PAWD:%s\n",sParameter.passwd);
          printf("SCHM:%s\n",sParameter.schema);
          printf("TOTAL_SQL:%s\n",sParameter.TOTAL_SQL);
          printf("LIMIT_ROWS:%d\n",sParameter.limit_rows);
          printf("DEL_SQL:%s\n",sParameter.DEL_SQL);
          printf("LOG_FILE_NAME:%s\n",sParameter.logfile);
       }
 }
*/


 if(fpFileHandle !=NULL)
 { 
      int TotalRow =0;
      TotalRow = GetFileRowNum(fpFileHandle);

      int iReadKeyValue=1,last_row=1;
      char key[35];
      char value[2049];

      for (int i=1 ; i<=TotalRow; i++)
      {

        iReadKeyValue = ReadKeyValue(fpFileHandle,&last_row,key, value); 
        if ( iReadKeyValue == 0)
        {
            for (int f=0; f < 9; f++)
                 if ( strcmp(key,Keys[f]) == 0)
                 {
                     switch(f)   // char* Keys[9]={"IPAD","USER","PROT","PAWD","SCHM","TOTAL_SQL","LIMIT_ROWS","DEL_SQL","LOG_FILE_NAME"};
                    {
                         case 0 : strcpy(sParameter.ip,value);break;
                         case 1 : strcpy(sParameter.user,value);break;
                         case 2 : strcpy(sParameter.port,value);break;
                         case 3 : strcpy(sParameter.passwd,value);break;
                         case 4 : strcpy(sParameter.schema,value);break;
                         case 5 : strcpy(sParameter.TOTAL_SQL,value); break;
                         case 6 :        sParameter.limit_rows=atoi(value); break;                        
                         case 7 : strcpy(sParameter.DEL_SQL,value); break;
                         case 8 : strcpy(sParameter.logfile,value);break;
                         defaultbreak;
                    }//witch
                    break;
                 }//if
        }

      }


          printf("IP:%s\n",sParameter.ip);
          printf("USER:%s\n",sParameter.user);
          printf("PROT:%s\n",sParameter.port);
          printf("PAWD:%s\n",sParameter.passwd);
          printf("SCHM:%s\n",sParameter.schema);
          printf("TOTAL_SQL:%s\n",sParameter.TOTAL_SQL);
          printf("LIMIT_ROWS:%d\n",sParameter.limit_rows);
          printf("DEL_SQL:%s\n",sParameter.DEL_SQL);
          printf("LOG_FILE_NAME:%s\n",sParameter.logfile);

 }


  MYSQL my_connection;
  int connect_flag = 0
  mysql_init(&my_connection);     //初始化链接

  char* pHost;
  char* pUser;
  char* pPassword;
  char* pSchema;
  pHost=sParameter.ip;
  pUser=sParameter.user;
  pPassword=sParameter.passwd;
  pSchema = sParameter.schema;

  if (mysql_real_connect(&my_connection,pHost,pUser,pPassword,pSchema,atoi(sParameter.port),NULL,CLIENT_FOUND_ROWS))
   {
     printf("Mysql Connect succent!\n");
     connect_flag = 1;
   }
  else
  {
     printf("Mysql Connect succent!\n");
     connect_flag = 0;
  }

 if ( connect_flag == 1)
 {
  MYSQL_RES* res_ptr;               //返回结果集指针
  MYSQL_ROW result_row;             //返回行
  int res,row,column;               //行列
  long  affected_rows = 0;

  uint8 Count_Rows = 0;

   mysql_query(&my_connection,"set names utf8mb4"); //设置字符集
   res =mysql_query(&my_connection,sParameter.TOTAL_SQL); //执行查询语句
   affected_rows = mysql_affected_rows(&my_connection);
   if(res) { printf("Query Faile %s\n",mysql_error(&my_connection)); } //返回错误
   else
   {
     res_ptr = mysql_store_result(&my_connection);      //获取这次结果集
     if (res_ptr)
     {
            row=mysql_num_rows(res_ptr);                 //获取行数
            column=mysql_num_fields(res_ptr);            //获取列数
            MYSQL_FIELD* FIELD_NAME_ARRY=mysql_fetch_fields(res_ptr);  //获取列名
            for (int c=0; c < column; c++)
            {
                printf("%s\t",FIELD_NAME_ARRY[c].name);
            }
            printf("\n");

            for(int i=1; i< row+1;i++)   //打印行内容
            {
                 result_row= mysql_fetch_row(res_ptr); //提取行到行变量 提取了 MYSQL服务器端就被清空,只能提取一次
                 for (int j=0; j < column;j++)
                   {
                     printf("%s\t",result_row[j]);  //从行变量 获取列的VALUE
                   }
               printf("\n");    
            }
            //result_row= mysql_fetch_row(res_ptr); //提取行到行变量
            Count_Rows = atoi(result_row[0]);
            printf("Count_Rows:%d\n",Count_Rows);
            printf("Count_times:%d\n",Count_Rows/sParameter.limit_rows+1);

       }

    }
    int iLoopTimes = Count_Rows/sParameter.limit_rows+1;

    strcat(sParameter.DEL_SQL," ");
    strcat(sParameter.DEL_SQL,"limit");
    strcat(sParameter.DEL_SQL," ");

    char sLimitRows[10];
    sprintf(sLimitRows,"%d",sParameter.limit_rows);
    strcat(sParameter.DEL_SQL,sLimitRows);

   for ( int i=0 ; i<iLoopTimes; i++)
   {


      res =mysql_query(&my_connection,sParameter.DEL_SQL);         //执行删除语句
      if(res) { printf("Delete Faile %s\n",mysql_error(&my_connection)); } 
      else
      {
       affected_rows = mysql_affected_rows(&my_connection);
       printf("Affected row:%d\n",affected_rows);
      } 

   }
 }



 mysql_close(&my_connection);

}

//---------------------------------------------------------------------------------------------------------------------

int ReadLine(  FILE* pFileHandle,  char *Keys[],const int KeysLength,Tparameter* pParameter)
{

   char LineBuf [2049]; //临时缓存区
   char ValueBuf [2049]; //临时缓存区
   char KeyBuf[35];
   memset(LineBuf,'\0',sizeof(LineBuf));            //临时缓存区初始化 
   memset(KeyBuf,'\0',sizeof(KeyBuf));      
   memset(ValueBuf,'\0',sizeof(ValueBuf)); 
   int iLimitRows=0;     

  if (pFileHandle != NULL)    
  {
    while(!feof(pFileHandle))                 //没有读到文件尾则循环读取
    {              

      fgets(LineBuf,2049,pFileHandle);                   //读取下行到BUF中
      if ( (LineBuf[0]=='#')||(LineBuf[0]=='\0') || (LineBuf[0]=='\r') || (LineBuf[0]=='\n') || (LineBuf[0]==' ') ) //如果这行是注解,回车,换行,空格则跳过
      {  continue ; }
      else
      {          
       for (int i=0;i<strlen(LineBuf);i++)                     //读取每一个字符
       {                          
         if ( LineBuf[i] == '=' )                                  //找到等号
         {   
             for ( int j=0; j<i;j++)       KeyBuf[j]=LineBuf[j];                      //把该行内容读到返回变量中                           
             for ( int k=1; k <= (strlen(LineBuf)-i);k++)   
              {
                if (LineBuf[k+i] !='\n')   
                {
                 ValueBuf[k-1]=LineBuf[k+i];                      //把该行内容读到返回变量中                           
                }
                else
                 break;
              }

             for (int f=0; f < KeysLength; f++)
                 if ( strcmp(KeyBuf,Keys[f]) == 0)
                 {
                     switch(f)   // char* Keys[9]={"IPAD","USER","PROT","PAWD","SCHM","TOTAL_SQL","LIMIT_ROWS","DEL_SQL","LOG_FILE_NAME"};
                    {
                         case 0 : strcpy(pParameter->ip,ValueBuf);break;
                         case 1 : strcpy(pParameter->user,ValueBuf);break;
                         case 2 : strcpy(pParameter->port,ValueBuf);break;
                         case 3 : strcpy(pParameter->passwd,ValueBuf);break;
                         case 4 : strcpy(pParameter->schema,ValueBuf);break;
                         case 5 : strcpy(pParameter->TOTAL_SQL,ValueBuf); break;
                         case 6 : pParameter->limit_rows=atoi(ValueBuf); break;                        
                         case 7 : strcpy(pParameter->DEL_SQL,ValueBuf); break;
                         case 8 : strcpy(pParameter->logfile,ValueBuf);break;
                         defaultbreak;
                    }//witch
                    break;
                 }//if
           break;
          }//if
       }//for
      }//else if      
      memset(LineBuf,'\0',sizeof(LineBuf));            
      memset(KeyBuf,'\0',sizeof(KeyBuf));      
      memset(ValueBuf,'\0',sizeof(ValueBuf));                    
    }//while 
    return 0 ;
  } //feof
return 1 ;
}




int ReadKeyValue( FILE* pFileHandle,int* plast_row,char* pKey, char *pValue)   //参数说明 第一个是文件句柄,第二个是上次读的行数,第3个是返回读取内容,第4个是等号位置
{

  char LineBuf[2049],KeyBuf[1024],ValueBuf[2049];                                                                                    //临时缓存区
  int  buff_size,i,iCurRow;
  iCurRow=1
  buff_size=0;
  memset(LineBuf,'\0',sizeof(LineBuf));        
  memset(KeyBuf,'\0',sizeof(KeyBuf));   
  memset(ValueBuf,'\0',sizeof(ValueBuf));    
                                                                                                                     //临时缓存区初始化      

  if (pFileHandle != NULL)    
  {
     fseek(pFileHandle,0,0);

    while(!feof(pFileHandle))                                                                          //没有读到文件尾则循环读取
    {              
       if( iCurRow >= *plast_row)                                                                          //正好读取到上次的位置时 
       {         
          fgets(LineBuf,2049,pFileHandle);                                                               //读取下行到BUF中
          iCurRow++;
          if ((LineBuf[0]=='#')||(LineBuf[0]=='\0')||(LineBuf[0]=='\r')||(LineBuf[0]=='\n')||(LineBuf[0]==' '))      //如果这行是注解,回车,换行,空格则跳过
            {            continue ;            }
          else
          {          
            for (i=0;i<strlen(LineBuf);i++)                                                 //读取每一个字符
            {                          
              if (LineBuf[i]=='=')                                                           //找到等号
              {   
                for ( int j=0; j<i;j++)       KeyBuf[j]=LineBuf[j];                      //读取KEY
                for ( int k=1; k <= (strlen(LineBuf)-i);k++)   
                 { 
                   if (LineBuf[k+i] !='\n'
                     {
                        ValueBuf[k-1]=LineBuf[k+i];                                         //读取VALUE                        
                      }
                    else   break;
                  }
                 *plast_row=iCurRow;
                 strcpy(pKey,KeyBuf);
                 strcpy(pValue,ValueBuf);
                 return 0;
              }  
            } 
           } //if # \r \n space charter
          } // if last row > cur row
          else
          {
            fgets(LineBuf,2049,pFileHandle);   // 已读过的行,文件指针下移一行
            iCurRow++;
          }

        } //while file read

      }
  return 1 ;
}



int GetFileRowNum( FILE* pFileHandle)
{
 int  iRow=0;
 char buff[2048];
 if (pFileHandle != NULL)
     while (!feof(pFileHandle)) 
     {
      fgets(buff,2049,pFileHandle); 
       iRow++;
     }  
  return iRow;



用C语言去操作MYSQL
c语言读取文本文件
C语言写文件C语言 地址变量 中级应用现代 C99, C11 标准下的 C 语言编程一篇讲清Linux下GCC编译C语言的参数C语言写文件FIX
C 语言的标准时间封装



文章转载自海鲨数据库架构师,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论