Finding a string inside all subdirectories - c++

I try to code a program that behaves like grep -r function. So far I can list all the subdirectories and folders inside of them recursively but what i need to do is to find a string inside all of these files and record them in a .log file. I am building with CMake on Ubuntu. The program compiles fine but probably I have something wrong with this function.(it basically saves the values found in a log file)
It's supposed to put inside the log file the following->
Directory:(line number):(the full line)
After the changes, the function works fine, I can see the directories and the line number of the searched word. The problem now is that I cannot see the line in the .log file, it shows in binary and not as a string. Do anyone know the reason ?
void showing_all_files(std::string path, std::string search)
{
std::ofstream log_file;
log_file.open("grep_ex.log");
for (const auto & entry : fs::recursive_directory_iterator(path))
{
int line_no = 0;
string line;
ifstream infile(path);
while(getline(infile, line))
{
++line_no;
auto pos = line.find(search);
if(pos != string::npos)
{
log_file << entry << ":" << line_no << ":" << line << endl;
}
}
// log_file << entry.path() << std::endl;
}
log_file.close();
}

ifstream infile(path); Should be ifstream infile(entry.path());.

Related

Can't able to find a keyword in a File

When I try to Find a Keyword from the GetLine() Function It only Returns a Empty String. But when I try to print the Line with std::cout, it prints everything, so i debugged the solution I found that the String is empty but std::cout somehow manages to print the lines in file.
std::ifstream file(fileToSearch);
std::string line;
cout << endl << keyWords[i];
while (std::getline(file, line)) {
cout << endl << keyWords[i]<<" ";
cout << line;
if (auto pos = line.find(keyWords[i]) != std::string::npos) {
// std::stringstream iss(line.substr(pos + keyWords[i].size()));
cout << endl << "found again in String Table" << endl;
//iss >> j;
break;
}
}
This is the data in the File
%Checking Windows(R) Installer VersionConfiguring Windows InstallerConfiguring %sĀ½Setup has completed configuring the Windows Installer on your system. The system needs to be restarted in order to continue with the installation. Please click Restart to reboot the system.%s
When I checked the Encoding of the file in Notepad++. I found that the file is not encoded at all , but when I changed the file to UTF-8 I can get the Value and Search It Successfully. Is there anyway to do this by code rather than changing it Manually??

How to read file in c++ using environment variable

I want to read a file contents in C++ program which I have written inside a dll file. Right now I have hardcoded the path, but I want the path to be either dynamic or I should be able to use thru environment variable so I can either specify the path or the folder directly. I am using if stream in C++.Is there any way to do it
What I tried
if(const char* env_p = std::getenv("userdata"))
std::cout << "Your PATH is: " << env_p <<'\n';
std::vector<std::string> v;
string line;
//ifstream Myfile("C:\\Program Files\\Folder1\\users.txt"); working as its has hardcoded path
ifstream Myfile("users.txt");--- not working
ifstream Myfile(%userdata%);--- not working
while(!Myfile.eof())
{
while(getline(Myfile,line))
v.push_back(line);
cout <<endl;
cout <<"User in the file"<<endl;
for(auto i:v)
cout << i<<endl<<endl;
Myfile.close();
}

For Loop not reading ifstream

I'm trying to read multiple files in a folder so I can parse through their data.
I first try to fill the list using a text document with all the file names in it, then based on that vector of string, continuously call ifstream so I can read every file and process the word data.
The problem I'm running into is that ifstream is failing to open all of the files, except one in the middle of the list?
Heres the output, its failing to read the dbfiles but they all have the right names?
These files aren't more than 8GB a piece so it should be able to handle it but it's not?
maybe theres a problem with the file paths?
std::ifstream dbfiles(argv[1]);
if (!dbfiles)
{
std::cerr << "Failed to open database " << argv[1] << " for reading." << std::endl;
}
std::string word;
std::vector<std::string> dbfile_names;
std::string file_name;
while (getline(dbfiles, file_name))
{ //reading in the file names
dbfile_names.push_back(file_name);
}//populate list of dbs
dbfiles.close();
for (unsigned int j = 0; j < dbfile_names.size(); j++)
{ //for every single file
std::ifstream dbfile(dbfile_names[j].c_str());
if (!dbfile)
{
std::cout << "Failed to open database file" << dbfile_names[j] << " for reading. READ FAILURE" << std::endl;
}else{
std::cout << "currently reading " << dbfile_names[j] << std::endl;
}
while (dbfile >> word)
{
//do stuff with the segments of data
//here I gather the data word by word and process it
}
dbfile.close();
}
I went into my debugger and found that due to getline, all the file names had a /r at the back of them.
The post over here Getting std :: ifstream to handle LF, CR, and CRLF?, helped describe the problem and how to easily fix it.
My files are now reading accordingly

appending "../xx.txt" to the relative path does work in C++

I read some topics about relative path, but I've been wandering around them for hours without answer.
The code is like this:
std::string path = "./Debug/";
path.append("../hi.txt/");
std::ifstream inFile(path);
std::string str;
if (inFile.is_open())
{
inFile >> str;
std::cout << str << std::endl;
}
else
{
std::cout << "open failed" << std::endl;
}
This code will output:"open failed".
Any help would be appreciated.
When you put a / at the end of a path, it tells the system to execute it as a directory (i.e. list its contents). Since hi.txt is not a directory, you can't execute it as a directory and therefore it fails (assuming of course you didn't name a directory hi.txt).
To fix it: remove the /:
std::string path = "./Debug/" ;
path.append("../hi.txt") ;

Whats the best way to get text from a .txt file to a vector<string>? C++

I asked a question yesterday but i didn't manage to do anything. I am using visual studio with marmalade and im already studying c++ but i need to get things done here so i asking for i little help and patience of you guys.
I got a few responses like
std::ifstream inp("restrict_words.txt");
std::istream_iterator<std::string> inp_it(inp), inp_eof;
std::vector<std::string> words(inp_it, inp_eof);
// words now has ever whitespace separated string
// from the input file as a vector entry
for (auto s : words)
std::cout << s << '\n';
and
std::ifstream ist("restrict_words.txt");
std::string word;
std::vector<std::string> readWords;
while(ist >> word)
readWords.push_back(word);
//test
for(unsigned i = 0; i != readWords.size(); ++i)
std::cout << readWords.at(i) << '\n';
Its such a easy thing and im not managing to do this.
I have my KingChatFilter.app and a chat folder inside my game folder. Inside this chat folder i have this txt with 160 words in 160 different lines.
All i need to do is read this txt and after putting it on a array checking if some of this string match with the one i want so i can do other stuff.
Please someone make me understand this thanks :)
I wrote a couple of functions to match your requirements:
#include <iostream>
#include <vector>
#include <algorithm>
#include <fstream>
using namespace std;
// Reads the file line by line and put all lines into words vector.
void read_to_vector(const char* file_name, vector<string> &words)
{
ifstream input(file_name);
string line;
while (getline(input, line))
{
words.push_back(line);
}
}
// Returns true if word is in words. False otherwise.
bool find_word(vector<string> &words, string word)
{
vector<string>::iterator it; // In c++11 you can change this to
// auto it;
// Using std::find from algorithm library.
it = find(words.begin(), words.end(), word);
return it != words.end(); // If the end of vector words was reached, then word was NOT found.
}
int main()
{
vector<string> words;
string target = "level";
read_to_vector("data.txt", words);
if (find_word(words, target))
cout << "Word " << target << " found" << endl;
else
cout << "Word " << target << " not found" << endl;
return 0;
}
following is working code i used to read file content line by line. One difference is maybe that u do not check if opening the file did succeed. If it does not, there come at least two main reasons to mind:
the file cannot be found at the specified path
the file is already opened by someone else
;
std::string fileNameWithPath = "..\\myFolder\\myfile.txt";
std::ifstream inputFile;
std::vector< std::string > fileContent;
inputFile.open( fileNameWithPath.c_str(), std::ios::in | std::ios::binary );
if( inputFile.is_open() )
{
std::string line;
while( std::getline( testDataFile, line ) )
{
inputFile.push_back( line );
}
}
inputFile.close();