I tried to store several data an cant achieve it:

#include <iostream>
#include <string.h>
#include <stdlib.h.>
#include <stdio.h>
#include "estructura.h"

void guardar_cliente(cliente x)
      {
      FILE*f;
      f= fopen("data.txt", "w");
      fwrite(&x, sizeof(x), 1, f);
      fclose(f);
      }

I dont know whats wrong im using another cpp file and a header file as you might have noticed, but the text file doesnt appear, whats wrong with this code pleeease help!!! im using vista btw

Don't use the standard libraries with the .h extension, they are out-dated (pre-1998) and are only kept around for backward compatibility and I wouldn't expect them to be updated to work fully on newer implementations (OS).

Use the following headers instead:

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstdio>

And it is bad practice to use C functions in C++. Use the iostream library instead of those old C functions (fopen, fwrite, fclose). Replace your code with this C++ equivalent:

void guardar_cliente(cliente x)
{
  std::ofstream f("data.txt", std::ios_base::binary | std::ios_base::out);
  f.write((char*)&x, sizeof(x));
}

> but the text file doesnt appear, whats wrong with this code
1. You're writing binary data, not a text file. So if you try to look at it using say notepad, you'll see garbage.

2. You open the file for writing each time, so ALL previous writes are lost. Perhaps you meant to append?

3. If you're using 'write' of some sort to write a struct as binary data, then you CANNOT have any pointers or STL type objects in your struct.

struct foo {
   int *data;  // bad
   char *message; // bad
   std::string text; // bad
};

Anything like this, and you've just save the pointer, and none of the indirect data it references.

Don't use the standard libraries with the .h extension, they are out-dated (pre-1998) and are only kept around for backward compatibility

Technically they're deprecated, but realistically that's a bluff. Even if the standard committee smokes a huge doobie and removes the old C headers in their stoned haze, compiler vendors will collectively give them the finger.

I wouldn't expect them to be updated to work fully on newer implementations (OS).

How do you figure that? They're a part of the standard, so they're required to work "fully" on any conforming implementation.

Use the following headers instead:

Which does little more than wrap the other headers in namespace std[1], so your previous statements seem a little weak. ;) That's not to say that the new headers aren't desirable for consistency and avoiding name collisions. You're also future proofing in the amazingly unlikely case that the old headers are removed from the standard.

Socratic Questioning:

And it is bad practice to use C functions in C++.

Why?

Use the iostream library instead of those old C functions (fopen, fwrite, fclose). Replace your code with this C++ equivalent:

And what does the "C++ equivalent"[2] buy you? Actually, let's modify that question a bit. What does foo() enjoy that bar() does not (aside from claims of C++ "purity"):

void foo(const some_struct& x)
{
    ofstream f("data.txt", ios::out | ios::binary);

    if (f)
        f.write((char*)&x, sizeof x);
}
void bar(const some_struct& x)
{
    FILE *f = fopen("data.txt", "wb");

    if (f != NULL) {
        fwrite(&x, sizeof x, 1, f);
        fclose(f);
    }
}

[1] Using the "as-if" rule.
[2] Assuming that the conforming C++ code using the library inherited from C is somehow not C++.

@Narue:
If we were to write a holy book for Daniweb's code goddess, it would describe this moment as:

And the Narue descended from the heavens,
and with a might display of wit,
like lightning ripping the sky,
she smite down the arrogant man.
Mere mortals shall be humble before their Goddess, she said.

Now, let me humbly reply..

>>How do you figure that? [old headers not working]

I have seen them not working. On BCB6, old C file IO's don't work under Vista (I had this painful problem some years ago), while the C++ iostreams work fine.

>>They're a part of the standard, so they're required to work "fully" on any conforming implementation.

Yeah, and all compilers are _required_ to support exported templates too, but only one compiler does. All compilers and all implementations of the standard libraries are delinquent in one way or another.

>>Why? [is it bad practice to use C functions in C++]

Oh.. come on.. now you're just trying to tick me off. You don't want me to do an "Inverse Torvalds Rant", do you? First off, you could hardly argue that it is "better" to use C functions in C++ when there is an equivalent solution using C++ standard libraries, at best, the two are equal. There are a certain number of idioms and design patterns that are very desirable in C++, and I know that you know most of them, and benefit everyday from knowing how to use them well. The C++ standard libraries (not those inherited from C, of course) contain some of the best examples of the use of these idioms to make a robust implementation, with proper exception-safety and handling, with easy-to-use generic containers and algorithms, etc. etc. Not only do you get all these benefits almost for free when using C++ functionalities, but you also get acquainted with the design, the logic and the robustness of its interfaces. Aren't C++ libraries a better example to follow? Also, when implementing things on top of C++ functionalities, the good design patterns it has tend to trickle up through your own designs as well.

So, is it "bad practice" to use C functions in C++? Yeah. Unless you think, like Linus Torvalds, that C is a superior programming language than C++. That's not my opinion, but I'm a mere mortal.

>>Actually, let's modify that question a bit. What does foo() enjoy that bar() does not

Actually, let's modify your example a bit further. What does foo enjoy that bar does not? [rhetorical]

class foo {
  ofstream f;
  public:
    foo() : f("data.txt", ios::out | ios::binary) { };
    //..
    void write(const some_struct& x) {
      if(f)
        f.write((const char*)&x, sizeof(x));
    };
};

class bar {
  FILE* f;
  public:
    bar() : f(fopen("data.txt", "wb")) { };
    ~bar() { 
      if(f)
        fclose(f);
    };
    void write(const some_struct& x) const {
      if(f)
        fwrite((const char*)&x, sizeof(x), 1, f);
    };
};

I can see at least two things (without going into style or C++ "purity"). "foo" is not only easier, simpler and clearer to write (not needing destructor) but inherently better in the face of exceptions being thrown in the constructor, thanks to RAII, of course. Second thing, const-correctness cannot be propagated through opaque pointers, they basically strip off the cv-qualifiers of the containing object.

Don't get me wrong, if you like to use C functions over C++ functions, be my guest, but I'm gonna keep telling beginners that it is bad practice to use C functions in C++. (btw, "practice" in french means "training", I also think that it is bad "training" to use C functions in C++).


So, Narue, maybe I missed something, but I didn't see you answer the original question about fopen() not creating the file, as it should. Say all you want about my (blunt) declarations about deprecated headers and C functions, at least I tried to give a helpful tip to solve the problem.

@Narue:

Well, that's far from the mature and though provoking response I've come to expect from you. I'm sorry I wasted your time.

>>Well, that's far from the mature and though provoking response I've come to expect from you. I'm sorry I wasted your time.

I'm sorry you see it that way. For the most part, I agreed with you, only complemented with some caveats. It only turned ugly when replying to the insinuation that it is not "bad practice" to us C functions in C++.
Promoting or even defending the use of C functions or deprecated things in C++ does tend to make my blood boil. I do understand and accept people who say "I use them because I'm working on a legacy code-base", "I use them because I have used them for X amount of years and they are more familiar to me", "I use them because all my colleagues are mostly coming from C", or better (but unlikely) "I use them because I have strong evidence that they are faster than the C++ alternative". But implying that there is no gain in moving to more "pure" C++ functionalities, that's vitriol to me.

I frankly have no idea what you would have expected me to reply to that (and was quite surprise to see this coming from you). I could certainly not turn my reply into a thesis on "C++ coding paradigms and why they beat C like a rented mule", so I kept it superficial. But then, the example code you posted comparing C IO and C++ IO. That ticked me off bad, I really don't take it well when people build straw-men arguments against my point (call that immature if you like). If that was an attempt to trigger an honest discussion, it was poorly realised, you missed the "honesty" part.

Anyways, I don't want to start a flame-war on this subject (and neither do you, I get it) (even though it might disappoint m4ster_r0shi ;) ).


Let's hope the OP comes back with an update on getting his file IO to work.

This article has been dead for over six months. Start a new discussion instead.