// TSUNAMI - Text Search Utility //-------------------- // Searches files for multiple text strings // // - Takes up to 10 search strings // - Searches up to 10 file types // - Accepts wildcards (*, ?) in file types // - Optionally searches subdirectories // - Optionally searches hidden files/directories // - Program can be paused or aborted early // - Handles both text and binary files // - All search strings must be found in file // - Writes search results (file name and path) to // TSUNAMI.OUT in current working directory // #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <dir.h> #include <dos.h> #include <string.h> const MAX_STRING = 512; const MAX_LIST = 10; const MAX_FNAME = 13; // max. field length for file types const MAX_SSTR = 64; // max. field length for search strings struct ft_list { char array[MAX_LIST][MAX_FNAME]; int count; }; struct ss_list { char array[MAX_LIST][MAX_SSTR]; int count; }; struct ft_list FLIST; // stores file types to search in struct ss_list SLIST; // stores strings to search for char SRCH_DIR[MAX_STRING]; char ORIG_DIR[MAX_STRING]; const YES = 1; const NO = 0; int DO_SUBDIRS; int DO_HIDDEN; int DO_OPTIMIZE; int RESULTS_COUNT = 0; char RESULTS_FILE[MAX_FNAME] = "TSUNAMI.OUT"; // output file FILE *results_fptr; //-------------------------------------------------------- void pause (void) { printf("\nPress any key... \n"); while (!kbhit()); } //----------------------------- int file_exist (const char *fname) { struct ffblk ffblk; return(findfirst(fname, &ffblk, FA_DIREC+FA_HIDDEN)); } //-------------------------------------------------------- char *upstr (char *s) { int i; for (i = 0; s[i] != 0; i++) s[i] = toupper(s[i]); return (s); } // upstr //-------------------------------------------------------- int get_ext_key (char k) { if (k == 0) k = getch(); return (k); } // get_ext_key //-------------------------------------------------------- char *get_input (char *s, int max_len) // s is the default input string to display // max_len is the maximum length for input + 1 // length of s MUST be <= max_len <= MAX_STRING { char t[MAX_STRING] = {'\0'}; int i, key; if (max_len > MAX_STRING) max_len = MAX_STRING; // keep in range strcpy(t, s); i = strlen(s); printf("%s", s); while (!kbhit()) { switch(key = getch()) { case 0: // EXTENDED KEY { key = get_ext_key(key); break; } case 8: // BACKSPACE { if (i > 0) { putch(key); putch(' '); putch(key); t[--i] = '\0'; } break; } case 13: // RETURN { putch('\n'); putch(key); strcpy(s, t); return(s); } case 27: // ESCAPE { putch('\n'); putch('\r'); s = ""; return(s); } default: { if (i < max_len-1) // allow for ending null { putch(key); t[i] = key; i++; t[i] = '\0'; break; } } } } return (s); } // get_input //-------------------------------------------------------- void user_interrupt (void) { int key = 0; switch (key = (int) toupper(getch())) { case 'P': // PAUSE { printf("\rPausing. Press any key to continue..."); clreol(); while (!kbhit()); break; } case 27: // ESCAPE { printf("\rAborting TSUNAMI"); clreol(); printf("\n\n%d results saved in %s\n", RESULTS_COUNT, RESULTS_FILE); chdir(ORIG_DIR); exit(1); } default: { } } } // user_interrupt //-------------------------------------------------------- void input_search_directory (void) { char s[MAX_STRING] = {'\0'}; strcpy(s, "C:\\DOCUME~1\\ADMINI~1\\MYDOCU~1\\DOWNLO~1"); printf("Specify directory to search in:\n"); do { strcpy(SRCH_DIR, upstr(get_input(s, MAX_STRING))); if (SRCH_DIR[0] == '\0') { printf("\nAborting TSUNAMI...\n"); exit(1); } if (SRCH_DIR[strlen(SRCH_DIR)-1] == '\\') SRCH_DIR[strlen(SRCH_DIR)-1] = '\0'; if (file_exist(SRCH_DIR) != 0) printf("\nERROR: Directory does not exist. Try again:\n"); strcpy(s, ""); } while (file_exist(SRCH_DIR) != 0); } // input_search_directory //-------------------------------------------------------- int toggle_YN (char *s) { char ch; printf("%s", s); do ch = toupper(getch()); while ((ch != 'Y') && (ch != 'N')); printf("%c\n", ch); if (ch == 'Y') return(YES); else return(NO); } // toggle_YN //-------------------------------------------------------- void input_search_strings (void) { char s[MAX_SSTR] = {'\0'}; SLIST.count = 0; printf("Specify search strings (max. 10):\n"); while (SLIST.count < MAX_LIST) { strcpy(s, ""); printf("%d) ", SLIST.count+1); strcpy(s, get_input(s, MAX_SSTR)); if (s[0] == '\0') break; strcpy(SLIST.array[SLIST.count], s); SLIST.count++; } } // input_search_strings //-------------------------------------------------------- void input_file_strings (void) { char s[MAX_FNAME] = {'\0'}; FLIST.count = 0; printf("Specify file types to search for (max. 10):\n"); while (FLIST.count < MAX_LIST) { strcpy(s, "*.*"); printf("%d) ", FLIST.count+1); strcpy(s, upstr(get_input(s, MAX_FNAME))); if (s[0] == '\0') break; strcpy(FLIST.array[FLIST.count], s); FLIST.count++; } } // input_file_strings //-------------------------------------------------------- int search_file_for_string (char *fname, char *s) { FILE *fptr; struct ffblk ffblk; char ch; int len; int si = 0; // search string index long fi = 0; // file index len = strlen(s); if ((fptr = fopen(fname, "rb")) != NULL) { findfirst(fname, &ffblk, FA_HIDDEN); while (fi < ffblk.ff_fsize) { ch = fgetc(fptr); fi++; // convert special characters to spaces if ((ch == '\n') || (ch == '\r') || (ch == '\t') || (ch == '\0')) ch = ' '; if ((ch == s[si]) && (si < len)) { si++; if (si == len) { fclose(fptr); return(1); } } else si = 0; } fclose(fptr); } return(0); } // search_file_for_string //-------------------------------------------------------- void save_results_to_file (char *fname) { char cwd[MAX_STRING] = {'\0'}; getcwd(cwd, MAX_STRING); if (cwd[3] != '\0') strcat(cwd, "\\"); fprintf(results_fptr, "%s%s\n", cwd, fname); if (!DO_OPTIMIZE) printf("\n"); } // save_results_to_file //-------------------------------------------------------- void search_for_strings (char *fname) { int i, n; n = 0; for (i = 0; i < SLIST.count; i++) { if (search_file_for_string(fname, SLIST.array[i]) == 0) break; if (kbhit()) user_interrupt(); // check for pause or abort n++; } if ((n > 0) && (n == SLIST.count)) { RESULTS_COUNT++; save_results_to_file(fname); } } // search_for_strings //-------------------------------------------------------- void search_for_files (char *fname) { struct ffblk ffblk; char cwd[MAX_STRING] = {'\0'}; int att = 0; int done; getcwd(cwd, MAX_STRING); if (cwd[3] != '\0') strcat(cwd, "\\"); if (DO_HIDDEN == YES) att = FA_HIDDEN; done = findfirst(fname, &ffblk, att); while (!done) { if (DO_OPTIMIZE == YES) search_for_strings(ffblk.ff_name); else { printf("\r%s%s", cwd, ffblk.ff_name); clreol(); search_for_strings(ffblk.ff_name); printf("\r"); clreol(); } done = findnext(&ffblk); } if (DO_SUBDIRS == YES) { att = att + FA_DIREC; done = findfirst("*.*", &ffblk, att); while (!done) { if (ffblk.ff_attrib & FA_DIREC) { if (ffblk.ff_name[0] != '.') { chdir(ffblk.ff_name); search_for_files(fname); chdir(".."); } } done = findnext(&ffblk); } } } // search_for_files //-------------------------------------------------------- int main (void) { int i; clrscr(); input_search_directory(); DO_SUBDIRS = toggle_YN("Search subdirectories? [Y/N]: "); DO_HIDDEN = toggle_YN("Search hidden files/directories? [Y/N]: "); DO_OPTIMIZE = toggle_YN("Full optimization (no screen output)? [Y/N]: "); input_search_strings(); input_file_strings(); getcwd(ORIG_DIR, MAX_STRING); if ((results_fptr = fopen(RESULTS_FILE, "wt")) != NULL) { chdir(SRCH_DIR); printf("Press (P) to Pause, (ESC) to Abort... for (i = 0; i < FLIST.count; i++) search_for_files(FLIST.array[i]); chdir(ORIG_DIR); fclose(results_fptr); printf("\n%d results in %s\n", RESULTS_COUNT, RESULTS_FILE); pause(); } return(0); }
C++ Programming for Novices
This blog is for novice C and C++ programmers who want to learn, share, and explore computer programming.
Wednesday, April 9, 2014
Updated Text Search Utility (Source Code)
Monday, April 7, 2014
My Text Search Utility
// TSUNAMI - Text Search Utility
// -----------------------------------
// Searches files for multiple text strings in given directory.
//
// - Takes up to 10 search strings
// - Searches up to 10 file types
// - Optionally searches subdirectories
// - Optionally searches hidden files/directories
// - Writes results to RESULTS.TMP in current working
// directory.
//
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <dir.h>
#include <dos.h>
#include <string.h>
const MAX_STRING = 1024;
const MAX_LIST = 10;
const MAX_FNAME = 13;
const MAX_SSTR = 64;
const YES = 1;
const NO = 0;
struct ft_list {
char array[MAX_LIST][MAX_FNAME];
int count;
};
struct ss_list {
char array[MAX_LIST][MAX_SSTR];
int count;
};
struct ft_list FLIST;
struct ss_list SLIST;
char RESULTS_FILE[MAX_FNAME] = "RESULTS.TMP";
char SRCH_DIR[MAX_STRING];
char ORIG_DIR[MAX_STRING];
int DO_SUBS;
int DO_HIDDEN;
FILE *results_fptr;
//--------------------------------------------------------
pause ()
{
printf("\nPress any key... \n");
while (!kbhit());
return(0);
}
//-----------------------------
int file_exist (const char *fname)
{
struct ffblk ffblk;
return(findfirst(fname, &ffblk, FA_DIREC+FA_HIDDEN));
}
//--------------------------------------------------------
char *upstr (char *s)
{
int i;
for (i = 0; s[i] != 0; i++) s[i] = toupper(s[i]);
return (s);
} // upstr
//--------------------------------------------------------
int get_ext_key (char k)
{
if (k == 0) k = getch();
return (k);
} // get_ext_key
//--------------------------------------------------------
char *get_input (char *s, int max_len)
{
char *t;
int i, key;
if ((t = (char *) malloc(MAX_STRING)) != NULL)
{
if (max_len <= MAX_STRING) strcpy(t, s);
i = strlen(t);
printf("%s", s);
while (!kbhit())
{
switch(key = getch())
{
case 0: // EXTENDED KEY
{
key = get_ext_key(key);
break;
}
case 8: // BACKSPACE
{
if (i > 0)
{
putch(key);
putch(' ');
putch(key);
t[--i] = '\0';
}
break;
}
case 13: // RETURN
{
putch('\n');
putch(key);
s = t;
return(s);
}
case 27: // ESCAPE
{
putch('\n');
putch('\r');
return(s);
}
default:
{
if (i < max_len)
{
putch(key);
t[i] = key;
i++;
t[i] = '\0';
break;
}
}
}
}
free(t);
}
return (s);
} // get_input
//--------------------------------------------------------
input_search_directory ()
{
struct ffblk ffblk;
char *s;
if ((s = (char *) malloc(MAX_STRING)) != NULL)
{
printf("Specify directory to search in:\n");
do
{
s = "";
strcpy(SRCH_DIR, upstr(get_input(s, MAX_STRING)));
if (SRCH_DIR[0] == '\0')
{
printf("\nAborting TSU...\n");
exit(1);
}
if (SRCH_DIR[strlen(SRCH_DIR)-1] == '\\')
SRCH_DIR[strlen(SRCH_DIR)-1] = '\0';
if (file_exist(SRCH_DIR) != 0)
printf("\nERROR: Directory does not exist. Try again:\n");
}
while (file_exist(SRCH_DIR) != 0);
free(s);
}
return (0);
} // input_search_directory
//--------------------------------------------------------
int toggle_subdirectories ()
{
char ch;
printf("Search subdirectories? [Y/N]: ");
do
ch = toupper(getch());
while ((ch != 'Y') && (ch != 'N'));
printf("%c\n", ch);
if (ch == 'Y') DO_SUBS = YES; else DO_SUBS = NO;
return (0);
} // toggle_subdirectories
//--------------------------------------------------------
int toggle_hidden ()
{
char ch;
printf("Search hidden files/directories? [Y/N]: ");
do
ch = toupper(getch());
while ((ch != 'Y') && (ch != 'N'));
printf("%c\n", ch);
if (ch == 'Y') DO_HIDDEN = YES; else DO_HIDDEN = NO;
return (0);
} // toggle_hidden
//--------------------------------------------------------
input_file_strings ()
{
char *s;
if ((s = (char *) malloc(MAX_FNAME)) != NULL)
{
s = "*.*";
FLIST.count = 0;
printf("Specify file types to search for (max. 10):\n");
while (FLIST.count < MAX_LIST)
{
printf("%d) ", FLIST.count+1);
s = upstr(get_input(s, MAX_FNAME));
strcpy(FLIST.array[FLIST.count], s);
if (FLIST.array[FLIST.count][0] == NULL) break;
FLIST.count++;
s = "";
}
free(s);
}
return (0);
} // input_file_strings
//--------------------------------------------------------
input_search_strings ()
{
char *s;
if ((s = (char *) malloc(MAX_SSTR)) != NULL)
{
SLIST.count = 0;
printf("Specify search strings (max. 10):\n");
while (SLIST.count < MAX_LIST)
{
printf("%d) ", SLIST.count+1);
s = "";
s = get_input(s, MAX_SSTR);
strcpy(SLIST.array[SLIST.count], s);
if (SLIST.array[SLIST.count][0] == NULL) break;
SLIST.count++;
}
free(s);
}
return (0);
} // input_search_strings
//--------------------------------------------------------
int search_file_for_string (char *fname, char *s)
{
struct ffblk ffblk;
char ch;
int i = 0;
int len;
FILE *fptr;
len = strlen(s);
if ((fptr = fopen(fname, "rt")) != NULL)
{
do
{
ch = fgetc(fptr);
// convert special characters to spaces
if ((ch == '\n') || (ch == '\r') || (ch == '\0')) ch = ' ';
if ((ch == s[i]) && (i < len))
{
i++;
if (i == len)
{
fclose(fptr);
return(1);
}
}
else i = 0;
}
while (ch != EOF);
fclose(fptr);
}
return(0);
} // search_file_for_string
//--------------------------------------------------------
save_results_to_file (char *fname)
{
char cwd[MAX_STRING];
getcwd(cwd, MAX_STRING);
if (cwd[3] != '\0') strcat(cwd, "\\");
fprintf(results_fptr, "%s%s\n", cwd, fname);
printf("\n");
return(0);
} // save_results_to_file
//--------------------------------------------------------
search_for_strings (char *fname)
{
int i, n;
char *cwd;
n = 0;
for (i = 0; i < SLIST.count; i++)
{
if (search_file_for_string(fname, SLIST.array[i]) == 0) break;
n++;
}
if ((n > 0) && (n == SLIST.count))
save_results_to_file(fname);
return(0);
} // search_for_strings
//--------------------------------------------------------
search_for_files (char *fname)
{
struct ffblk ffblk;
char cwd[MAX_STRING];
int att = 0;
int done;
getcwd(cwd, MAX_STRING);
if (cwd[3] != '\0') strcat(cwd, "\\");
if (DO_HIDDEN == YES) att = FA_HIDDEN;
done = findfirst(fname, &ffblk, att);
while (!done)
{
printf("\r%s%s", cwd, ffblk.ff_name);
clreol();
search_for_strings(ffblk.ff_name);
printf("\r");
clreol();
done = findnext(&ffblk);
}
if (DO_SUBS == YES)
{
att = att + FA_DIREC;
done = findfirst("*.*", &ffblk, att);
while (!done)
{
if (ffblk.ff_attrib & FA_DIREC)
{
if (ffblk.ff_name[0] != '.')
{
chdir(ffblk.ff_name);
search_for_files(fname);
chdir("..");
}
}
done = findnext(&ffblk);
}
}
return (0);
} // search_for_files
//--------------------------------------------------------
int main (void)
{
int i;
clrscr();
input_search_directory();
toggle_subdirectories();
toggle_hidden();
input_search_strings();
input_file_strings();
getcwd(ORIG_DIR, MAX_STRING);
if ((results_fptr = fopen(RESULTS_FILE, "wt")) != NULL)
{
if (chdir(SRCH_DIR) == 0)
{
for (i = 0; i < FLIST.count; i++)
search_for_files(FLIST.array[i]);
chdir(ORIG_DIR);
}
fclose(results_fptr);
pause();
}
return(0);
}
Subscribe to:
Posts (Atom)