John Boe
John Boe

Reputation: 3621

How to declare char sequence for function (C++)?

How to make declaration for function to have char sequence in the result?

I have this now:

#define _MAX_PATH   260    
char * GetTempFileName(char fileName [_MAX_PATH]);

But the result should be in type char [_MAX_PATH]


#include <array>
typedef std::array<char,_MAX_PATH> Path;
extern class Setts
{
    char path [_MAX_PATH];

public:
    Setts();~Setts();
    Path getTempFileName(const Path &fileName);
} setts;

Setts::~Setts(){}

Path Setts::getTempFileName(const Path &fileName) 
{
    GetCurrentDirectory(_MAX_PATH, path);
    strcat(path, "\\");
    strcat(path, fileName);
    return path;
}

This is what makes problem to me...

error C2143: syntax error : missing ';' before 'Setts::GetTempFileNameA'
error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
error C2556: 'int Setts::GetTempFileNameA(Setts::Path)' : overloaded function differs only by return type from 'Setts::Path Setts::GetTempFileNameA(Setts::Path)'

Is it really not possible to get the result in char sequence char [_MAX_PATH] ? The problem here is, that when I create new type Path, so all functions of conditions that depends on char [_MAX_PATH] type cause errors in the project.


From comments with g-makulik

What does mean the path.data() ... data looks like some function, what does this do? Is it evaluated after the result of the function is saved to path variable? – user1141649 16 mins ago

g-makulik:

It provides access to the std::array's underlying data (an array of char[260]). You can use it in other places to interface that array as well. – 

I tried to simplify it because compatibility with the rest of the project:

settings.h:
#include <stdlib.h>
#include <iostream>
#include <array>
typedef char Path [_MAX_PATH]; 

extern class Setts
{
    Path& path;

public:
    Setts();~Setts();

    Path& getTempFileName(const Path &fileName);
    bool load();

    Path& BasePath;
    Path& ScenPath;

    Path& TempPath;
    #define DEL_TEMP_ON_EXIT 1;

    Path& logname;

    bool intense;

} setts;

settings.cpp:

#include <windows.h>
#include "settings.h"
#include <stdio.h>

Setts::~Setts(){}

Path& Setts::getTempFileName(const Path &fileName) 
{
    GetCurrentDirectory(_MAX_PATH, path);
    strcat(path, "\\");
    strcat(path, fileName);
    return path;
}

bool Setts::load()
{
    TempPath = getTempFileName("scendata.tmp");
    logname = getTempFileName("ats_cache.log");

    return (result == ERROR_SUCCESS);
}

Now I got error: near TempPath = getTempFileName("scendata.tmp"); and logname = getTempFileName("ats_cache.log"); :

'Setts::getTempFileName' : cannot convert parameter 1 from 'const char [13]' to 'const Path (&)' Reason: cannot convert from 'const char [13]' to 'const Path' There is no context in which this conversion is possible error C2664: 'Setts::getTempFileName' : cannot convert parameter 1 from 'const char [14]' to 'const Path (&)' Reason: cannot convert from 'const char [14]' to 'const Path' There is no context in which this conversion is possible

Upvotes: 0

Views: 1194

Answers (4)

John Boe
John Boe

Reputation: 3621

I have solved the problem. Thanks to all involved. (I have removed the class just for simplification here.

#define _MAX_PATH   260    
char path [_MAX_PATH];
char BasePath [_MAX_PATH];
char ScenPath [_MAX_PATH];
char TempPath [_MAX_PATH];
char logname [_MAX_PATH];

char* getTempFileName(char *fileName, char *targetVariable);

char* getTempFileName(char *fileName, char *targetVariable) 
{
GetCurrentDirectory(_MAX_PATH, targetVariable);
strcat_s(targetVariable, _MAX_PATH, "\\");
strcat_s(targetVariable, _MAX_PATH, fileName);
return targetVariable;
}

getTempFileName("scendata.tmp",TempPath);
getTempFileName("ats_cache.log",logname);

Upvotes: 0

πάντα ῥεῖ
πάντα ῥεῖ

Reputation: 1

I c++ you should better do:

#include <array>

typedef std::array<char,260> Path;

Path MyTempFileName(const Path& fileName);

Here's a fixed version of your code:

#include <array>
class Setts
{

public:
    Setts();~Setts();
    typedef std::array<char,_MAX_PATH> Path;
    Path& MyTempFileName(Path fileName);

private:
    Path path;  //Path to INI
};

Setts::~Setts(){}

Setts::Path& Setts::MyTempFileName(Setts::Path fileName) 
{
    GetCurrentDirectory(_MAX_PATH, path.data());
    strcat(path.data(), "\\");
    strcat(path.data(), fileName);
    return path;
}

But I'd say using std::string to keep the data, and std::ostringstream to format it would be a better solution for your use case than fixed size arrays.

Upvotes: 2

masoud
masoud

Reputation: 56509

std::array, std::string, std::vector and a simple struct. All of them are useful.

typedef std::string                Path;  // or
typedef std::array<char, MAX_PATH> Path;  // or
typedef std::vector<char>          Path;

Path GetTempFileName(const Path &path);

or simply:

struct Path
{
   char value[MAX_PATH];
};

C++11 presents using as an alternative for typedef:

using Path = std::string;                 // or
using Path = std::array<char, MAX_PATH>;  // or
using Path = std::vector<char>;

Upvotes: 3

Pat
Pat

Reputation: 1776

Generally in C, you would provide the output buffer to the function as well as the size of it. Also, assuming fileName is zero-terminated, there is no need to specify the size of the buffer.

char * GetTempFileName(const char *fileName, char *tempFileName, size_t tempFileNameSize);

The function should return the tempFileName pointer or NULL in case of an error. You would then call it like:

char fileName[] = "myFile.txt";
char tempFileName[_MAX_PATH];
if (GetTempFileName(fileName, tempFileName, sizeof(tempFileName)) == NULL) {
   // handle error
}

I'm also assuming the implementation of GetTempFileName will use the fileName parameter as some form of template.

Upvotes: 0

Related Questions