简体   繁体   中英

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

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>;

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.

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.

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM