Home > Enterprise >  Get temp path with file name
Get temp path with file name

Time:05-14

I want to get path to file like this > %ENV%/%FILE_NAME%.docx

But c doesn't make sense at all and nothing works..
I would use std::string but it's not compatible so I tried multiple ways of converting it to char[] or char* but none of them works and I'm also pretty sure this is unsafe..

My code so far (I know it's the worst code ever..)

char* appendCharToCharArray(char* array, char a)
{
    size_t len = strlen(array);

    char* ret = new char[len   2];

    strcpy(ret, array);
    ret[len] = a;
    ret[len   1] = '\0';

    return ret;
}

const char* getBaseName(std::string path)
{
    std::string base_filename = path.substr(path.find_last_of("/\\")   1);

    std::string::size_type const p(base_filename.find_last_of('.'));
    std::string file_without_extension = base_filename.substr(0, p);

    return file_without_extension.c_str();
}

int main()
{
    char szExeFileName[MAX_PATH];
    GetModuleFileName(NULL, szExeFileName, MAX_PATH);

    const char* file_name = getBaseName(std::string(szExeFileName));

    char* new_file = getenv("temp");
    new_file = appendCharToCharArray(new_file, '\\');

    for (int i=0;i<sizeof(file_name)/sizeof(file_name[0]);i  )
    {
        new_file = appendCharToCharArray(new_file, file_name[i]);
    }

    new_file = appendCharToCharArray(new_file, '.');
    new_file = appendCharToCharArray(new_file, 'd');
    new_file = appendCharToCharArray(new_file, 'o');
    new_file = appendCharToCharArray(new_file, 'c');
    new_file = appendCharToCharArray(new_file, 'x');

    std::cout << new_file << std::endl;
}

CodePudding user response:

Using appendCharToCharArray() is just horribly inefficient in general, and also you are leaking lots of memory with the way you are using it. Just use std::string instead. And yes, you can use std::string in this code, it is perfectly "compatible" if you use it correctly.

getBaseName() is returning a char* pointer to the data of a local std::string variable that goes out of scope when the function exits, thus a dangling pointer is returned. Again, use std::string instead.

And, you should use the Win32 GetTempPath/2() function instead of getenv("temp").

Try something more like this:

#include <iostream>
#include <string>

std::string getBaseName(const std::string &path)
{
    std::string base_filename = path.substr(path.find_last_of("/\\")   1);

    std::string::size_type const p(base_filename.find_last_of('.'));
    std::string file_without_extension = base_filename.substr(0, p);

    return file_without_extension;
}

int main()
{
    char szExeFileName[MAX_PATH] = {};
    GetModuleFileNameA(NULL, szExeFileName, MAX_PATH);

    char szTempFolder[MAX_PATH] = {};
    GetTempPathA(MAX_PATH, szTempFolder);

    std::string new_file = std::string(szTempFolder)   getBaseName(szExeFileName)   ".docx";

    std::cout << new_file << std::endl;
}

Online Demo

That being said, the Win32 Shell API has functions for manipulating path strings, eg:

#include <iostream>
#include <string>
#include <windows.h>
#include <shlwapi.h>

#pragma comment(lib, "Shlwapi.lib")

int main()
{
    char szExeFileName[MAX_PATH] = {};
    GetModuleFileNameA(NULL, szExeFileName, MAX_PATH);

    char szTempFolder[MAX_PATH] = {};
    GetTempPathA(MAX_PATH, szTempFolder);

    char new_file[MAX_PATH] = {};
    PathCombineA(new_file, szTempFolder, PathFindFileNameA(szExeFileName));
    PathRenameExtensionA(new_file, ".docx");

    std::cout << new_file << std::endl;
}

Or, if you are using C 17 or later, consider using std::filesystem::path instead, eg:

#include <iostream>
#include <filesystem>
#include <windows.h>

namespace fs = std::filesystem;

int main()
{
    char szExeFileName[MAX_PATH] = {};
    GetModuleFileNameA(NULL, szExeFileName, MAX_PATH);

    char szTempFolder[MAX_PATH] = {};
    GetTempPathA(MAX_PATH, szTempFolder);

    fs::path new_file = fs::path(szTempFolder) / fs::path(szExeFileName).stem();
    new_file  = ".docx";

    // alternatively:
    // fs::path new_file = fs::path(szTempFolder) / fs::path(szExeFileName).filename();
    // new_file.replace_extension(".docx");

    std::cout << new_file << std::endl;
}

Online Demo

  •  Tags:  
  • c
  • Related