Change file/path extension - c++

Using VC++, how can I remove the extension from the following file path and change it to a new extension(using strings):
CString path(_T(m_DirTree.GetCurrentDir())); // copy file path to variable 'path' of type CString
//Add code here....
The path to the file in question is L:\PowerStar 5 Demo II\Programs\Demo\Programs\33100.PRG and I would like to change the file extension to 33100.CRC. Is there some way I could use _splitpath to change the file extension to .CRC? This path is one of many which can be selected via a directory tree that is passed to variable path and I am just using this particular path as an example. So I cannot alter it as below:
CString path(_T("L:\PowerStar 5 Demo II\Programs\Demo\Programs\33100.CRC"));
Is it possible to concatenate the strings so I can open without getting an exception?
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
// Split path to isolate file extension(.prg) for if statement
_splitpath(m_DirTree.GetCurrentDir(), drive, dir, fname, ext);
CString crcFile;
crcFile = strcat(fname,".CRC"); // concatenate chars to point to .CRC file of same name
FILE *cr = fopen(fname, "r"); // Handle to the file in question
The above code throws an unhandled exception.

Try using the Shell API function PathRenameExtension. Or if you want the buffer management handled for you CPathT::RenameExtension, for example:
CPath path(_T("L:\\PowerStar 5 Demo II\\Programs\\Demo\\Programs\\33100.PRG"));
path.RenameExtension(_T(".CRC"));
CString modifiedPath = path;

CString has 2 methods, which might help you.
ReverseFind() and Left()
CString filenameWithoutExtension = path.Left(path.ReverseFind(_T('.')));
Then you can add your new file extension (e.g. ".exe") at the end of the new string.
path = filenameWithoutExtension + _T(".exe");

Related

getenv core dump error in daemon service program

I wrote a daemon service program and I want to open a file in /home/user path while the service is active. But I don't want to open file as root. The first thing I tried for this was to get the user name with the getenv("USER") function, keep it in a string, and then open a txt file with this string path. But after daemonize the program getenv function caused core dump.
int main(){
make_daemon();
const char *userName = "USER";
const char *homePath = "/home/";
const char *env_p = getenv(userName); //Core dump!
std::string m_filePath = homePath;
m_filePath += env_p;
m_filePath += "/test.txt"; // "/home/<user>/test.txt"
//open filePath
//some stuff...
}
I can probably solve this problem by running the service as root and creating a text file somewhere in the /usr/local/ path, but I want to create the text file with the user, not root. Is it possible or is there any other way to do this?

Directory Open Issue when passing path as parameter

I having an issue with my program which is expected to either ask a user to input a directory path or to use an predefine directory path as an argument so that my program can open that directory.
Asking a user to input the directory path (C:\Users\Desktop\Test) works fine. But I am having an issue when I am passing the file path as argument.
It should be passed as this:
char location[1000] = "C:\Users\Desktop\Test";
if ((dir = opendir (location)) != NULL){
......
}
But using argument, my program can only open the directory if location is initialised and assigned as this:
char location[1000] = "C:\\Users\\Desktop\\Test";
if ((dir = opendir (location)) != NULL){
......
}
However, I need to concatenate location with a filename in another part of my program so that it becomes: C:\Users\Desktop\Test\file.txt
It won`t work with: C:\\Users\\Desktop\\Test\\file.txt.
char location[1000] can`t be modified as it works well with my code when opening or closing directory.

Concat a String in python

this is are my files
2015125_0r89_PEO.txt
2015125_0r89_PED.txt
2015125_0r89_PEN.txt
2015126_0r89_PEO.txt
2015126_0r89_PED.txt
2015126_0r89_PEN.txt
2015127_0r89_PEO.txt
2015127_0r89_PED.txt
2015127_0r89_PEN.txt
and I want to change to this:
US.CAR.PEO.D.2015.125.txt
US.CAR.PED.D.2015.125.txt
US.CAR.PEN.D.2015.125.txt
US.CAR.PEO.D.2015.126.txt
US.CAR.PED.D.2015.126.txt
US.CAR.PEN.D.2015.126.txt
US.CAR.PEO.D.2015.127.txt
US.CAR.PED.D.2015.127.txt
US.CAR.PEN.D.2015.127.txt
this is my code so far,
import os
paths = (os.path.join(root, filename)
for root, _, filenames in os.walk('C:\\data\\MAX\\') #location files
for filename in filenames)
for path in paths:
a = path.split("_")
b = a[2].split(".")
c = "US.CAR."+ b[0] + ".D." + a[0]
print c
when I run the script it's no make any error, but not change the name of the files .txt which it is what it should supposed to do
any help?
The way you do it by first getting the path and then manipulating it will get bad results, in this case is best first get the name of the file, make the changes to it and then change the name of the file itself, like this
for root,_,filenames in os.walk('C:\\data\\MAX\\'):
for name in filenames:
print "original:", name
a = name.split("_")
b = a[2].split(".")
new = "US.CAR.{}.D.{}.{}".format(b[0],a[0],b[1]) #don't forget the file extention
print "new",new
os.rename( os.path.join(root,name), os.path.join(root,new) )
string concatenation is more inefficient, the best way is using string formating.

How to read a XML file using fstream in IOS

I am using XCode, and here is a c++ code in XCode
std::fstream stream("templates.Xml", std::ios::binary | std::ios::in);
if(!stream) return false;
I put the Xml file in the folder that contain the ".xcodeproj", and I put it in the folder that contains ".app" but the stream always return false, why?
It looks like you are trying to open the file from the wrong directory.
"templates.Xml" is saved in the bundle- is not saved in the documents directory. By default, if you open "./filename", this actually points to:
/Users/arinmorf/Library/Application Support/iPhone Simulator/7.0.3/Applications/246E91F9-FAB2-4A46-B1F1-855B5363F24D/Documents/
Where arinmorf would be your username and the long hex string is randomly generated every time you install the app on the simulator.
The templates.xml file would be found in:
/Users/arinmorf/Library/Application Support/iPhone Simulator/7.0.3/Applications/246E91F9-FAB2-4A46-B1F1-855B5363F24D/iFly.app/templates.xml
iFly.app is the name of my app, yours would be "T". BUT you can't use the absolute path in your project, because of the randomly generated string, you need to use the NSBundle or CFBundleRef.
In objective-C, you would use:
filePath = [[NSBundle mainBundle] pathForResource:#"templates" ofType:#"xml"];
NSData *myData = [NSData dataWithContentsOfFile:filePath];
In C++ it looks like:
CFURLRef fileURL = CFBundleCopyResourceURL(CFBundleGetMainBundle(), CFSTR("templates"), CFSTR("xml"), NULL);
CFStringRef filePath = CFURLCopyFileSystemPath(fileURL, kCFURLPOSIXPathStyle);
CFStringEncoding encodingMethod = CFStringGetSystemEncoding();
const char *path = CFStringGetCStringPtr(filePath, encodingMethod);
FILE* f = fopen(path, "r");
(Credit to Chris Frederick at https://stackoverflow.com/a/8768366/2070758 for C++ version)
Yes, I solved the problem in two ways either depending on Main Bundle, or create custom bundle and use it.

Get actual folder path

How I can get actual folder path where my program is without my exe file name in C++?
The following function will give you the application path:
::GetModuleFileName(NULL, szAppPath, MAX_PATH);
Now to extract the folder, you need to find the last backslash:
char szApplicationPath[MAX_PATH] = "";
::GetModuleFileName(NULL, szApplicationPath, MAX_PATH);
//Get the folder part
CString strApplicationFolder;
strApplicationFolder = szApplicationPath;
strApplicationFolder = strApplicationFolder.Left(strApplicationFolder.ReverseFind("\\"));