I used to write a C program on Linux. I used Lex for lexical analysis to count the characters, words, and lines of N text files at the same time. I think Lex is really interesting. It is true that Lex is very powerful and suitable for small lexical analysis. This program references an example in lex and YACC.
% {
Unsigned int char_count = 0, word_count = 0, line_count = 0;
%}
%
[^/T/N] + {word_count ++; char_count + = yyleng ;};
/N {char_count ++; line_count ++ ;};
. Char_count ++;
%
Char ** file_list;
Unsigned int current_file = 0;
Unsigned int total_file = 0;
Unsigned int total_cc = 0;
Unsigned int total_wc = 0;
Unsigned int total_lc = 0;
Typedef struct file_info {
Unsigned int C;
Unsigned int W;
Unsigned int L;
Char * Name;
} Info;
Info ** all;
Int create_info (INT num)
{
Info * TMP;
Int I;
If (Num <= 0 ){
Return-1;
}
All = (Info **) malloc (sizeof (int *) * num );
For (I = 0; I <num; I ++ ){
TMP = (Info *) malloc (sizeof (Info ));
TMP-> C = 0;
TMP-> W = 0;
TMP-> L = 0;
TMP-> name = NULL;
All [I] = TMP;
}
Return 1;
}
Int delete_info (INT num)
{
Int I;
If (all = (Info **) 0) | num <= 0 ){
Return-1;
}
For (I = 0; I <num; I ++ ){
Free (ALL [I]);
}
Free (all );
Return 1;
}
Int set_info (int pos)
{
Int length = 0;
If (Pos <0 ){
Return-1;
}
All [POS]-> C = char_count;
All [POS]-> W = word_count;
All [POS]-> L = line_count;
All [POS]-> name = file_list [POS];
Return 1;
}
Int main (INT argc, char ** argv)
{
File * file;
Int position = 0;
Int I;
File_list = argv + 1;
Total_file = argc-1;
Current_file = 0;
Printf ("--------------------------------------------------------------/N ",
Total_file );
If (argc> 1 ){
If (create_info (total_file) =-1 ){
Fprintf (stderr, "% s/n", "encounter a error when malloc memory .");
Exit (1 );
}
}
If (argc = 2 ){
File = fopen (argv [1], "R ");
If (! File ){
Fprintf (stderr, "cocould not open % S./N", argv [1]);
Delete_info (total_file );
Exit (1 );
}
Yyin = file;
}
Yywrap ();
Yylex ();
If (argc> 1 ){
Total_cc + = char_count;
Total_wc + = word_count;
Total_lc + = line_count;
If (set_info (current_file-1) =-1 ){
Fprintf (stderr, "% s/n", "encounter a error when set information
Info .");
Delete_info (total_file );
Exit (1 );
}
For (I = 0; I <total_file; I ++ ){
Printf ("char: %-8lu word: %-8lu line: %-8lu file name: % s/n", all [I]->
C, all [I]-> W, all [I]-> L, file_list [I]);
}
Printf ("------------------------- total --------------------------------
/N ");
Printf ("chars: %-8lu words: %-8lu lines: %-8lu files: % d/N", total_cc, tot
Al_wc, total_lc, total_file );
} Else {
Printf ("char: %-8lu word: %-8lu line: %-8lu/N", char_count, word_count, l
Ine_count );
}
Delete_info (total_file );
Return 0;
}
Yywrap ()
{
File * file = NULL;
If (current_file> 0) & (current_file <total_file) & (total_file> 1 ))
{
Total_cc + = char_count;
Total_wc + = word_count;
Total_lc + = line_count;
If (set_info (current_file-1) =-1 ){
Fprintf (stderr, "% s/n", "encounter a error when set information
Info .");
Delete_info (total_file );
Exit (1 );
}
Char_count = word_count = line_count = 0;
Fclose (yyin );
}
While (file_list [current_file]! = (Char *) 0) & (current_file <total_fil
E )){
File = fopen (file_list [current_file ++], "R ");
If (! File ){
Fprintf (stderr, "cocould not open % S.", file_list [current_file-1]
);
} Else {
Yyin = file;
Break;
}
}
Return (file? 0: 1 );
}