пару недель назад столкнулся с такой проблемой. был лог, и из этого лога нужно было вытащить числа, сложить и посчитать среднее арифметическое. я не нашёл никакой тулзы или редактора который бы мог сделать это автоматом и не нужно было клацать на калькуляторе 150 чисел вручную (хотя не исключено что вим это умеет). вот кусок лога: [demod/stv362/s362lock.c:189][0] s362_Lock() Status[2] Time[500ms] [demod/stv362/s362lock.c:189][0] s362_Lock() Status[2] Time[400ms] [demod/stv362/s362lock.c:189][0] s362_Lock() Status[2] Time[1800ms] [demod/stv362/s362lock.c:189][0] s362_Lock() Status[2] Time[500ms] мне нужно было вытащить эти самые миллисекунды. я решил не заморачиваться поисками и написал такую простенькую программку, которая это делает. в данный момент нет поддержки связанных списков для файлов неопределённого размера, не поддерживается обработка того, что время попадается 2 раза в строке, и нет защиты от переполнения unsigned int переменной. В общем-то хотелось бы послушать какие ещё тут могут быть бока, а также про неоптимальность алгоритма и т.д. и т.п. ;)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *version="0.53";
#define CHARS_PER_STRING 300
//#define DEBUG_ENABLE
FILE * file_ptr;
int times[300]; // strings in file
int FileScan(FILE* file_ptr, const char * sequence)
{
unsigned int i;
unsigned int sequence_size=0;
unsigned int total=0;
unsigned char have_sequence=0;
char tmp_string[CHARS_PER_STRING]; //array to contain one string
char * tmp_str_ptr;
char digit[10];
int digit_cnt=0;
unsigned int strings_seq_cnt=0; //strings with sequence found
unsigned int strings_total_cnt=0; //total number of strings in file
sequence_size=strlen(sequence);
#ifdef DEBUG_ENABLE
printf ("sequence: %s \n", sequence);
printf("size of seq %d\n", sequence_size);
#endif
//working till the EOF, one iteration == one string have read
while ( fgets(tmp_string,CHARS_PER_STRING,file_ptr) != NULL )
{
tmp_str_ptr=tmp_string;
have_sequence=0;
while (*tmp_str_ptr)
{
if (*tmp_str_ptr == *sequence)
{
if ( !strncmp(tmp_str_ptr,sequence,sequence_size) ) //if we found Time[
{
#ifdef DEBUG_ENABLE
printf("seq found\n");
#endif
tmp_str_ptr += sequence_size ; //set pointer to time digits
while (*tmp_str_ptr >= '0' && *tmp_str_ptr <= '9')
{
if (digit_cnt >= 10)
{
printf("[error] value found is too big. \n");
return 1;
}
digit[digit_cnt]=*tmp_str_ptr;
tmp_str_ptr++;
digit_cnt++;
have_sequence=1;
}
#ifdef DEBUG_ENABLE
printf ("digit %d \n",digit_cnt);
#endif
}
}
tmp_str_ptr++;
}
if (have_sequence)
{
times[strings_seq_cnt]=atoi(digit);
strings_seq_cnt++;
}
for (i=0; i<10; i++)
digit[i]='a';
strings_total_cnt++; //increased for every cycle iteration, contains number of strings in file
digit_cnt=0;
}
for (i=0; i<strings_seq_cnt; i++)
{
total+=times[i];
printf ("string: %d time : %d \n",i+1,times[i]);
}
printf ("strings total: %d \n",strings_total_cnt);
printf ("strings with sequence: %d \n",strings_seq_cnt);
printf ("time sum: %d \n",total);
if (strings_seq_cnt)
total/=strings_seq_cnt;
printf ("time~: %d\n",total);
return 0;
}
int main (int argc , char* argv[])
{
unsigned int i;
#ifdef DEBUG_ENABLE
printf("timefromlog started. version: %s\n",version);
printf("argc=%d\n",argc);
for (i=0; i<argc; i++)
{
printf("argv[%d]: %s\n",i,argv[i]);
}
#endif
//parsing input without getopt() !
if (argc == 2)
{
if ( !(strcmp(argv[1],"--help") ) )
printf ("this is a help for timefromlog program.\nfirst param: filename to search in.\nsecond param: sequence digits start after.\n --help - this help\n --version - program version\n");
else if ( !(strcmp(argv[1],"--version") ) )
printf ("version: %s \n", version);
else
printf("incorrect params. run program with --help\n");
return 1;
}
else if (argc != 3)
{
printf("incorrect params. run program with --help\n");
return 1;
}
file_ptr=fopen(argv[1],"r");
if (!file_ptr)
{
printf("[error] : can't open file\n");
return 1;
}
else
printf("[working] : file opened\n");
FileScan(file_ptr, argv[2]);
if ( !fclose(file_ptr) )
printf("[working] : file closed successfully\n");
else
printf("[error] : file can not be closed\n");
return 0;
}