Is there any way to create a memory buffer as a FILE*. In TiXml it can print the xml to a FILE* but i cant seem to make it print to a memory buffer.
There is a POSIX way to use memory as a FILE descriptor: fmemopen or open_memstream, depending on the semantics you want: Difference between fmemopen and open_memstream
I guess the proper answer is that by Kevin. But here is a hack to do it with FILE *. Note that if the buffer size (here 100000) is too small then you lose data, as it is written out when the buffer is flushed. Also, if the program calls fflush() you lose the data.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
FILE *f = fopen("/dev/null", "w");
int i;
int written = 0;
char *buf = malloc(100000);
setbuffer(f, buf, 100000);
for (i = 0; i < 1000; i++)
{
written += fprintf(f, "Number %d\n", i);
}
for (i = 0; i < written; i++) {
printf("%c", buf[i]);
}
}
fmemopen can create FILE from buffer, does it make any sense to you?
I wrote a simple example how i would create an in-memory FILE:
#include <unistd.h>
#include <stdio.h>
int main(){
int p[2]; pipe(p); FILE *f = fdopen( p[1], "w" );
if( !fork() ){
fprintf( f, "working" );
return 0;
}
fclose(f); close(p[1]);
char buff[100]; int len;
while( (len=read(p[0], buff, 100))>0 )
printf(" from child: '%*s'", len, buff );
puts("");
}
C++ basic_streambuf inheritance
In C++, you should avoid FILE* if you can.
Using only the C++ stdlib, it is possible to make a single interface that transparently uses file or memory IO.
This uses techniques mentioned at: Setting the internal buffer used by a standard stream (pubsetbuf)
#include <cassert>
#include <cstring>
#include <fstream>
#include <iostream>
#include <ostream>
#include <sstream>
/* This can write either to files or memory. */
void write(std::ostream& os) {
os << "abc";
}
template <typename char_type>
struct ostreambuf : public std::basic_streambuf<char_type, std::char_traits<char_type> > {
ostreambuf(char_type* buffer, std::streamsize bufferLength) {
this->setp(buffer, buffer + bufferLength);
}
};
int main() {
/* To memory, in our own externally supplied buffer. */
{
char c[3];
ostreambuf<char> buf(c, sizeof(c));
std::ostream s(&buf);
write(s);
assert(memcmp(c, "abc", sizeof(c)) == 0);
}
/* To memory, but in a hidden buffer. */
{
std::stringstream s;
write(s);
assert(s.str() == "abc");
}
/* To file. */
{
std::ofstream s("a.tmp");
write(s);
s.close();
}
/* I think this is implementation defined.
* pusetbuf calls basic_filebuf::setbuf(). */
{
char c[3];
std::ofstream s;
s.rdbuf()->pubsetbuf(c, sizeof c);
write(s);
s.close();
//assert(memcmp(c, "abc", sizeof(c)) == 0);
}
}
Unfortunately, it does not seem possible to interchange FILE* and fstream: Getting a FILE* from a std::fstream
You could use the CStr method of TiXMLPrinter which the documentation states:
The TiXmlPrinter is useful when you
need to:
Print to memory (especially in non-STL mode)
Control formatting (line endings, etc.)
https://github.com/Snaipe/fmem is a wrapper for different platform/version specific implementations of memory streams
It tries in sequence the following implementations:
open_memstream.
fopencookie, with growing dynamic buffer.
funopen, with growing dynamic buffer.
WinAPI temporary memory-backed file.
When no other mean is available, fmem falls back to tmpfile()
Related
I'm pretty new to C, and I'm not sure what is wrong with this piece of code I have written. It is supposed to open (or create if needed) a file using a name specified and in that file write a bunch of signs taken from the /dev/urandom file. I need a precise amount of elements each one of a specified length. I need to be able to later edit that created file, but I wanted to focus on creating this generator part first. It doesn't show any errors when compiling or when I try to execute it, but still nothing happens - the file still doesn't exist anywhere. What's wrong with it?
int main(){
void generate(char str[], int a, int b);
}
void generate(char str[], int a, int b){
int n=0;
char fname[128];
strcpy(fname,str);
strcpy(fname, ".txt");
FILE *myFile = fopen(fname, "w");
FILE *randomiser = fopen("/dev/urandom", "r");
char bufor[a];
size_t result = fread (bufor, b, a, randomiser);
size_t end = fwrite (bufor, b, a, myFile);
fclose(myFile);
fclose(randomiser);
}
#edit
change the tile as someone suggested and changed a code a bit since im still trying to work it out
I forgot to mention that the whole point of this function is for it to be called in terminal as for example ./program generate data 100 100.
Here is the exact solution you asked for
There you go. I use open instead of fopen, read a certain amount of char out of /dev/urandom then write it to fd2 (the file created),
Be carefull the size of the buffer, be careful The NULL (\0) terminate the string
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
int generate(char **av)
{
int fd1 = open("/dev/urandom", O_RDONLY);
int fd2 = open(av[1], O_CREAT | O_RDWR, S_IRWXU);
int size = atoi(av[2]);
int row = atoi(av[3]);
int i = -1;
int j = -1;
if (fd1 == -1 || fd2 == -1 || size <= 0 || row <= 0 )
return (1);
char buf[size];
while (++i < row-1)
{
read(fd1, buf, size);
buf[size -1] = '\0';
write(fd2, buf, size -1);
while (++j < size)
buf[j] = '\0';
}
close(fd1);
close(fd2);
return (0);
}
int main(int ac, char **av)
{
int s;
if (ac < 4)
return (1);
generate(av);
return (0);
}
for 10 * 100 char into file 'blabla' Use with :
$~> gcc prog.c -o program
$~> ./program blabla 100 10
Will create / open the file "blabla" read 100 from /dev/uramdom and wirte to blabla
To explain what you did wrong here look :
This is a declaration of a function
void generate(int i, char *a);
This is a call to a function
generate(25, "Blablabla");
sometime when you declare a function you also instanciate it aswell
int generate(int i, char *a)
{
Operation;
operation;
return (0);
}
Declaration, and instanciation are different, let's assume i wrote funtion generate under function main in the above code example, function main would not know what is "generate" but if you declare it before main just like this it works
void generate(int i, char *a);
Here's what I made out of your source code with minimal changes
#include <stdio.h>
void generate(char basename[], size_t size);
int main(void) {
generate("foobar", 42);
}
void generate(char basename[], size_t size) {
char fname[128];
sprintf(fname, "%s.txt", basename);
FILE *myFile = fopen(fname, "w");
FILE *randomiser = fopen("/dev/urandom", "r");
char bufor[size];
size_t result = fread(bufor, 1, size, randomiser);
fwrite(bufor, 1, result, myFile);
fclose(myFile);
fclose(randomiser);
}
The problem is that your program never calls the generate() function, as #fredrik pointed out in comments. This:
void generate(char str[], int a, int b);
is a function declaration, not a call. Although it is legal to put such a declaration inside a function, it is much more conventional to put it outside and preceding the function(s) that will be doing the calling. And in this case, you could avoid using a separate declaration at all by just moving the main() function to the end, after the definition of generate().
But that still doesn't get around the fact that you need to call the function if you want it to do anything. And to call it, you will need to provide arguments. For example,
generate("random_data", 10, 4);
From your description, you'll want to use arguments determined from evaluation of command-line parameters, but that aspect would be a separate question.
For example, If my program segaults, instead of gcc printing to the console "Segmentation Fault" can I have it print "Ya dun goofed"?
Segfaults are generally caused by dereferencing a garbage pointer. Therefore, while the literal answer to what you asked is that, as kaylum said, you can catch SIGSEGV in a signal handler, the better answer is that, before you use a pointer, you should ask yourself, “How do I know that this pointer is valid and that I am staying within the bounds of my array?"
If you don’t know that, your program has a bug. If you think you do, you can turn the assumption into an assertion which, since your pointer is valid, will always pass. For example:
void fill_array( unsigned fill_this_many,
size_t array_size,
int a[array_size] )
{
assert(a);
assert( array_size >= fill_this_many );
for ( unsigned i = 0; i < fill_this_many; ++i )
a[i] = f(i);
return;
}
You’ll now get a detailed message when you’re about to dereference a null pointer or write past the end of your array, which will contain more useful information for debugging than, "There was a segfault somewhere," and it might even save you from silent memory corruption too.
If you want to write your own message, you can define a wrapper such as:
#include <stdio.h>
#include <stdlib.h>
void fatal_error_helper( const char* file, int line, const char* restrict message )
{
fflush(stdout); // Don’t cross the streams!
fprintf( stderr, "\nError in %s, line %d: %s\n", file, line, message );
exit(EXIT_FAILURE);
}
#define fatal_error(message) fatal_error_helper( __FILE__, __LINE__, (message) )
int main(void)
{
int *big_array = calloc( 1073741824UL, sizeof(int) );
if (!big_array)
fatal_error("Not enough memory.");
return EXIT_SUCCESS;
}
And a contrived example of how to do bounds-checking at compile time, so as to fail gracefully if your constants change:
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#define LENGTH 14U
#define M 5U
int main(void)
{
char message[LENGTH] = "hello, world!";
static_assert( M < LENGTH, "Tried to capitalize more letters than the array can hold." );
for ( unsigned i = 0; i < M; ++i )
message[i] = toupper(message[i]);
printf( "%s\n", message );
return EXIT_SUCCESS;
}
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
void segv_handler(int sig)
{
(void)sig;
const char *msg = "Hello signal handler!";
size_t len = strlen(msg);
write(STDERR_FILENO, msg, len);
abort();
}
int main()
{
struct sigaction act;
act.sa_handler = segv_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGSEGV, &act, NULL);
int *nullint = 0;
*nullint = 4;
return 0;
}
EDIT: I tough code is pretty much explanation how to do it. Of course there is a lot details that needs to be taken into account when writing signal handlers.
Basic limitation is that signal handler can't access any variable/structure that isn't written to atomically because handler could be called between any two instructions in your program. That means no calls to heap memory management, buffered io like printf, etc.
More details what the code does can be found from man pages stdout, sigaction and write.
Could someone instruct me on how to print a single letter, for example "b" in C while using only the write function (not printf).
I'm pretty sure it uses
#include <unistd.h>
Could you also tell me how the write properties work? I don't really understand
int write( int handle, void *buffer, int nbyte );
Could some of you guys toss in a few C beginner tips as well?
I am using UNIX.
You have found your function, all you need now is to pass it proper parameters:
int handle = open("myfile.bin", O_WRONLY);
//... You need to check the result here
int count = write(handle, "b", 1); // Pass a single character
if (count == 1) {
printf("Success!");
}
I did indeed want to use stdout. How do I write a version to display the whole alphabet?
You could use a pre-defined constant for stdout. It is called STDOUT_FILENO.
If you would like to write out the whole alphabet, you could do it like this:
for (char c = 'A' ; c <= 'Z' ; c++) {
write(STDOUT_FILENO, &c, 1);
}
Demo.
Let's see the man page of write(), which says,
ssize_t write(int fd, const void *buf, size_t count);
Description
write() writes up to count bytes from the buffer pointed buf to the file referred to by the file descriptor fd.
As per your requirement, you need to pass an address of a buffer containing b to print to standard output.
Let's see some code along with, shall we?
#include <stdio.h>
#include <unistd.h>
int main(void) {
char b = 'b';
write(STDOUT_FILENO, &b, 1);
return 0;
}
Let me explain. Here, the STDOUT_FILENO is the file descriptior for standard output as defined in unistd.h, &b is the address of the buffer containing 'b' and the number of bytes is 1.
Also valid is:
#include <stdio.h>
#include <unistd.h>
int main(void) {
char b[1] = {'b'};
write(STDOUT_FILENO, b, 1);
return 0;
}
Or:
#include <stdio.h>
#include <unistd.h>
int main(void) {
char b[1] = "b";
write(STDOUT_FILENO, b, 1);
return 0;
}
I've been trying to use the SHA_256 functions in sha256.h on a FreeBSD 9.1 system but it seems to be corrupting memory space of my program causing all kinds of manic behavior. I wrote up a quick program to just to play with those functions and still am having problems.
In the example below, int i is changed when I call SHA256_Init(), as shown by the output from the printf() statements surrounding it.
This is what I get running the code.
$ ./miner "hello world"
i = 0
i = 32
0000000032 9010a9cf81ce2c28a642fd03ddf6da5790c65c30cd4a148c4257d3fe488bacc7
Why is this value changing to 32? Am I missing something? The code is below...
#include <sha256.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#define DIFFICULTY 0
int main(int argc, const char **argv) {
uint nonce, i, j;
SHA256_CTX ctx;
size_t arglen;
unsigned char digest[32];
char * data;
if(argc < 1) exit(1);
arglen = strlen(argv[1]);
data = malloc(arglen + 1);
char digestStr[65];
i = 0;
do {
nonce = i;
strncpy(data, argv[1], arglen + 1);
printf("i = %i\n", i);
SHA256_Init(&ctx);
printf("i = %i\n", i);
SHA256_Update(&ctx, data, arglen);
SHA256_Update(&ctx, (unsigned char *) &nonce, sizeof(nonce));
SHA256_Final(digest, &ctx);
SHA256_End(&ctx, digestStr);
printf("%010i\t%s\n", i, digestStr);
j = 0;
while(j < 32 && digest[j] == '\0') {
j++;
}
i++;
} while(j < DIFFICULTY);
free(data);
return 0;
}
I just had this exact same problem and solved it.
The issue is that your are including a different header in your code than the SHA2 library you linked into your application is using.
In my case the SHA256_CTX struct was a different size in the openSSL library. The openSSL library's struct was 8 bytes bigger than the struct length in the file.
The function SHA256_Init(&ctx) does a memset on the SHA256_CTX struct which then corrupts 8 extra random bytes after the struct. I say random because it will do different things in a release vs debug build because the optimizing compiler will move your variables around.
I have a segmentation fault...i'm not sure what's causing it. Also, when passing the member pname into the function get_names, am I doing this correctly, or is there a better way of doing this?
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str);
int main (void) {
int i;
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(i, &(*player[i].pname));
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int count, char *str) {
FILE *inp;
char status;
inp = fopen("teamnames.rtf", "r");
status = fscanf(inp, "%s", str);
if (status == EOF) {
count = MAX_PLAYRS;
}
}
With your code unchanged, I get a segmentation fault if the file can't be opened properly (i.e. it's unreadable due to permissions, or it simply does not exist).
Here's a modified version of you function get_names():
void get_names(int count, char *str)
{
FILE *inp;
inp = fopen("teamnames.rtf", "r");
if (inp == NULL) {
perror("Failed");
return;
}
fgets(str, MAX_NAME, inp);
fclose(inp);
}
This would still read the first name 16 times, but it would tell you why it didn't manage to open the file. To read the next name from the file (rather than repeatedly the first name), open (and close) the file in the main() function instead.
Also, you might as well call get_names() like so:
get_names(i, player[i].pname);
No need to do that &(*...) thing you're doing.
And, finally, I hope that the teamnames.rtf file is not actually an RTF file, but a simple text file with a name on each line.
The problem comes from this line:
get_names(i, &(*player[i].pname));
Understanding pointers and dereferencing is one of the biggest adjustments to learning C if you are switching from another language. You're doing it wrong, and I think you should seek out a tutorial on the subject. Try http://www.cplusplus.com/doc/tutorial/pointers/ as a starting point.
Get a debugger to tell you what is wrong. Compile the code with debugging enabled (see you man page for your compiler) and run something like this:
gdb a.out core
Then you should be able to see which line made the code core dump. You could use idb as well, if you have the intle compiler installed. This is, of course, on *nix. If you are talking windows, use the VS debugger.
In addition do NOT use fscanf as it is unsafe. Use fgets instead.
There are many strange things. First thing is, it seems like the names are in a file, but what you are doing is in every iteration of your for loop, you call get_names which opens the file again, that is goes to the beginning of the file and you read the same name over and over again.
That is if you closed the file. Since you haven't closed the file, the file is already open and you keep reopening it (which could be the cause of your problem)
Another thing is, how can
if (status == EOF) {
count = MAX_PLAYRS;
}
Give you the current count? Regardless of the count of the players in the file, you are just setting it to MAX_PLAYERS.
Another thing is that count is an input to the function that is not a pointer, so setting it does not change the value outside the function (which is what I assumed you wanted).
Here is how I would do it with minimum change to your code:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
void get_names (int count, char *str, FILE *inp);
int main (void) {
FILE *inp;
int i;
int count;
inp = fopen("teamnames.rtf", "r");
for (i = 0; i < MAX_PLAYRS; i++) {
get_names(&count, player[i].pname, inp);
printf("Player: %s\n", player[i].pname);
}
}
void get_names (int *count, char *str) {
char status;
status = fscanf(inp, "%s", str);
if (status == EOF) {
*count = MAX_PLAYRS;
}
}
Here is how I would do it more concisely:
#include <stdio.h>
#define MAX_NAME 20
#define MAX_PLAYRS 16
typedef struct {
char pname[MAX_NAME];
int runs;
char how_out;
} Team_t;
Team_t player[MAX_PLAYRS];
Team_t *player_ptr[MAX_PLAYRS];
int get_names (Team_t *team);
int main (void) {
get_names(player);
}
int get_names (Team_t *team) {
int i = 0;
FILE *inp;
inp = fopen("teamnames.rtf", "r");
while (i < MAX_PLAYRS && !feof(inp) {
fscanf(inp, "%s", team[i].pname);
printf("Player: %s\n", player[i].pname);
}
}
Note that the problems with fscanf, checking array boundaries etc are not the concern of this solution, but this rather gives you the idea of what to do not a code for you to copy-paste.