FILE* initialisation in different function c++ - c++

I need to initialise FILE *fi in different function. This example code shows the problem.
#include<iostream>
using namespace std;
void init(FILE* fi)
{
fi=fopen("in.txt", "r");
if(fi==NULL)
{
cout<<"Got NULL\n";
}
}
int main()
{
FILE* fi;
init(fi);
if(fi==NULL)
{
cout<<"NULL\n";
return 0;
}
return 0;
}
The program outputs NULL (not "Got NULL"), and I don't have a clue how to make it work...
It is important that I have fi passed as a pointer, not getting it as a return value.

You shouldn't manipulate arguments unless that's the specific intent of the code. It's better to simply return things:
FILE* init()
{
return fopen("in.txt", "r");
}
Then you call it like this:
FILE* fi = init();
Note that since you're using C++ you should avoid using C anachronisms like FILE and instead use C++ file streams.
If you need to handle multiple return values:
std::tuple<FILE*, FILE*> init() {
return std::make_tuple(
fopen("in.txt", "r"),
fopen("out.txt", "w")
);
}
This is just a step towards making it proper C++ code by encapsulating all of this inside a proper class definition and then you can manipulate properties directly:
class FileWrapper {
public:
FileWrapper();
~FileWrapper();
void init();
protected:
FILE *fi;
FILE *fo;
}
void FileWrapper::init() {
fi = fopen("in.txt", "r");
fo = fopen("out.txt", "w");
}
In that case you don't even need return values. You'll also be able to automatically clean up those filehandles when that wrapper class gets deallocated if you write a proper destructor.

OK, got it.
Replase
void init(FILE* fi)
with
void init(FILE*&fi)

Related

Accessing a DLL with a header file in Code::Blocks

I'm having trouble here. I don't know how to link and define methods in a C++ DLL inside a header file. How do I link it into Code::Blocks? Also, how do I define the method inside a header file? I know this seems like a stupid question but I can't find it anywhere online.
Assuming you mean Windows because of the MinGW, it's not that bad. For example, a function in "theDLL.dll" named "someDllFunction" that takes a double and returns an int might have this excerpt:
//dllfunctions.h
int someDllFoo(double d) {
auto dll = LoadLibraryW(L"theDLL");
if (!dll) {
//error
}
using FooType = int(*)(double);
auto func = (FooType)GetProcAddress(dll, "someDllFunction");
if (!func) {
//error
}
int result = func(d);
if (!FreeLibrary(dll)) {
//error
}
return result;
}
//whatever.cpp
#include "dllfunctions.h"
int main() {
int result = someDllFoo(3.2);
}
You could take this even further by writing a more generic caller. The following will not work for a void return type, since it assigns the result, but that's addable:
template<typename Ret, typename... Args>
Ret callDllFunction(const std::wstring &dllName, const std::string &funcName, Args... args) {
auto dll = LoadLibraryW(dllName.c_str());
if (!dll) {
//error
}
using FuncType = Ret(*)(Args...);
auto func = (FuncType)GetProcAddress(dll, funcName.c_str());
if (!func) {
//error
}
Ret result = func(args...);
if (!FreeLibrary(dll)) {
//error
}
return result;
}
int main() {
//tested example
callDllFunction<int>(L"user32", "MessageBoxW", nullptr, nullptr, nullptr, 0);
}
That should work, or at least be on the right track. Of course, as I said, that doesn't work for void return types until you add another version of it. You could also extend it for __stdcall functions. As well, it would be a good idea to set up an error mechanism so that the function from the DLL's errors can be handled. If it's something that uses SetLastError, it might be overridden by the FreeLibrary call. It really depends on what exactly you need it to do. You might also consider putting dll into a smart pointer that calls FreeLibrary when the function ends.

how to call the function for an array of classes c++

I created a class in C++ called Commands (file name commands.cpp).
I've taken that and put it into a command array (file name test.cpp).
What I would like to know is how to call the functions that are within the Commands class.
for example I have a function within the Commands class
called
void command::init(char data[])
{
//detail
}
and what i have tried to do to call the function is
EDIT
Class test{
int CmdCount; // number of commands in the array
int MaxCmds; // max amount of commands allowed
command* cmds;
Public:
int get_command_count() const{
return CmdCount;
}
int readfile(const char fname[]){
char line[161];
FILE* fp;
fp = fopen(fname, "r");
if(fp){
for(int i = 0; 1 == fscanf(fp, "%160[^\n]\n", line; i++){
cmds[get_command_count()].init(line);
CmdCount += 1;
}
}
fclose(fp);
}
};
I just want to know how to be able to call void command::init(char data[]).
Any suggestions?
thanks.
Sounds like your array contains instances of your class. In that case you want to call the method on a single entry in the array:
my_array[i].someMethod();
where my_array[i] is an instance of your class.

Creating a global FILE* object?

I'm building a program that has several functions that need to read data from a file. Since the functions are used fairly frequently, opening and closing the file for each call would be too time consuming, so my plan was to make the FILE* object global, and have the file open the whole duration of the program. Apparently, though, it's not possible, since this:
#include <fstream>
FILE * yhtit;
yhtit = fopen("thefile.txt","r");
int main() {
return 0; }
gives error: main.cpp|54|error: expected constructor, destructor, or type conversion before ‘=’ token|
What's the best way to keep a file open the whole duration of the program, without having to separately pass the FILE* object to every function that needs it?
You almost got it right. Try this:
#include <fstream>
FILE * yhtit;
int main() {
yhtit = fopen("thefile.txt","r");
//Do your thing here.
fclose(yhtit);
return 0;
}
It'd be better to pass the FILE pointer to your functions than to create a global variable. Global variables are often code smells—signs of questionable coding. You can pass the file to your functions without having to open and close the file multiple times. For example:
#include <stdio.h>
void readData(FILE *);
void readMoreData(FILE *);
int main() {
FILE *fp = fopen("...", "r");
readData(fp);
readMoreData(fp);
fclose(fp);
return 0;
}
#include <fstream>
FILE * yhtit = fopen("thefile.txt","r");
int main() {
return 0; }
You can maintain the File * variable in a structure and make that structure accessible from any function.
typedef struct
{
FILE *fp;
//other members can also be part of this structure.
}myData;
appInit(myData *ptr)
{
ptr->fp = fopen(<>,<>);
//Initialise other variables also
return;
}
appDeInit(myData *ptr)
{
fclose(ptr->fp);
}
main()
{
myData *ptr= malloc(sizeof(myData));
appInit(ptr);
//Play with ptr in all your function calls
foo(ptr);
appDeInit(myData);
}

how to open many files simultaneously for reading in c

I'm trying to port some of my c++ code into c. I have the following construct
class reader{
private:
FILE *fp;
alot_of_data data;//updated by read_until() method
public:
reader(const char*filename)
read_until(some conditional dependent on the contents of the file, and the arg supplied)
}
Im then instantiating hundreds of these object and iterate over them using several 'read_until()' for each file until allfiles is at eof.
I'm failing to see any clever way to do this in c, the only solution I can come up with is making an array of FILE pointers, and do the same with all the private member data from my class.
But this seems very messy, can I implement the functionality of my class as a function pointer, or anything better, I think I'm missing a fundamental design pattern?
The files are way to big to have all in memory, so reading everything from every file is not feasible
Thanks
You create an abstract data type:
typedef struct {
FILE *fp;
alot_of_data data;//updated by read_until() method
} reader;
void init_reader(reader* that, const char* filename);
void read_until(reader* that, some conditional dependent on the contents of the file, and the arg supplied)
Then you can create and use objects of this type just as with objects of the class, except that, instead of obj.func(), you write func(&obj):
reader r;
init_reader(&r, "blah.txt");
read_until(&r, /* ... */);
The easiest way is to just convert the data into a struct:
struct reader
{
FILE *file;
alot_of_data data;
};
Then define ordinary functions, that take a struct reader as their first argument:
int reader_construct(struct reader *r, const char *filename)
{
if((r->file = fopen(filename, "rt")) == NULL)
return 0;
/* do other inits */
return 1;
}
and the reader function becomes:
int read_until(struct reader *r, arguments)
{
/* lots of interesting code */
}
Then just have an array of structures, call reader_construct() on them and then do the read_until() calls as required.
You could of course opt for a more dynamic constructor, that returns the "object":
struct reader * reader_new(const char *filename)
{
struct reader *r = malloc(sizeof *r);
if(r == NULL)
return NULL;
if(reader_construct(r, filename))
return r;
return NULL;
}
The principle of information hiding is the same, regardless of the language you use. Just move the stuff you want to hide into the source file:
// reader.h
typedef struct reader reader;
reader* new_reader(const char*filename);
void read_until(reader*, ...);
// reader.c
struct reader {
FILE *fp;
alot_of_data data;//updated by read_until() method
};
reader *new_reader(const char*filename) { ... }
void read_until(reader*, ...) { ... }
You could always create a structure to hold all the related information, and then loop over that... Just an idea... (I think C supports structures - it's been a while...)

Getting a FILE* from a std::fstream

Is there a (cross-platform) way to get a C FILE* handle from a C++ std::fstream ?
The reason I ask is because my C++ library accepts fstreams and in one particular function I'd like to use a C library that accepts a FILE*.
The short answer is no.
The reason, is because the std::fstream is not required to use a FILE* as part of its implementation. So even if you manage to extract file descriptor from the std::fstream object and manually build a FILE object, then you will have other problems because you will now have two buffered objects writing to the same file descriptor.
The real question is why do you want to convert the std::fstream object into a FILE*?
Though I don't recommend it, you could try looking up funopen().
Unfortunately, this is not a POSIX API (it's a BSD extension) so its portability is in question. Which is also probably why I can't find anybody that has wrapped a std::stream with an object like this.
FILE *funopen(
const void *cookie,
int (*readfn )(void *, char *, int),
int (*writefn)(void *, const char *, int),
fpos_t (*seekfn) (void *, fpos_t, int),
int (*closefn)(void *)
);
This allows you to build a FILE object and specify some functions that will be used to do the actual work. If you write appropriate functions you can get them to read from the std::fstream object that actually has the file open.
There isn't a standardized way. I assume this is because the C++ standardization group didn't want to assume that a file handle can be represented as a fd.
Most platforms do seem to provide some non-standard way to do this.
http://www.ginac.de/~kreckel/fileno/ provides a good writeup of the situation and provides code that hides all the platform specific grossness, at least for GCC. Given how gross this is just on GCC, I think I'd avoid doing this all together if possible.
UPDATE: See #Jettatura what I think it is the best answer https://stackoverflow.com/a/33612982/225186 (Linux only?).
ORIGINAL:
(Probably not cross platform, but simple)
Simplifying the hack in http://www.ginac.de/~kreckel/fileno/ (dvorak answer), and looking at this gcc extension http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00069.html#a59f78806603c619eafcd4537c920f859,
I have this solution that works on GCC (4.8 at least) and clang (3.3 at least) before C++11:
#include<fstream>
#include<ext/stdio_filebuf.h>
typedef std::basic_ofstream<char>::__filebuf_type buffer_t;
typedef __gnu_cxx::stdio_filebuf<char> io_buffer_t;
FILE* cfile_impl(buffer_t* const fb){
return (static_cast<io_buffer_t* const>(fb))->file(); //type std::__c_file
}
FILE* cfile(std::ofstream const& ofs){return cfile_impl(ofs.rdbuf());}
FILE* cfile(std::ifstream const& ifs){return cfile_impl(ifs.rdbuf());}
and can be used this,
int main(){
std::ofstream ofs("file.txt");
fprintf(cfile(ofs), "sample1");
fflush(cfile(ofs)); // ofs << std::flush; doesn't help
ofs << "sample2\n";
}
Note: The stdio_filebuf is not used in newer versions of the library. The static_cast<>() is somewhat dangerous too. Use a dynamic_cast<>() instead of if you get a nullptr you need that's not the right class. You can try with stdio_sync_filebuf instead. Problem with that class is that the file() is not available at all anymore.
Limitations: (comments are welcome)
I find that it is important to fflush after fprintf printing to std::ofstream, otherwise the "sample2" appears before "sample1" in the example above. I don't know if there is a better workaround for that than using fflush. Notably ofs << flush doesn't help.
Cannot extract FILE* from std::stringstream, I don't even know if it is possible. (see below for an update).
I still don't know how to extract C's stderr from std::cerr etc., for example to use in fprintf(stderr, "sample"), in an hypothetical code like this fprintf(cfile(std::cerr), "sample").
Regarding the last limitation, the only workaround I found is to add these overloads:
FILE* cfile(std::ostream const& os){
if(std::ofstream const* ofsP = dynamic_cast<std::ofstream const*>(&os)) return cfile(*ofsP);
if(&os == &std::cerr) return stderr;
if(&os == &std::cout) return stdout;
if(&os == &std::clog) return stderr;
if(dynamic_cast<std::ostringstream const*>(&os) != 0){
throw std::runtime_error("don't know cannot extract FILE pointer from std::ostringstream");
}
return 0; // stream not recognized
}
FILE* cfile(std::istream const& is){
if(std::ifstream const* ifsP = dynamic_cast<std::ifstream const*>(&is)) return cfile(*ifsP);
if(&is == &std::cin) return stdin;
if(dynamic_cast<std::ostringstream const*>(&is) != 0){
throw std::runtime_error("don't know how to extract FILE pointer from std::istringstream");
}
return 0; // stream not recognized
}
Attempt to handle iostringstream
It is possible to read with fscanf from istream using fmemopen, but that requires a lot of book keeping and updating the input position of the stream after each read, if one wants to combine C-reads and C++-reads. I wasn't able to convert this into a cfile function like above. (Maybe a cfile class that keeps updating after each read is the way to go).
// hack to access the protected member of istreambuf that know the current position
char* access_gptr(std::basic_streambuf<char, std::char_traits<char>>& bs){
struct access_class : std::basic_streambuf<char, std::char_traits<char>>{
char* access_gptr() const{return this->gptr();}
};
return ((access_class*)(&bs))->access_gptr();
}
int main(){
std::istringstream iss("11 22 33");
// read the C++ way
int j1; iss >> j1;
std::cout << j1 << std::endl;
// read the C way
float j2;
char* buf = access_gptr(*iss.rdbuf()); // get current position
size_t buf_size = iss.rdbuf()->in_avail(); // get remaining characters
FILE* file = fmemopen(buf, buf_size, "r"); // open buffer memory as FILE*
fscanf(file, "%f", &j2); // finally!
iss.rdbuf()->pubseekoff(ftell(file), iss.cur, iss.in); // update input stream position from current FILE position.
std::cout << "j2 = " << j2 << std::endl;
// read again the C++ way
int j3; iss >> j3;
std::cout << "j3 = " << j3 << std::endl;
}
Well, you can get the file descriptor - I forget whether the method is fd() or getfd(). The implementations I've used provide such methods, but the language standard doesn't require them, I believe - the standard shouldn't care whether your platform uses fd's for files.
From that, you can use fdopen(fd, mode) to get a FILE*.
However, I think that the mechanisms the standard requires for synching STDIN/cin, STDOUT/cout and STDERR/cerr don't have to be visible to you. So if you're using both the fstream and FILE*, buffering may mess you up.
Also, if either the fstream OR the FILE closes, they'll probably close the underlying fd, so you need to make sure you flush BOTH before closing EITHER.
In a single-threaded POSIX application you can easily get the fd number in a portable way:
int fd = dup(0);
close(fd);
// POSIX requires the next opened file descriptor to be fd.
std::fstream file(...);
// now fd has been opened again and is owned by file
This method breaks in a multi-threaded application if this code races with other threads opening file descriptors.
yet another way to do this in Linux:
#include <stdio.h>
#include <cassert>
template<class STREAM>
struct STDIOAdapter
{
static FILE* yield(STREAM* stream)
{
assert(stream != NULL);
static cookie_io_functions_t Cookies =
{
.read = NULL,
.write = cookieWrite,
.seek = NULL,
.close = cookieClose
};
return fopencookie(stream, "w", Cookies);
}
ssize_t static cookieWrite(void* cookie,
const char* buf,
size_t size)
{
if(cookie == NULL)
return -1;
STREAM* writer = static_cast <STREAM*>(cookie);
writer->write(buf, size);
return size;
}
int static cookieClose(void* cookie)
{
return EOF;
}
}; // STDIOAdapter
Usage, for example:
#include <boost/iostreams/filtering_stream.hpp>
#include <boost/iostreams/filter/bzip2.hpp>
#include <boost/iostreams/device/file.hpp>
using namespace boost::iostreams;
int main()
{
filtering_ostream out;
out.push(boost::iostreams::bzip2_compressor());
out.push(file_sink("my_file.txt"));
FILE* fp = STDIOAdapter<filtering_ostream>::yield(&out);
assert(fp > 0);
fputs("Was up, Man", fp);
fflush (fp);
fclose(fp);
return 1;
}
There is a way to get file descriptor from fstream and then convert it to FILE* (via fdopen). Personally I don't see any need in FILE*, but with file descriptor you may do many interesting things such as redirecting (dup2).
Solution:
#define private public
#define protected public
#include <fstream>
#undef private
#undef protected
std::ifstream file("some file");
auto fno = file._M_filebuf._M_file.fd();
The last string works for libstdc++. If you are using some other library you will need to reverse-engineer it a bit.
This trick is dirty and will expose all private and public members of fstream. If you would like to use it in your production code I suggest you to create separate .cpp and .h with single function int getFdFromFstream(std::basic_ios<char>& fstr);. Header file must not include fstream.
I ran in that problem when I was faced with isatty() only working on a file descriptor.
In newer versions of the C++ standard library (at least since C++11), the solution proposed by alfC does not work anymore because that one class was changed to a new class.
The old method will still work if you use very old versions of the compiler. In newer version, you need to use std::basic_filebuf<>(). But that does not work with the standard I/O such as std::cout. For those, you need to use __gnu_cxx::stdio_sync_filebuf<>().
I have a functional example in my implementation of isatty() for C++ streams here. You should be able to lift off that one file and reuse it in your own project. In your case, though, you wanted the FILE* pointer, so just return that instead of the result of ::isatty(fileno(<of FILE*>)).
Here is a copy of the template function:
template<typename _CharT
, typename _Traits = std::char_traits<_CharT>>
bool isatty(std::basic_ios<_CharT, _Traits> const & s)
{
{ // cin, cout, cerr, and clog
typedef __gnu_cxx::stdio_sync_filebuf<_CharT, _Traits> io_sync_buffer_t;
io_sync_buffer_t * buffer(dynamic_cast<io_sync_buffer_t *>(s.rdbuf()));
if(buffer != nullptr)
{
return ::isatty(fileno(buffer->file()));
}
}
{ // modern versions
typedef std::basic_filebuf<_CharT, _Traits> file_buffer_t;
file_buffer_t * file_buffer(dynamic_cast<file_buffer_t *>(s.rdbuf()));
if(file_buffer != nullptr)
{
typedef detail::our_basic_filebuf<_CharT, _Traits> hack_buffer_t;
hack_buffer_t * buffer(static_cast<hack_buffer_t *>(file_buffer));
if(buffer != nullptr)
{
return ::isatty(fileno(buffer->file()));
}
}
}
{ // older versions
typedef __gnu_cxx::stdio_filebuf<_CharT, _Traits> io_buffer_t;
io_buffer_t * buffer(dynamic_cast<io_buffer_t *>(s.rdbuf()));
if(buffer != nullptr)
{
return ::isatty(fileno(buffer->file()));
}
}
return false;
}
Now, you should be asking: But what is that detail class our_basic_filebuf?!?
And that's a good question. The fact is that the _M_file pointer is protected and there is no file() (or fd()) in the std::basic_filebuf. For that reason, I created a shell class which has access to the protected fields and that way I can return the FILE* pointer.
template<typename _CharT
, typename _Traits = std::char_traits<_CharT>>
class our_basic_filebuf
: public std::basic_filebuf<_CharT, _Traits>
{
public:
std::__c_file * file() throw()
{
return this->_M_file.file();
}
};
This is somewhat ugly, but cleanest I could think off to gain access to the _M_file field.