Copy files out of different folders to a specific on in C++ - c++

My problem is that i have several folders with the names "MORE0001" "MORE0002" etc and they contain one .SPE-file each.
I want to know if there is a way to extract all the .SPE-files to ONE folder by iterating through all the single-MORE...-folders.
I need sth. like this:
for (int i=0; i<10;i++){
newfile = getfile("directory/MORE%04d/filename.SPE", i);
// copy newfile to a new directory..
}
I hope you guys can help me find an easy solution, because i didn´t find a similar problem yet.

it´s just TOO easy..
i can just use the rename-function..
so it would be like:
rename(path/filename.SPE, newpath/filename.SPE);
thanks, but solved it myself ;)!

I have created one sample program, which might helps to resolve your problem.
#include<Windows.h>
#include<regex>
using namespace std;
void main()
{
regex e1("MORE\\d+");
string szDir = "C:\\*";
WIN32_FIND_DATA ffd;
HANDLE hFind = FindFirstFileA(szDir.c_str(), &ffd);
do
{
if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
if (regex_match(ffd.cFileName,e1 ))
{
string s1 = ffd.cFileName;
string s2 = "C:\\" + s1 + "\\*";
WIN32_FIND_DATA ffdMORE;
HANDLE hFindMORE = FindFirstFile(s2.c_str(), &ffdMORE);
do
{
regex e2("\\w+.SPE");
if (regex_match(ffdMORE.cFileName,e2))
{
string commondir = "C:\\CommonDir\\";
string sourcePath = "C:\\" + s1 + "\\";
CopyFile(sourcePath.append(ffdMORE.cFileName).c_str(), commondir.append(ffdMORE.cFileName).c_str(), FALSE);
}
} while (FindNextFile(hFindMORE, & ffdMORE) != 0);
}
}
} while (FindNextFile(hFind, &ffd) != 0);
}
Thanks,
Bharathraj

Related

Get string of temp file and add custom folder

I'm new to C++ and I have been thinking how to get string of the user's temp folder on Windows and append to it a custom folder name.
e.g "\Users\user\AppData\Local\Temp\NameOfCustomFolder"
I've tried this:
std::string szOutput{};
TCHAR path_buf[MAX_PATH];
DWORD ret_val = GetTempPath(MAX_PATH, path_buf);
if (ret_val > MAX_PATH || (ret_val == 0))
{
std::cout << "GetTempPath failed";
}
else
{
szOutput = path_buf, "NameOfCustomFolder\\file.exe"
}
return szOutput;
This does not perform the string concatenation you want
szOutput = path_buf, "NameOfCustomFolder\\file.exe";
Rather do
szOutput = std::string{path_buf} + "NameOfCustomFolder\\file.exe";
If you can use C++17, I would suggest std::filesystem::path::append
It will take care of the path separators, and will make it easy to go cross-platform.

count the number of directories in a folder C++ windows

I have written a Java program that at one point counts the number of folders in a directory. I would like to translate this program into C++ (I'm trying to learn it). I've been able to translate most of the program, but I haven't been able to find a way to count the subdirectories of a directory. How would I accomplish this?
Thanks in advance
Here is an implementation using the Win32 API.
SubdirCount takes a directory path string argument and it returns a count of its immediate child subdirectories (as an int). Hidden subdirectories are included, but any named "." or ".." are not counted.
FindFirstFile is a TCHAR-taking alias which ends up as either FindFirstFileA or FindFirstFileW. In order to keep strings TCHAR, without assuming availabilty of CString, the example here includes some awkward code just for appending "/*" to the function's argument.
#include <tchar.h>
#include <windows.h>
int SubdirCount(const TCHAR* parent_path) {
// The hideous string manipulation code below
// prepares a TCHAR wildcard string (sub_wild)
// matching any subdirectory immediately under
// parent_path by appending "\*"
size_t len = _tcslen(parent_path);
const size_t alloc_len = len + 3;
TCHAR* sub_wild = new TCHAR[alloc_len];
_tcscpy_s(sub_wild, alloc_len, parent_path);
if(len && sub_wild[len-1] != _T('\\')) { sub_wild[len++] = _T('\\'); }
sub_wild[len++] = _T('*');
sub_wild[len++] = _T('\0');
// File enumeration starts here
WIN32_FIND_DATA fd;
HANDLE hfind;
int count = 0;
if(INVALID_HANDLE_VALUE != (hfind = FindFirstFile(sub_wild, &fd))) {
do {
if(fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
// is_alias_dir is true if directory name is "." or ".."
const bool is_alias_dir = fd.cFileName[0] == _T('.') &&
(!fd.cFileName[1] || (fd.cFileName[1] == _T('.') &&
!fd.cFileName[2]));
count += !is_alias_dir;
}
} while(FindNextFile(hfind, &fd));
FindClose(hfind);
}
delete [] sub_wild;
return count;
}

C++ equivalent of MATLAB's "fileparts" function

In MATLAB there's a nice function called fileparts that takes a full file path and parses it into path, filename (without extension), and extension as in the following example from the documentation:
file = 'H:\user4\matlab\classpath.txt';
[pathstr, name, ext] = fileparts(file)
>> pathstr = H:\user4\matlab
>> name = classpath
>> ext = .txt
So I was wondering if there's an equivalent function in any standard C++ or C libraries that I could use? Or would I have to implement this myself? I realize it's fairly simple, but I figured if there's already something pre-made that would be preferable.
Thanks.
The boost library has a file system component "basic_path" that allows you use iterators to discover each component in the filename. Such a component would be OS specific, and I believe you need to compile boost separately for Windows, Linux etc.
I just wrote this simple function. It behaves similar as Matlab's fileparts and works independent of platform.
struct FileParts
{
string path;
string name;
string ext;
};
FileParts fileparts(string filename)
{
int idx0 = filename.rfind("/");
int idx1 = filename.rfind(".");
FileParts fp;
fp.path = filename.substr(0,idx0+1);
fp.name = filename.substr(idx0+1,idx1-idx0-1);
fp.ext = filename.substr(idx1);
return fp;
}
A platform-independent way with C++11/14.
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
void fileparts(string full, string& fpath, string& fname, string& fext)
{
auto source = fs::path(full);
fpath = source.parent_path().string();
fname = source.stem().string();
fext = source.extension().string();
}
...
string fpath, fname, fext;
fileparts(full_file_path,fpath,fname,fext);
Some possible solutions, depending on your OS:
Visual C++ _splitpath function
Win32 Shell Path Handling Functions such as PathFindExtension, PathFindFileName, PathStripPath, PathRemoveExtension, PathRemoveFileSpec
Ekalic's text-only approach is useful, but it didn't check for errors. Here's one that does, and also works with both / and \
struct FileParts
{
std::string path; //!< containing folder, if provided, including trailing slash
std::string name; //!< base file name, without extension
std::string ext; //!< extension, including '.'
};
//! Using only text manipulation, splits a full path into component file parts
FileParts fileparts(const std::string &fullpath)
{
using namespace std;
size_t idxSlash = fullpath.rfind("/");
if (idxSlash == string::npos) {
idxSlash = fullpath.rfind("\\");
}
size_t idxDot = fullpath.rfind(".");
FileParts fp;
if (idxSlash != string::npos && idxDot != string::npos) {
fp.path = fullpath.substr(0, idxSlash + 1);
fp.name = fullpath.substr(idxSlash + 1, idxDot - idxSlash - 1);
fp.ext = fullpath.substr(idxDot);
} else if (idxSlash == string::npos && idxDot == string::npos) {
fp.name = fullpath;
} else if (/* only */ idxSlash == string::npos) {
fp.name = fullpath.substr(0, idxDot);
fp.ext = fullpath.substr(idxDot);
} else { // only idxDot == string::npos
fp.path = fullpath.substr(0, idxSlash + 1);
fp.name = fullpath.substr(idxSlash + 1);
}
return fp;
}

Save all file names in a directory to a vector

I need to save all ".xml" file names in a directory to a vector. To make a long story short, I cannot use the dirent API. It seems as if C++ does not have any concept of "directories".
Once I have the filenames in a vector, I can iterate through and "fopen" these files.
Is there an easy way to get these filenames at runtime?
Easy way is to use Boost.Filesystem library.
namespace fs = boost::filesystem;
// ...
std::string path_to_xml = CUSTOM_DIR_PATH;
std::vector<string> xml_files;
fs::directory_iterator dir_iter( static_cast<fs::path>(path_to_xml) ), dir_end;
for (; dir_iter != dir_end; ++dir_iter ) {
if ( boost::iends_with( boost::to_lower_copy( dir_iter->filename() ), ".xml" ) )
xml_files.push_back( dir_iter->filename() );
}
I suggest having a look at boost::filesystem if it should be portable and bringing boost in isn't too heavy.
If you don't like boost, try Poco. It has a DirectoryIterator. http://pocoproject.org/
Something like this (Note, Format is a sprintf:ish funciton you can replace)
bool MakeFileList(const wchar_t* pDirectory,vector<wstring> *pFileList)
{
wstring sTemp = Format(L"%s\\*.%s",pDirectory,L"xml");
_wfinddata_t first_file;
long hFile = _wfindfirst(sTemp.c_str(),&first_file);
if(hFile != -1)
{
wstring sFile = first_file.name;
wstring sPath = Format(L"%s%s",pDirectory,sFile.c_str());
pFileList->push_back(sPath);
while(_wfindnext(hFile,&first_file) != -1)
{
wstring sFile = first_file.name;
wstring sPath = Format(L"%s%s",pDirectory,sFile.c_str());
pFileList->push_back(sPath);
}
_findclose(hFile);
}else
return false;
return true;
}

Recursive file search using C++ MFC?

What is the cleanest way to recursively search for files using C++ and MFC?
EDIT: Do any of these solutions offer the ability to use multiple filters through one pass? I guess with CFileFind I could filter on *.* and then write custom code to further filter into different file types. Does anything offer built-in multiple filters (ie. *.exe,*.dll)?
EDIT2: Just realized an obvious assumption that I was making that makes my previous EDIT invalid. If I am trying to do a recursive search with CFileFind, I have to use *.* as my wildcard because otherwise subdirectories won't be matched and no recursion will take place. So filtering on different file-extentions will have to be handled separately regardless.
Using CFileFind.
Take a look at this example from MSDN:
void Recurse(LPCTSTR pstr)
{
CFileFind finder;
// build a string with wildcards
CString strWildcard(pstr);
strWildcard += _T("\\*.*");
// start working for files
BOOL bWorking = finder.FindFile(strWildcard);
while (bWorking)
{
bWorking = finder.FindNextFile();
// skip . and .. files; otherwise, we'd
// recur infinitely!
if (finder.IsDots())
continue;
// if it's a directory, recursively search it
if (finder.IsDirectory())
{
CString str = finder.GetFilePath();
cout << (LPCTSTR) str << endl;
Recurse(str);
}
}
finder.Close();
}
Use Boost's Filesystem implementation!
The recursive example is even on the filesystem homepage:
bool find_file( const path & dir_path, // in this directory,
const std::string & file_name, // search for this name,
path & path_found ) // placing path here if found
{
if ( !exists( dir_path ) ) return false;
directory_iterator end_itr; // default construction yields past-the-end
for ( directory_iterator itr( dir_path );
itr != end_itr;
++itr )
{
if ( is_directory(itr->status()) )
{
if ( find_file( itr->path(), file_name, path_found ) ) return true;
}
else if ( itr->leaf() == file_name ) // see below
{
path_found = itr->path();
return true;
}
}
return false;
}
I know it is not your question, but it is also easy to to without recursion by using a CStringArray
void FindFiles(CString srcFolder)
{
CStringArray dirs;
dirs.Add(srcFolder + "\\*.*");
while(dirs.GetSize() > 0) {
CString dir = dirs.GetAt(0);
dirs.RemoveAt(0);
CFileFind ff;
BOOL good = ff.FindFile(dir);
while(good) {
good = ff.FindNextFile();
if(!ff.IsDots()) {
if(!ff.IsDirectory()) {
//process file
} else {
//new directory (and not . or ..)
dirs.InsertAt(0,nd + "\\*.*");
}
}
}
ff.Close();
}
}
Check out the recls library - stands for recursive ls - which is a recursive search library that works on UNIX and Windows. It's a C library with adaptations to different language, including C++. From memory, you can use it something like the following:
using recls::search_sequence;
CString dir = "C:\\mydir";
CString patterns = "*.doc;abc*.xls";
CStringArray paths;
search_sequence files(dir, patterns, recls::RECURSIVE);
for(search_sequence::const_iterator b = files.begin(); b != files.end(); b++) {
paths.Add((*b).c_str());
}
It'll find all .doc files, and all .xls files beginning with abc in C:\mydir or any of its subdirectories.
I haven't compiled this, but it should be pretty close to the mark.
CString strNextFileName , strSaveLog= "C:\\mydir";
Find.FindFile(strSaveLog);
BOOL l = Find.FindNextFile();
if(!l)
MessageBox("");
strNextFileName = Find.GetFileName();
Its not working. Find.FindNextFile() returning false even the files are present in the same directory``