I see C's getcwd via:
man 3 cwd
I suspect C++ has a similar one, that could return me a std::string .
If so, what is it called, and where can I find it's documentation?
Thanks!
Ok, I'm answering even though you already have accepted an answer.
An even better way than to wrap the getcwd call would be to use boost::filesystem, where you get a path object from the current_path() function. The Boost filesystem library allows you to do lots of other useful stuff that you would otherwise need to do a lot of string parsing to do, like checking if files/directories exist, get parent path, make paths complete etcetera. Check it out, it is portable as well - which a lot of the string parsing code one would otherwise use likely won't be.
Update (2016): Filesystem has been published as a technical specification in 2015, based on Boost Filesystem v3. This means that it may be available with your compiler already (for instance Visual Studio 2015). To me it also seems likely that it will become part of a future C++ standard (I would assume C++17, but I am not aware of the current status).
Update (2017): The filesystem library has been merged with ISO C++ in C++17, for
std::filesystem::current_path();
std::string's constructor can safely take a char* as a parameter. Surprisingly there's a windows version too.
Edit: actually it's a little more complicated:
std::string get_working_path()
{
char temp[MAXPATHLEN];
return ( getcwd(temp, sizeof(temp)) ? std::string( temp ) : std::string("") );
}
Memory is no problem -- temp is a stack based buffer, and the std::string constructor does a copy. Probably you could do it in one go, but I don't think the standard would guarantee that.
About memory allocation, via POSIX:
The getcwd() function shall place an absolute pathname of the current working directory in the array pointed to by buf, and return buf. The pathname copied to the array shall contain no components that are symbolic links. The size argument is the size in bytes of the character array pointed to by the buf argument. If buf is a null pointer, the behavior of getcwd() is unspecified.
Let's try and rewrite this simple C call as C++:
std::string get_working_path()
{
char temp [ PATH_MAX ];
if ( getcwd(temp, PATH_MAX) != 0)
return std::string ( temp );
int error = errno;
switch ( error ) {
// EINVAL can't happen - size argument > 0
// PATH_MAX includes the terminating nul,
// so ERANGE should not be returned
case EACCES:
throw std::runtime_error("Access denied");
case ENOMEM:
// I'm not sure whether this can happen or not
throw std::runtime_error("Insufficient storage");
default: {
std::ostringstream str;
str << "Unrecognised error" << error;
throw std::runtime_error(str.str());
}
}
}
The thing is, when wrapping a library function in another function you have to assume that all the functionality should be exposed, because a library does not know what will be calling it. So you have to handle the error cases rather than just swallowing them or hoping they won't happen.
It's usually better to let the client code just call the library function, and deal with the error at that point - the client code probably doesn't care why the error occurred, and so only has to handle the pass/fail case, rather than all the error codes.
You'll need to just write a little wrapper.
std::string getcwd_string( void ) {
char buff[PATH_MAX];
getcwd( buff, PATH_MAX );
std::string cwd( buff );
return cwd;
}
I used getcwd() in C in the following way:
char * cwd;
cwd = (char*) malloc( FILENAME_MAX * sizeof(char) );
getcwd(cwd,FILENAME_MAX);
The header file needed is stdio.h.
When I use C compiler, it works perfect.
If I compile exactly the same code using C++ compiler, it reports the following error message:
identifier "getcwd" is undefined
Then I included unistd.h and compiled with C++ compiler.
This time, everything works.
When I switched back to the C compiler, it still works!
As long as you include both stdio.h and unistd.h, the above code works for C AND C++ compilers.
All C functions are also C++ functions. If you need a std::string, just create one from the char* that getcwd gets for you.
I also used boost::filesystem as stated in another answer above. I just wanted to add that since the current_path() function does not return a std::string, you need to convert it.
Here is what I did:
std::string cwd = boost::filesystem::current_path().generic_string();
You could create a new function, which I would prefer over linking to a library like boost(unless you already are).
std::string getcwd()
{
char* buff;//automatically cleaned when it exits scope
return std::string(getcwd(buff,255));
}
Related
There's a function provided by my uni that is supposed to read in a file. In the parameter, there's the fileName parameter. What I don't understand is why they're using a character pointer instead of a simple string?
Also, how would I call this function with a string filename then?
I'm running C++14 on Visual studio 2017 community edition.
double* read_text(char *fileName, int sizeR, int sizeC)
{
double* data = new double[sizeR*sizeC];
int i = 0;
ifstream myfile(fileName);
if (myfile.is_open())
{
while (myfile.good())
{
if (i > sizeR*sizeC - 1) break;
myfile >> *(data + i);
i++;
}
myfile.close();
}
else cout << "Unable to open file";
//cout << i;
return data;
}
Edit: I get it guys, it's stupid. I'll post a separate question then. Thanks for the fast response!
why is this filename parameter a char pointer instead of string?
Because the designer of the API chose to do so. Most people at Stack Overflow are not the author of that API, so we cannot answer this question accurately.
However, there is another similar question that we can answer: What are reasons to use character pointer as a string argument? Let me answer that question instead:
Not using std::string as an argument allows the user of the API to not create a std::string object. This may be useful when:
The API needs to be used in "freestanding" implementations that don't provide the standard library and thus have no std::string. This probably doesn't apply to your particular example since the implementation of the function uses the standard library, but I include this argument for completeness.
The API needs to be used on systems that provide no dynamic memory allocation, which std::string requires.
The dynamic memory allocation that creation of the string may require may be too slow in the context where the API is used (this won't apply to an API that is going to read from disk, but I include the argument here for completeness).
(const) char* makes it possible to use the API from C. This may be relevant because:
The API may have originally been written for C, and has been inherited to a code base that now uses C++, but the API has not been changed in order to maintain backwards compatibility.
Providing a C compatible API allows using the API from other languages that are able to interface with C. Many languages have support for C interfaces while very few languages have support for C++ interfaces.
Also, how would I call this function with a string filename then?
You can get a pointer to a null terminated string using the c_str member function. Unfortunately the API is badly designed and the argument is non-const, while the pointer returned by c_str is const. You can const_cast the constness of the argument away in order to call this function. This is "OK" because the function doesn't actually modify the pointed string.
If you can require C++17 standard and the source string is non-const, then the data member function will be simpler as it doesn't require const_cast. Prior to C++17 there was no non-const overload, so it would require the same const casting, and prior to C++11 the pointed string was not guaranteed to be null terminated.
To make it clear: Using a non-const string argument for this function is bad design - whether that argument is a character pointer to null terminated string, or a reference to std::string.
P.S.There are other, more serious problems:
The caller of the function cannot possibly know how many numbers were read from the file. There is no way of avoiding UB in case the file has less than sizeR*sizeC values.
Returning a bare pointer that owns dynamic memory resource is a very bad design.
The loop that reads from the file checks whether the read was successful after the value has already been added to the array and the value is never overwritten, so the last element written into the array is always has an unspecified value.
Is it possible to have a function like this:
const char* load(const char* filename_){
return
#include filename_
;
};
so you wouldn't have to hardcode the #include file?
Maybe with a some macro?
I'm drawing a blank, guys. I can't tell if it's flat out not possible or if it just has a weird solution.
EDIT:
Also, the ideal is to have this as a compile time operation, otherwise I know there's more standard ways to read a file. Hence thinking about #include in the first place.
This is absolutely impossible.
The reason is - as Justin already said in a comment - that #include is evaluated at compile time.
To include files during run time would require a complete compiler "on board" of the program. A lot of script languages support things like that, but C++ is a compiled language and works different: Compile and run time are strictly separated.
You cannot use #include to do what you want to do.
The C++ way of implementing such a function is:
Find out the size of the file.
Allocate memory for the contents of the file.
Read the contents of the file into the allocated memory.
Return the contents of the file to the calling function.
It will better to change the return type to std::string to ease the burden of dealing with dynamically allocated memory.
std::string load(const char* filename)
{
std::string contents;
// Open the file
std::ifstream in(filename);
// If there is a problem in opening the file, deal with it.
if ( !in )
{
// Problem. Figure out what to do with it.
}
// Move to the end of the file.
in.seekg(0, std::ifstream::end);
auto size = in.tellg();
// Allocate memory for the contents.
// Add an additional character for the terminating null character.
contents.resize(size+1);
// Rewind the file.
in.seekg(0);
// Read the contents
auto n = in.read(contents.data(), size);
if ( n != size )
{
// Problem. Figure out what to do with it.
}
contents[size] = '\0';
return contents;
};
PS
Using a terminating null character in the returned object is necessary only if you need to treat the contents of the returned object as a null terminated string for some reason. Otherwise, it maybe omitted.
I can't tell if it's flat out not possible
I can. It's flat out not possible.
Contents of the filename_ string are not determined until runtime - the content is unknown when the pre processor is run. Pre-processor macros are processed before compilation (or as first step of compilation depending on your perspective).
When the choice of the filename is determined at runtime, the file must also be read at runtime (for example using a fstream).
Also, the ideal is to have this as a compile time operation
The latest time you can affect the choice of included file is when the preprocessor runs. What you can use to affect the file is a pre-processor macro:
#define filename_ "path/to/file"
// ...
return
#include filename_
;
it is theoretically possible.
In practice, you're asking to write a PHP construct using C++. It can be done, as too many things can, but you need some awkward prerequisites.
a compiler has to be linked into your executable. Because the operation you call "hardcoding" is essential for the code to be executed.
a (probably very fussy) linker again into your executable, to merge the new code and resolve any function calls etc. in both directions.
Also, the newly imported code would not be reachable by the rest of the program which was not written (and certainly not compiled!) with that information in mind. So you would need an entry point and a means of exchanging information. Then in this block of information you could even put pointers to code to be called.
Not all architectures and OSes will support this, because "data" and "code" are two concerns best left separate. Code is potentially harmful; think of it as nitric acid. External data is fluid and slippery, like glycerine. And handling nitroglycerine is, as I said, possible. Practical and safe are something completely different.
Once the prerequisites were met, you would have two or three nice extra functions and could write:
void *load(const char* filename, void *data) {
// some "don't load twice" functionality is probably needed
void *code = compile_source(filename);
if (NULL == code) {
// a get_last_compiler_error() would be useful
return NULL;
}
if (EXIT_SUCCESS != invoke_code(code, data)) {
// a get_last_runtime_error() would also be useful
release_code(code);
return NULL;
}
// it is now the caller's responsibility to release the code.
return code;
}
And of course it would be a security nightmare, with source code left lying around and being imported into a running application.
Maintaining the code would be a different, but equally scary nightmare, because you'd be needing two toolchains - one to build the executable, one embedded inside said executable - and they wouldn't necessarily be automatically compatible. You'd be crying loud for all the bugs of the realm to come and rejoice.
What problem would be solved?
Implementing require_once in C++ might be fun, but you thought it could answer a problem you have. Which is it exactly? Maybe it can be solved in a more C++ish way.
A better alternative, considering also performances etc., to compile a loadable module beforehand, and load it at runtime.
If you need to perform small tunings to the executable, place parameters into an external configuration file and provide a mechanism to reload it. Once the modules conform to a fixed specification, you can even provide "plugins" that weren't available when the executable was first developed.
There is a function to load files:
int loadfile(char *fn)
{
printf( "\n my path: '%s' \n", fn );
FILE *f = fopen( fn, "r");
printf( "got\n" );
...
return 1;
}
The first file is in main() newfile( argv[1] );, works. The second is get by flex parsing/reading the first file, what I belive isn't related to the problem.
The console:
path: 'file1.hot'
got
path: 'file2.hot'
Segmentation fault: 11
The printf was able to print the char *fn, but fopen get a segmentation fault.
The next situation was, I tried explicit to put the file inside the loadfile doing fopen( "file2.hot", "r"); and works.
I'm compiling with g++, there is a different approaching when using c++ to use char * or fopen?
EDIT
Sorry, there's no newfile( argv[1] );. Correct: loadfile( argv[1] );.
General remark: When using C++, please prefer std::fstream to the C-style fopen/fread/etc.; also prefer std::string to char*. The latter alone will cure many memory headaches. If you, for some reason, have to stick to the C-style functions, be sure to check the return values (as mentioned in the other answers here already) - fopen for example returns a NULL pointer when it fails.
More specific to your question: Try to run your program under gdb (e.g. gdb <your-program>), to see where the Segmentation fault occurs exactly; that way you will also be able to see more details (e.g. variable contents etc.). Alternatively, if working under linux, use analysis tools such as valgrind to detect any kind of memory access problems.
you should always check return values from functions that have a return value. In this case make sure when you fopen the file that the return handle is not NULL and also make sure if you open the file, to fclose it.
Learn to use the GDB debugger (assuming you are on Linux), or the valgrind utility.
Perhaps putting your file path inside a std::string is worthwhile, and, as nyarlathotep mentioned, use a std::fstream.
It could happen that your fn is not null terminated....
Compile with g++ -Wall -g
As Anders K answered, always check the result of fopen against NULL. Pierre Vittet's Talpo extension to GCC (coded in MELT) is able to check automatically that you do check that.
I am working on a program which uses realpath() to get the absolute path of a file. Unfortunately, this function takes a string buffer that is expected to be so large that it is big enough and that's not safe when this application has to run across multiple platforms. Is there a safe version of this function which avoids the buffer overflow issue, perhaps using dynamic memory allocation?
See here for information on safe and portable use of realpath:
http://www.opengroup.org/onlinepubs/9699919799/functions/realpath.html
Basically, modern standards allow you to pass a NULL pointer, and realpath will allocate a buffer of the appropriate length. If you want to be portable to legacy systems which do not support this standard, simply check #ifdef PATH_MAX and use a fixed-size buffer of length PATH_MAX. As far as I know, there are no legacy systems that lack a constant PATH_MAX but which do not support NULL arguments to realpath.
From the manpage:
If resolved_path is specified as
NULL, then realpath() uses malloc(3)
to allocate a buffer of up to PATH_MAX
bytes to hold the resolved pathname,
and returns a pointer to this buffer.
The caller should deallocate this
buffer using free(3).buffer using free(3).
So it seems like you can just do this:
char *real_path = realpath(path, NULL);
// use real_path
free(real_path);
There is a way to do the same in Boost using boost::filesystem:
#include <boost/filesystem.hpp>
using namespace boost::filesystem;
try{
path absolutePath = canonical("./../xxx"); //will throw exception if file not exists!
}
catch{...}{
cout << "File not exists";
}
cout << absolutePath.string();
There is QT way to do it (got from here):
QFileInfo target_file_name(argv[1]);
QString absolute_path = target_file_name.absolutePath()
There is a bit complicated implementation of realpath in C++. Cannot tell anything about it's safety, but it should allow path with length more then PATH_MAX. Going to test it soon.
At some places in my code, I print debug messages like this:
int ret = getLinkSpeed(device.getSysName(), linkSpeed);
if (ret < 0)
{
logDebug("Failed to obtain port speed for this device. Error: " + std::string(strerror(errno)));
}
From the documentation it is not entirely clear if strerror will return 0 under certain conditions (which would cause my code to crash). Does anyone know if it's safe?
Why not write a function to do this:
string ErrStr() {
char * e = strerror(errno);
return e ? e : "";
}
This is easy to use, self-documenting, can be adapted to reformat the output and covers the possibility that strerror() might return NULL (I don't know if it can).
Where you might get problems, is if you use a multi-threaded application. In this case, you need to use strerror_r
Good question (+1), the documentation seems quite vague. I'm not sure if there is a "harder" source, such as the POSIX specification for instance.
Thinking a bit pragmatically, here is GNU libc's implementation. It returns a pointer to a static string buffer, so it cannot return 0.
In response to p00ya's comment, the safe (and also very pragmatical, heh) thing to do in the face of conflicting, vague or incomplete specifications is of course to assume the worst, and
not assume that the return value will always be a valid string.