I'm new in c++. I'm trying to list files in dir. I'm using unicode. The problem is not listing files but treat string and paths with wchar*, I'm going mad. Here's my test code:
#define UNICODE 1
#include <stdio.h>
#include <windows.h>
#include <wchar.h>
int wmain(int argc,wchar_t **argv){
if (argc > 1){
wchar_t* path=argv[1];
wchar_t* pwc;
int last_occurence;
pwc=wcsrchr(path,L'\\');
last_occurence = pwc-path+1;
int len = wcslen(path);
if (last_occurence == len){
//slash
}else{
//no slash
wcscat(path,L"\\");
}
wcscat(path,L"*");
WIN32_FIND_DATA FindData;
HANDLE hSearch;
hSearch = FindFirstFile(path , &FindData);
if(hSearch == INVALID_HANDLE_VALUE){
return -1;
}else{
// *** PROBLEM STARTS HERE
wchar_t* filePath=NULL;
do{
wcscpy(filePath,path);
wcscat(filePath,FindData.cFileName);
wprintf(L"Path %s\n",filePath);
memset(filePath, '\0', wcslen(filePath));
// *** PROBLEM ENDS HERE
}while( FindNextFile(hSearch, &FindData) > 0 );
int ret = FindClose(hSearch);
return 0;
}
}
}
When I run the compiled app, it stops responding. What I would like to do is print the path I pass to my app (c:\dir1\dir2) and append the files in it (file1,file2) as follows:
c:\dir1\dir2\file1
c:\dir1\dir2\file2
How to solve this problem? There are best methods to do something like this? I would remain with wchar not std string if possible
There are a few issues with your code.
you are concatenating "\\*" to the memory that argv[1] points to, which is bad. You need to change path from a wchar_t* pointer to an wchar_t[] array, and then wcscpy the argv[1] data into it.
you are not allocating any memory for filePath, so wcscpy() and wcscat() are writing to invalid memory. You need to change filePath to a wchar_t[] array as well, and then wcscpy/wcscat the path data into it.
you are also not ignoring the concatenated * when combining the path and cFileNames values together.
you don't need the memset() at all (especially since you are giving it the wrong byte count anyway).
Try something more like this instead:
#define UNICODE 1
#include <stdio.h>
#include <windows.h>
#include <wchar.h>
int wmain(int argc, wchar_t **argv)
{
if (argc < 2)
{
wprintf(L"Usage: \"%s\" path\n", argv[0]);
return -1;
}
int len = wcslen(argv[1]);
if (len >= MAX_PATH)
{
wprintf(L"Path is too long\n");
return -1;
}
wchar_t path[MAX_PATH+1] = {};
wcscpy(path, argv[1]);
if ((len > 0) && (path[len-1] != L'\\'))
wcscat(path, L"\\");
wchar_t searchMask[MAX_PATH+2] = {};
wcscpy(searchMask, path);
wcscat(searchMask, L"*");
WIN32_FIND_DATA FindData;
HANDLE hSearch = FindFirstFileW(searchMask, &FindData);
if (hSearch == INVALID_HANDLE_VALUE)
{
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
wprintf(L"Error looking for first file\n");
return -1;
}
wprintf(L"No files found\n");
}
else
{
wchar_t filePath[MAX_PATH*2];
do
{
wcscpy(filePath, path);
wcscat(filePath, FindData.cFileName);
wprintf(L"Path %s\n", filePath);
}
while (FindNextFileW(hSearch, &FindData));
if (GetLastError() != ERROR_NO_MORE_FILES)
{
FindClose(hSearch);
wprintf(L"Error looking for next file\n");
return -1;
}
FindClose(hSearch);
}
return 0;
}
Though, you really should be using the std::unique_ptr and std::wstring classes and let them manage memory/resources for you. Using C library functions is not helping you learn C++:
#define UNICODE 1
#include <windows.h>
#include <wchar.h>
#include <iostream>
#include <string>
#include <memory>
struct FindDeleter
{
typedef HANDLE pointer;
void operator()(HANDLE h)
{
if(h != INVALID_HANDLE_VALUE)
FindClose(h);
}
};
int wmain(int argc, wchar_t **argv)
{
if (argc < 2)
{
std::wcerr << L"Usage: \"" << argv[0] << L"\" path" << std::endl;
return -1;
}
std::wstring path = argv[1];
if ((!path.empty()) && (path[path.length()-1] != L'\\'))
path += L'\\';
WIN32_FIND_DATA FindData;
std::unique_ptr<HANDLE, FindDeleter> hSearch(FindFirstFileW((path + L"*").c_str(), &FindData));
if (hSearch.get() == INVALID_HANDLE_VALUE)
{
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
std::wcerr << L"Error looking for first file" << std::endl;
return -1;
}
std::wcout << L"No files found" << std::endl;
}
else
{
do
{
std::wstring filePath = path + FindData.cFileName;
std::wcout << L"Path " << filePath << std::endl;
}
while (FindNextFileW(hSearch.get(), &FindData));
if (GetLastError() != ERROR_NO_MORE_FILES)
{
std::wcerr << L"Error looking for next file" << std::endl;
return -1;
}
}
return 0;
}
Or, if you are not using a C++11 compiler:
#define UNICODE 1
#include <windows.h>
#include <wchar.h>
#include <iostream>
#include <string>
class FindHandle
{
private:
HANDLE m_hFind;
public:
FindHandle(HANDLE hFind) : m_hFind(hFind) {}
~FindHandle()
{
if (m_hFind != INVALID_HANDLE_VALUE)
FindClose(m_hFind);
}
HANDLE get() { return m_hFind; }
};
int wmain(int argc, wchar_t **argv)
{
if (argc < 2)
{
std::wcerr << L"Usage: \"" << argv[0] << L"\" path" << std::endl;
return -1;
}
std::wstring path = argv[1];
if ((!path.empty()) && (path[path.length()-1] != L'\\'))
path += L'\\';
WIN32_FIND_DATA FindData;
FindHandle hSearch(FindFirstFileW((path + L"*").c_str(), &FindData));
if (hSearch.get() == INVALID_HANDLE_VALUE)
{
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
std::wcerr << L"Error looking for first file" << std::endl;
return -1;
}
std::wcout << L"No files found" << std::endl;
}
else
{
do
{
std::wstring filePath = path + FindData.cFileName;
std::wcout << L"Path " << filePath << std::endl;
}
while (FindNextFileW(hSearch.get(), &FindData));
if (GetLastError() != ERROR_NO_MORE_FILES)
{
std::wcerr << L"Error looking for next file" << std::endl;
return -1;
}
}
return 0;
}
Related
I haven't been able to find anything else about this online at all. I have a simple authenticator program, with a .dll injector written into it. If the key matches the one in the database, it will run the injector, and constantly check to make sure that the key is still active. For some reason, my console window outputs "tick" about every second. When the injector is taken out, and it is just the authenticator it will not do this.
#include <iostream>
#include <string>
#include <Windows.h>
#include <thread>
#include <WinInet.h>
#include <TlHelp32.h>
#include <fcntl.h>
#include <io.h>
#include <fcntl.h>
#include <cstdio>
#include <chrono>
#include "include/c0gnito.h"
std::string Key;
std::string hwid = GetHardwareID(); //Gets the hwid
char* StringToChar(std::string string) //A function to convert a string to a char
{
return _strdup(string.c_str());
}
template <class T>
void msg(T msg)
{
std::cout << msg << std::endl;
}
bool FileExists(const std::string& fileName)
{
struct stat buffer;
return (stat(fileName.c_str(), &buffer) == 0);
}
void WriteStringToIni(std::string string, std::string file, std::string app, std::string key)
{
WritePrivateProfileStringA(app.c_str(), key.c_str(), string.c_str(), file.c_str());
}
std::string ReadStringFromIni(std::string file, std::string app, std::string key)
{
char buf[100];
GetPrivateProfileStringA(app.c_str(), key.c_str(), "NULL", buf, 100, file.c_str());
return (std::string)buf;
}
LONG address = 0x0;
BYTE newvalue[] = { 0x0 };
HWND hwnd;
HANDLE phandle;
DWORD pid;
DWORD GetProcId(const char* procName)
{
DWORD procId = 0;
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 procEntry;
procEntry.dwSize = sizeof(procEntry);
if (Process32First(hSnap, &procEntry))
{
do
{
if (!_stricmp(procEntry.szExeFile, procName))
{
procId = procEntry.th32ProcessID;
break;
}
} while (Process32Next(hSnap, &procEntry));
}
}
CloseHandle(hSnap);
return procId;
}
const char* dllPath = "C:\\Windows\\System32\\sysproc.dll";
const char* procName = "Project1.exe";
DWORD procId = 0;
int main() //Entry point
{
system("color b"); //Sets the color to blue
Initialize("B2wVksYPzgCBOtNq8SFQ05GCuKrzwNIRytotMczYWCSv59sypLJhPEnLY9w8cmml"); //Connects to the authentication server
if (FileExists("./Config.ini"))
{
Key = ReadStringFromIni("./Config.ini", "License", "Key"); //Gets the key saved in the file
}
else
{
std::cout << "Welcome, please enter your license key: ";
std::cin >> Key; //Gets the user's key
if (Authenticate(StringToChar(Key), (StringToChar(hwid)))) {}// Authenticates key & hwid
else
{
std::cout << "Invalid Key!" << std::endl;
exit(2000);
}
WriteStringToIni(Key, "./Config.ini", "License", "Key"); //Creates a file that stores the key entered
}
if (Authenticate(StringToChar(Key), (StringToChar(hwid)))) // Authenticates key & hwid
{
std::cout << "Sucessfully Authenticated!" << std::endl;
Sleep(2000);
while (!procId)
{
procId = GetProcId(procName);
Sleep(30);
}
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, 0, procId);
if (hProc && hProc != INVALID_HANDLE_VALUE)
{
void* loc = VirtualAllocEx(hProc, 0, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProc, loc, dllPath, strlen(dllPath) + 1, 0);
HANDLE hThread = CreateRemoteThread(hProc, 0, 0, (LPTHREAD_START_ROUTINE)LoadLibraryA, loc, 0, 0);
if (hThread)
{
CloseHandle(hThread);
}
}
if (hProc)
{
CloseHandle(hProc);
}
}
else
{
exit(0);
}
system("cls");
std::cout << "Hardware ID: " << hwid << std::endl;
std::cout << "_______________________________________________________" << std::endl;
std::cout << " " << std::endl;
std::thread auth([&]() //Authentication Thread that keep on checking the connection and user previleges
{
while (true)
{
std::cout << "Auth is checking..." << std::endl;
if (!Authenticate(StringToChar(Key), (StringToChar(hwid))))
{
exit(0);
}
std::cout << "Sucessfully Authenticated!" << std::endl;
Sleep(60000);
}
});
std::cin.get();
}
How can i get current file name without path, i want to use it on WinExec,
example for what am trying to do,
WinExec("Do something to <mycurrentfilename.exe>", SW_HIDE);
In common case you have to use GetModuleFileName function.
Example:
#include <Windows.h>
#include <sstream>
int main(void) {
char myexepath[MAX_PATH] = { 0 };
DWORD returnCode = GetModuleFileNameA(NULL, myexepath, MAX_PATH);
if (returnCode != 0 && returnCode < MAX_PATH)
{
std::string filepath(myexepath);
filepath = filepath.substr(filepath.find_last_of('\\') + 1);
std::ostringstream ss;
ss << "Do something to \"" << filepath << "\"";
WinExec(ss.str().c_str(), SW_HIDE);
}
else
{
// process GetModuleFileName error.
}
return 0;
}
Example uses char encoding for filename, but it can be changed to wchar_t or universal TCHAR
I am trying to search the registry's uninstall folder for a given program that I know is there by checking regedit. My function currently finds the program, but for some reason it doesn't update the output value from the RegGetValue function until the next iteration. So it prints the correct registry key and its predecessor. Any ideas?
I am on a Windows 10 64bit workstation with Intel processors using Visual Studio 2015 if that matters.
main.cpp
#include "Registry.h"
#include <Windows.h>
#include <tchar.h>
void main()
{
Registry test(_T("Microsoft SQL Server 2012 Native Client "));
}
Registry.h
#pragma once
#include <Windows.h>
#include <string>
#define REG_PATH L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
#define X86REG_PATH L"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
class Registry
{
public:
Registry(TCHAR* name);
~Registry();
TCHAR* findGUID();
TCHAR* getDisplayName();
TCHAR* getGUID();
TCHAR* getVersion();
TCHAR* getPublisher();
TCHAR* getInstallDate();
private:
TCHAR* displayName;
TCHAR* guid;
TCHAR* version;
TCHAR* publisher;
TCHAR* installDate;
};
Registry.cpp
#pragma once
#include "Registry.h"
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <fstream>
Registry::Registry(TCHAR* name)
{
HKEY hKey;
LPCTSTR lpSubKey;
DWORD ulOptions;
REGSAM samDesired;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
std::wofstream file;
file.open("test.txt");
int index = 0;
HKEY UninstallDir = hKey;
TCHAR subKey[MAX_PATH];
DWORD subKeySize = MAX_PATH;
while (RegEnumKeyEx(hKey, index, subKey, &subKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
HKEY guid;
TCHAR* guidPath = new TCHAR[MAX_PATH];
_tcscpy_s(guidPath, MAX_PATH, REG_PATH);
_tcscat_s(guidPath, MAX_PATH, subKey);
TCHAR compareName[MAX_PATH];
DWORD nameSize;
//print all registry keys to file
file << index << ": " << guidPath << std::endl;
int test;
RegGetValue(HKEY_LOCAL_MACHINE, guidPath, _T("DisplayName"), RRF_RT_ANY, NULL, &compareName, &nameSize);
//compare all registry keys *temporary to debug
if (_tcscmp(guidPath, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\{49D665A2-4C2A-476E-9AB8-FCC425F526FC}")) == 0)
{
std::wcout << guidPath << " found" << std::endl;
}
if (_tcscmp(compareName, name) == 0)
{
_tprintf(_T("%d: %s\n"), index, guidPath);
}
//print if found
index++;
subKeySize = 260;
}
file.close();
}
else
{
std::cout << "Could not open registry key." << std::endl;
}
//temporary to see console
std::cin.get();
}
//still need to be completed
Registry::~Registry()
{
}
TCHAR* Registry::findGUID()
{
return _T("");
}
TCHAR* Registry::getDisplayName()
{
return _T("");
}
TCHAR* Registry::getGUID()
{
return _T("");
}
TCHAR* Registry::getVersion()
{
return _T("");
}
TCHAR* Registry::getPublisher()
{
return _T("");
}
TCHAR* Registry::getInstallDate()
{
return _T("");
}
I see a lot of problems with your code.
You are mixing std::wcout and _tprintf(), which causes buffering conflicts.
You are mixing char and wchar_t data incorrectly.
You are leaking guidPath on every loop iteration.
You are not initializing nameSize when calling RegGetValue().
You are not setting up your code to access the 32bit Wow64Node key correctly.
Try something more like this instead.
main.cpp
#include <Windows.h>
#include "Registry.h"
void main()
{
Registry test(L"Microsoft SQL Server 2012 Native Client");
}
Registry.h
#pragma once
#include <Windows.h>
#include <string>
class Registry
{
public:
Registry(const std::wstring &name);
~Registry();
std::wstring findGUID();
std::wstring getDisplayName();
std::wstring getGUID();
std::wstring getVersion();
std::wstring getPublisher();
std::wstring getInstallDate();
private:
std::wstring displayName;
std::wstring guid;
std::wstring version;
std::wstring publisher;
std::wstring installDate;
};
Registry.cpp
#pragma once
#include <Windows.h>
#include "Registry.h"
#include <iostream>
#include <fstream>
#define REG_PATH L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"
Registry::Registry(const std::wstring &name)
{
HKEY hKey;
// If you want to open the 32bit Wow64Node key,
// DO NOT open the key directly! Open the 64bit
// key and include the KEY_WOW64_32KEY flag
// so it will redirect to the Wow64Node key...
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, REG_PATH, NULL, KEY_READ, &hKey) == ERROR_SUCCESS)
{
std::wofstream file;
file.open(L"test.txt");
WCHAR subKey[MAX_PATH];
DWORD subKeySize = MAX_PATH;
WCHAR compareName[MAX_PATH];
DWORD nameSize;
int index = 0;
while (RegEnumKeyEx(hKey, index, subKey, &subKeySize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
// print all registry keys to file
file << index << L": " << REG_PATH << subKey << std::endl;
int test;
nameSize = sizeof(compareName);
RegGetValue(hKey, NULL, L"DisplayName", RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ | RRF_ZEROONFAILURE, NULL, compareName, &nameSize);
//compare all registry keys *temporary to debug
if (wcscmp(subKey, L"{49D665A2-4C2A-476E-9AB8-FCC425F526FC}") == 0)
{
std::wcout << subKey << L" found" << std::endl;
}
if (name == compareName)
{
std::wcout << name << L" found" << std::endl;
}
//print if found
index++;
subKeySize = MAX_PATH;
}
file.close();
}
else
{
std::wcout << L"Could not open registry key." << std::endl;
}
//temporary to see console
std::wcin.get();
}
//still need to be completed
Registry::~Registry()
{
}
std::wstring Registry::findGUID()
{
return L"";
}
std::wstring Registry::getDisplayName()
{
return L"";
}
std::wstring Registry::getGUID()
{
return L"";
}
std::wstring Registry::getVersion()
{
return L"";
}
std::wstring Registry::getPublisher()
{
return L"";
}
std::wstring Registry::getInstallDate()
{
return L"";
}
I am trying to store the name of all txt files in a directory in a string and print them out. I need to count the number of txt files in the directory and then print the names. The part of counting is working, but I can't seem to get the name working. I have found some examples but they don't work in visual studio which is what I'm using.
Here is my code.
int main() {
bool x = true;
int i = 0;
wchar_t* file = L"../Menu/Circuitos/*.txt";
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
hFind = FindFirstFile(file, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE) {
i++;
while ((x = FindNextFile(hFind, &FindFileData)) == TRUE) {
i++;
}
}
cout << "number of files " << i << endl;
return 0;
}
FindFirstFile already has the first valid handle. If you immediately call FindNextFile then the first handle is lost. The file count in your example would be wrong.
Use do-while loop istead.
Also, the handle obtained from FindFirstFile must be closed with FindClose
HANDLE hFind;
hFind = FindFirstFile(file, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
do {
wcout << FindFileData.cFileName << "\n";
i++;
} while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
cout << "number of files " << i << endl;
Use std::vector and std::wstring to store the items
#include <string>
#include <vector>
...
std::vector<std::wstring> vs;
HANDLE hFind;
hFind = FindFirstFile(file, &FindFileData);
if (hFind != INVALID_HANDLE_VALUE)
{
do {
vs.push_back(FindFileData.cFileName);
} while (FindNextFile(hFind, &FindFileData));
FindClose(hFind);
}
std::cout << "count:" << vs.size() << "\n";
for (auto item : vs)
std::wcout << item << "\n";
For some older compilers auto may not be available, use this instead
for (int i = 0; i < vs.size(); i++)
std::wcout << vs[i] << "\n";
Note, Windows API works with c-strings. In many cases you have to use .c_str() to obtain character array. For example:
if (vs.size())
{
std::wstring str = vs[0];
MessageBox(0, str.c_str(), 0, 0);
}
Here is a portable version using the new ISO Standard Filesystem Library TS (technical specification) for those with compilers that support it:
#include <vector>
#include <iostream>
#include <algorithm>
#include <experimental/filesystem>
// for readability
namespace fs = std::experimental::filesystem;
/**
* Function object to test directory entries
* for a specific file extension.
*/
struct file_extension_is
{
std::string ext;
file_extension_is(std::string const& ext): ext(ext) {}
bool operator()(fs::directory_entry const& entry) const
{
return entry.path().extension() == ext;
}
};
int main(int, char* argv[])
{
try
{
// directory supplied on the command line if present
// else current directory
fs::path dir = argv[1] ? argv[1] : ".";
// place to store the results
std::vector<fs::directory_entry> entries;
// copy directory entries that have file extension ".txt"
// to the results
fs::directory_iterator di(dir);
fs::directory_iterator end;
std::copy_if(di, end, std::back_inserter(entries),
file_extension_is(".txt"));
// print it all out
std::cout << "Number of files: " << entries.size() << '\n';
for(auto const& entry: entries)
std::cout << entry.path().string() << '\n';
}
catch(std::exception const& e)
{
std::cerr << e.what() << '\n';
}
catch(...)
{
std::cerr << "Unknown exception." << '\n';
}
}
I am an absolute newbie to C++ and have only started to program with it 3 days ago.
I am trying to do the folliwng:
traverse a directory for X.X files (typically .), and for each file, do the following:
Search within the file for a string (findFirst) and then search until another string (findLast) - The files will be HTML format.
In this selection, I want to perform several tasks (yet to write) - but they will be the following:
One of the strings will be the Filename I want to write to. - so extract this field and create an outputfile with this name
Some of the lines will be manufacturer part numbers - extract these and format the output file accordingly
most of it will be description of product. Again - this will be in an HTML construct - so extract this and format the output file.
So far, I have managed to get working the traverse directory, and selecting the start and finish keywords - using some help from the internet.
My problem is here
processFiles(inputFileName, "testing", "finish");
I need the inputFileName to be the name of the traversed filename.
All the examples I have found simply print the filename using cout
I need to pass this into the processFiles function.
Can someone tell me what i need to use? i have tried it->c_Str() and other variations of (*it) and .at, .begin etc
my non printing example is below:
// Chomp.cpp : Defines the entry point for the console application.
//
#include <stdafx.h>
#include <windows.h>
#include <string>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <cctype>
#include <algorithm>
#include <vector>
#include <stack>
//std::ifstream inFile ( "c:/temp/input.txt" ) ;
std::ofstream outFile( "c:/temp/output.txt") ;
using namespace std;
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void openFiles()
{
if (!(outFile.is_open()))
{
printf ("Could not Create Output file\n");
exit(0);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
bool ListFiles(wstring path, wstring mask, vector<wstring>& files)
{
HANDLE hFind = INVALID_HANDLE_VALUE;
WIN32_FIND_DATA ffd;
wstring spec;
stack<wstring> directories;
directories.push(path);
files.clear();
while (!directories.empty())
{
path = directories.top();
spec = path + L"\\" + mask;
directories.pop();
hFind = FindFirstFile(spec.c_str(), &ffd);
if (hFind == INVALID_HANDLE_VALUE)
return false;
do
{
if (wcscmp(ffd.cFileName, L".") != 0 && wcscmp(ffd.cFileName, L"..") != 0)
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
directories.push(path + L"\\" + ffd.cFileName);
else
files.push_back(path + L"\\" + ffd.cFileName);
}
} while (FindNextFile(hFind, &ffd) != 0);
if (GetLastError() != ERROR_NO_MORE_FILES)
{
FindClose(hFind);
return false;
}
FindClose(hFind);
hFind = INVALID_HANDLE_VALUE;
}
return true;
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
void processFiles(const wchar_t *inFileName, std::string findFirst,std::string findLast )
{
/*
std::string findFirst = "testing" ;
std::string findLast = "finish" ;
*/
std::string inputLine ;
int lineNum = 0 ;
char buffer[2048];
size_t found = 0;
std::ifstream inFile;
inFile.open (inFileName); // Open The file
if (inFile.is_open())
{
while( std::getline( inFile, inputLine ))
{
++lineNum ;
// printf ("Line len = %d\n ", inputLine.length());
if( (found = inputLine.find(findFirst)) != std::string::npos )
{
std::cout << "###Line " << lineNum << " At Position [ " << found << " ]\n" ;
sprintf_s(buffer, 2048, "[%-5.5d] %s\n", lineNum, inputLine.c_str());
outFile << buffer ;
bool foundLast = 0;
while( std::getline( inFile, inputLine ))
{
++lineNum ;
sprintf_s(buffer, 2048, "[%-5.5d] %s\n", lineNum, inputLine.c_str());
if( (found = inputLine.find(findLast)) != std::string::npos )
{
outFile << buffer ;
break; // Found last string - so stop after printing last line
}
else
outFile << buffer ;
}
}
else
{
// std::cout << "=>" << inputLine << '\n' ;
}
}
}
else
{
printf ("Cant open file \n");
exit(0);
}
inFile.close() ; // Close The file
}
/////////////////////////////////////////////////////////////////////////////////////////////
/// M A I N
/////////////////////////////////////////////////////////////////////////////////////////////
int main()
{
std::ifstream inFile ;
int startLine = 0;
int endLine = 0;
int lineSize = 0;
char buffer[512];
vector<wstring> files; // For Parsing Directory structure
openFiles();
// Start The Recursive parsing of Directory Structure
if (ListFiles(L"C:\\temp", L"*.*", files))
{
for (vector<wstring>::iterator it = files.begin(); it != files.end(); ++it)
{
printf ("Filename1 is %s\n", it->c_str());
printf ("Filename2 is %s\n", files.begin());
outFile << "\n------------------------------\n";
//outFile << it << endl;
wcout << it->c_str() << endl;
outFile << "\n------------------------------\n";
const wchar_t *inputFileName = it->c_str();
// processFiles(inputFileName, "testing", "finish");
// getchar();
}
}
outFile.close();
getchar();
}
Make your processFile accept a wstring, viz:
void processFiles(wstring inFileName, std::string findFirst,std::string findLast )
{
// Make the necessary changes so that you use a wstring for inFileName
}
Call it from main() using:
processFiles(*it, "testing", "finish");
You need to change processFile to use a wifstream instead of a ifstream and you should change all of your narrow strings to use wide strings (or vice versa). Narrow strings and wide strings are not compatible with each other and in order to use one with the other a conversion function must be used such as mbstowcs.
Edit:
You can find an example that should compile here.