How to convert a file stream to string in C? - c

I'm using a system function which writes the output information into a stream of file pointer.
func(FILE *__fp)
I need to use this information in my program rather than printing this out to a file. For that I thought of creating a tmpfile() and writing to it then reading back from it. But is there a better way to get this information?

There are OS-specific solutions to writing to a memory buffer instead of a file, like for example the POSIX fmemopen or open_memstream (both which should be very useful considering your linux tag).
You can also change the internal buffer to your own with setvbuf.
On an unrelated note: Symbols starting with a leading underscore and followed by another underscore (like for example your __fp argument) are reserved. Such symbols may only be used by "the implementation", i.e. the compiler and library.

Related

Why is there no dscanf()?

Why is there no dscanf function for reading from file descriptors?
We have fprintf, sprintf and dprintf for printing but for scanning there is only fscanf and sscanf.
It is not possible to write dscanf.
The scanf family requires that the stream is buffered, or else that it is capable of putting back a character that was read. POSIX file descriptors are neither.
Consider this stream
1234xyz
How would you scan a number off it? You cannot read it byte by byte and stop just before x. That would require clairvoyance. You also cannot read x and decide you don't need it, because you cannot put it back.
Because the printf and scanf family of functions is part of the C language, the functions handling file descriptors are not. Instead they are part of the operating system API (on POSIX platforms like Linux or OSX, other platforms emulate these system calls).
And the dprintf function is not a standard C function, it's an extension. From this printf (and family) manual page:
The dprintf() and vdprintf() functions were originally GNU extensions that were later standardized in POSIX.1-2008.
That there's no dscanf function is probably just an oversight from those who made the original dprintf extension.

string FILE stdio compatible?

Is there anything like a string file in stdio/string/stdlib ? I mean a special way to fopen a FILE stream, which actually directs the writes to an internal buffer and takes care of buffer allocation/reallocation ? After fclose, the text should be available as null-terminated char[] or similar.
I need to interface to legacy code that receives a FILE* as an argument and writes to it, and I'd prefer to avoid writing to a temporary disk file.
Other forms of storage could do instead of char[] (f.i. string), but a FILE* pointer must be available.
I am looking for an alternative to creating a temporary disk file.
fmemopen & open_memstream are in the POSIX 2008 standard, probably inspired by GNU libc string streams, and give in-memory FILE* streams.
See also this question quite similar to yours, and also that answer.
BTW, many operating systems have RAM based or virtual memory based filesystems (à la tmpfs)
If you are coding in C++11 (not in C) and perhaps for some earlier C++ standard you can of course use std::stringstream-s
So you could use open_memstream on Posix, and some other solution on Windows (just with #if _POSIX_C_SOURCE > 200809L per feature_test_macros(7) ...)
The C standard does not provide (yet) any in-memory FILE streams, so if you need them you have to code or use platform-specific functions.
Create the temporary file using CreateFile(... FILE_ATTRIBUTE_TEMPORARY, FILE_FLAG_DELETE_ON_CLOSE ...) and then convert the HANDLE to FILE*.
You said you didn't like a write to a temporary file, so these flags to CreateFile are a strong hint to Windows to keep the file in cache if possible. And if Windows would run of of RAM, even a char[] can end up in a swap file anyway.

pstatus_t no found in procfs.h (LINUX)

I am reading the /proc/PID/status file using my C program and I want to use the pstatus_t struct to directly read the values from the file into this struct. However, my compiler is showing that this file is not present in the procfs.h.
I have checked few examples on internet where they are using the same header file but in my case, it is not working.
When you say "reading /proc/PID/status", I'm assuming that you are running in userspace (as opposed to in the kernel). In this case, the pstatus_t structure is worthless to you. Most files under /proc, including status, are a text-formatted representation of the kernel data structures. There is no way to directly get the binary contents of a kernel pstatus_t structure.

Call a function or a program when using the C-function fopen

I have a situation in C where I would like to call a c-function when calling fopen. This means I would like to have a "virtual file" of some sort. When I use fopen on this "virtual file" I would like to call a function to produce the data in the file.
Is this possible?
Thanks!
There isn't a direct way to call a function to produce output. However, you can call another process using popen(), which may be sufficient for your needs.
This means I would like to have a "virtual file" of some sort. When I
use fopen on this "virtual file" I would like to call a function to
produce the data in the file.
To do that, you'd need to write your own file system. Lucky for you, other people have done the hard part: take a look at FUSE. For example, you could write a file system where the "files" are really RSS feeds. You could then use standard file calls to read the data form those feeds.
Now, whether you should take this approach is a different question. If you have control of the code that's reading the file, it'd probably be easier to just have it call the appropraite data-providing function than to require installing a custom file system.
In standard C that is not possible, AFAIK,
If you use a system with the GNU Glibc (such as GNU/Linux) you can have custom streams, notably thru fopencookie.
Notice that the standard C++ library also provides (its own variant of) streams, and you could have your own.
On GNU/Linux, the kernel enables you also to provide a file-system in user space with FUSE

MPFR, printf, decimal places, locales, file i/o problem

A user of my program has reported problems reading a settings file written by my program. I looked at the settings file in question and instead of decimal points using the period "." it uses commas ",".
I'm assuming this is to do with locales?
The file i/o is using fprintf and mpfr_out_str for file output and getline combined with atol, atof, mpfr_set_str, etc for file input.
What do I do here? Should I force my program to always use periods even if the machine's locale wants to use commas? If so, where do I start?
Edit: I've just noticed that this problem occurs when specifying the settings file to use on the command line instead of loading it via the GUI - would this indicate a problem on the OP's machine or in my code?
Do you call setlocale at all? If not, I would suggest either embedding the locale used to generate the file in the settings file or force all settings file I/O to use the C locale, via the previous suggestion of setlocale(LC_ALL, "C").
One other option is to use the locale specific formatting functions (suffixed with _l in MSVC) and create the C locale explicitly, via _create_locale(LC_ALL, "C").

Resources