fork download
  1. //GREP.CPP
  2. //COPYRIGHT EMILE J. KEITH 2014//
  3. #include <iostream>
  4. #include <regex>
  5. #include <cstdlib>
  6. #include <exception>
  7. #include <fstream>
  8. #include <iomanip>
  9. #include <boost/filesystem.hpp>//filesystem header file from boost library, cross platform compatible
  10.  
  11. using namespace std;
  12. using namespace boost::filesystem;
  13.  
  14. int main(int argc, char *argv[])
  15. {
  16. if(argc<3)
  17. {
  18. cout<<"Not enough Arguments provided\n";
  19. }
  20. else
  21. {
  22. regex rootExpression("([A-Za-z]:[\\\\/]){1,1}");//This expression states the first char in the word must be any capital letter followed by a : and then a back or forward slash
  23. regex expressionToMatch;
  24. string concatinatedPath, extension, fileToSearch, fileName, fileExtension, currentLine;
  25. bool iFlag=false, vFlag=false, lFlag=false, nFlag=false, cFlag=false, iterator=false, fullPathProvided=false, match=false;
  26. /*iFlag is ignore case
  27. vFlag prints non matching
  28. lFlag prints just file names instead of actual matching string
  29. nFlag prints line number in input file
  30. cFlag just print number of matches and not the matches*/
  31. unsigned short lineNumber, numberOfMatches=0;
  32. unsigned long currentPosition, endOfFile;
  33. path searchPath;//a class from the boost filesystem header
  34. if(argc>=4 && argv[1][0]=='-' && argv[1][1]=='i')
  35. iFlag=true;
  36. else if(argc>=4 && argv[1][0]=='-' && argv[1][1]=='v')//Only one flag can be provided as an argument, therefore else if works perfectly for this situation
  37. vFlag=true;
  38. else if(argc>=4 && argv[1][0]=='-' && argv[1][1]=='l')
  39. lFlag=true;
  40. else if(argc>=4 && argv[1][0]=='-' && argv[1][1]=='n')
  41. nFlag=true;
  42. else if(argc>=4 && argv[1][0]=='-' && argv[1][1]=='c')
  43. cFlag=true;
  44. for(unsigned short count=argc-1;count>0;count--)
  45. {
  46. if(regex_search(string(argv[count]),rootExpression))//if the current argument matches the expression
  47. {
  48. fullPathProvided=true;
  49. for(unsigned short counter=count; counter<argc; counter++)
  50. {
  51. concatinatedPath+=argv[counter];//concatinate it onto the string
  52. if(concatinatedPath[concatinatedPath.length()-1]!='\\' && counter!=(argc-1))//And as long as the last char of the argument is not a \ and it is not the last argument
  53. {
  54. concatinatedPath+=" ";//add a space
  55. }
  56. }
  57. break;//break the for loop
  58. }
  59. }
  60. if(!fullPathProvided)//If a full search path was not provided, identified by the previous regex having no matches
  61. concatinatedPath=argv[argc-1];//Use the last provided argument as the concatinated path
  62. if((concatinatedPath.find_last_of('\\')+1==concatinatedPath.find_last_of('*'))||(concatinatedPath.find_last_of('/')+1==concatinatedPath.find_last_of('*')) || ((!fullPathProvided) && concatinatedPath.at(0)=='*' && concatinatedPath.at(1)=='.'))
  63. {//if the char in the path after the last \ or / is *
  64. iterator=true;
  65. extension=concatinatedPath.substr(concatinatedPath.find_last_of('.'),string::npos);//take a substring begining from the last . and assign it to the extension
  66. }
  67. else
  68. {
  69. fileToSearch=concatinatedPath.substr(concatinatedPath.find_last_of('\\')+1,string::npos);//else everything after the last \ or / specifies a specific file to search
  70. }
  71. if(iFlag)//if the -i flag is active
  72. expressionToMatch.assign(argv[2],regex::icase);//Assign the third argument to the regex object expressionToMatch and make it case insensitive
  73. else
  74. expressionToMatch.assign(argv[1]);//else assign the second argument to expressionToMatch
  75. if(fullPathProvided)
  76. searchPath.append(concatinatedPath);
  77. else
  78. searchPath.append(current_path().string()+"\\"+concatinatedPath);
  79. if(exists(searchPath) || (iterator && exists(searchPath.parent_path())))//If the path exists, or iteretor is true and the root path for the searPath variable exists
  80. {
  81. if(iterator)//if iteratin
  82. {
  83. directory_iterator end_iter;//directory_iterator class, when initialized without a path, it is default set to indicate the end of a directory flag
  84. if(searchPath.parent_path()==current_path())//If the searPath root is the same as current directoyr
  85. {
  86. for(directory_iterator dir_iter(searchPath.parent_path()); dir_iter!=end_iter; ++dir_iter)//this time the directory_iterator class instance was intitialized with a path vairiable, and is set to the beginning of the directory(LAYMAN'S TERMS)
  87. {
  88. path newPath=dir_iter->path();//new path currently holds the value of the path for the item dir_iter is currently positioned on
  89. fileName=newPath.filename().string();//extracts the filename from the path, casts to a string then returns it
  90. fileExtension=newPath.extension().string();
  91. if(is_regular_file(newPath))
  92. {
  93. if(fileExtension==extension)
  94. {
  95. ifstream file((fileName+fileExtension));
  96. try
  97. {
  98. if(file.bad())
  99. throw runtime_error("could not open "+fileName+fileExtension+" for reading!\n");
  100. else
  101. {
  102. file.seekg(0, ios::end);
  103. endOfFile=file.tellg();//find out the position of the last charachter in file
  104. file.seekg(0, ios::beg);//set reading pointer back to start of file
  105. }
  106. }
  107. catch(runtime_error &ex)
  108. {
  109. cerr<<ex.what()<<endl;
  110. }
  111. lineNumber=1;
  112. while(getline(file, currentLine))
  113. { //This is where the error occurs
  114. system("PAUSE");
  115. //cout<<"I am reading line "<<lineNumber<<" which is "<<currentLine;
  116. currentPosition=file.tellg();
  117. if(currentPosition==endOfFile)
  118. {
  119. if(cFlag)
  120. cout<<numberOfMatches;
  121. numberOfMatches=0;
  122. lineNumber=1;
  123. cout<<endl;
  124. file.close();
  125. break;
  126. }
  127. else
  128. {
  129. cout<<"almost at match\n";
  130. if(regex_search(currentLine,expressionToMatch) || (!regex_search(currentLine, expressionToMatch) && vFlag))//The last condition says f there is no match and vFlag is true, execute this block of code. Since vFlag is print non-matching lines
  131. {
  132. cout<<"match\n";
  133. numberOfMatches++;
  134. if(!match && lFlag)//if no match has been made for this file, and lFlag active, which is to print file name
  135. {
  136. cout<<fileName<<endl;
  137. numberOfMatches=0;
  138. lineNumber=1;
  139. break;//We know already that the file contains a match so, we need to read no further so break
  140. }
  141. else
  142. {
  143. if(nFlag)//If the nFlag is true which means to print line number
  144. cout<<lineNumber<<". ";
  145. cout<<currentLine<<'\n';
  146. lineNumber++;
  147. }
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. else
  158. cout<<"That specified file could not be found"<<endl;
  159. }
  160. return 0;
  161. }
Compilation error #stdin compilation error #stdout 0s 0KB
stdin
Standard input is empty
compilation info
prog.cpp:9:102: fatal error: boost/filesystem.hpp: No such file or directory
 #include <boost/filesystem.hpp>//filesystem header file from boost library, cross platform compatible
                                                                                                      ^
compilation terminated.
stdout
Standard output is empty