-3

Here is my code:

#include <stdio.h>
#include <iostream>
#include <conio.h>

char filename[100];
FILE *stream, *stream2;
char s[20];
struct date
{
    int day, month, year;
};
struct employee
{
    int ID;
    char name[100];
    date birthdate;
    char address[20];
    char rank[20];
    int money;
};

void main()
{
    errno_t err;
    // Open for read (will fail if file "crt_fopen_s.c" does not exist)

    // Open for write 
    err = fopen_s(&stream2, "C:/Users/Van/Desktop/LAALAL/fool.txt", "w+");
    if (err == 0)
    {
        employee nv;
        std::cout << "\nInput information of an employee:\n";
        std::cout << "\tInput ID : ";
        std::cin >> nv.ID;
        std::cin.sync();
        std::cout << "\tInput name : ";
        std::cin.clear();
        gets_s(s);
        gets_s(nv.name);
        std::cout << "\tInput birthdate (Day Month Year ) : ";
        std::cin >> nv.birthdate.day >> nv.birthdate.month >> nv.birthdate.year;

        std::cout << "\tInput address: ";
        std::cin.clear();
        gets_s(s);
        gets_s(nv.address);
        std::cout << "\tInput rank : ";
        std::cin.clear();
        gets_s(s);
        gets_s(nv.rank);
        std::cout << "\tMoney : ";
        std::cin >> nv.money;
        std::cin.sync();

        std::fwrite(&nv, sizeof(nv), 1, stream2);
        std::fclose(stream2);
    }
}

Well I don't have any problem with the code, but when I input my information, I cant read the output in the file. Here is the picture of my output:

enter image description here

What is my problem? Thanks in advance for your time!

Błażej Michalik
  • 4,474
  • 40
  • 55
dinhvan2804
  • 93
  • 14
  • 1
    What is your expected output? The data is saved in binary form. – πάντα ῥεῖ Jan 01 '16 at 14:21
  • try to use string instead of char type – Arash Hatami Jan 01 '16 at 14:32
  • @ArashHatami This would make the suspected problem even worse. – πάντα ῥεῖ Jan 01 '16 at 14:33
  • are you sure ?? i have no problem with using string in file programming @πάνταῥεῖ – Arash Hatami Jan 01 '16 at 14:35
  • @ArashHatami Did you ever use `write()` to save them to a file? – πάντα ῥεῖ Jan 01 '16 at 14:36
  • Use a debugger and examine your data before you call `fwrite()`. The data is likely there, it's just written out in binary form. You can try reading it back in with `fread()` to see. (I say "likely there" because you're not checking for any errors on any of your function calls...) – Andrew Henle Jan 01 '16 at 14:38
  • no, i used **<<** operator every time @πάνταῥεῖ – Arash Hatami Jan 01 '16 at 14:40
  • @ArashHatami *no, i used << operator every time*. No. He's referring to this line: `std::fwrite(&nv, sizeof(nv), 1, stream2);` That line writes binary data to your file. If you want to use a C-style `FILE` operation and want text in your file, you need to use `fprintf()` instead of `fwrite()` and format the data yourself. Or see the answer below that recommends using a C++ `ofstream`. – Andrew Henle Jan 01 '16 at 14:44

2 Answers2

1

You are using fwrite() function, which writes data to files as binary, not as text (ASCII). You should be using std::ofstream class from <fstream> (instead of FILE), together with << operator.

More info here: http://www.cplusplus.com/doc/tutorial/files/


Example code:

#include <iostream>
#include <fstream>
using namespace std;

struct some_struct{
    int some_int;
    char some_char;
};

int main () {
    struct some_struct x;
    x.some_int = 123123;
    x.some_char = 'x';

    //This is how you open the file.
    ofstream myfile; 
    myfile.open ("example.txt");

    //This is is how you write to it.
    myfile << "Integer: " << x.some_int << " Char: " << x.some_char;

    //This is how you close it.
    myfile.close();
    return 0;
}

Output inside the file example.txt:

Integer: 123123 Char: x
Błażej Michalik
  • 4,474
  • 40
  • 55
  • `std::ofstream::write()` would do exactly the same. – πάντα ῥεῖ Jan 01 '16 at 14:28
  • @πάντα ῥεῖ: That's why you don't use `write()`, you use << operators. – Błażej Michalik Jan 01 '16 at 14:29
  • @BłażejMichalik *@πάντα ῥεῖ: That's why you don't use `write()`, you use << operators.* The `<<` operator doesn't apply to a file accessed via a C `FILE` pointer that was opened with a C `fopen()` call. – Andrew Henle Jan 01 '16 at 14:35
  • @Andrew Henle: That's why I said he should use std::ofstream. More clarification comming soon. – Błażej Michalik Jan 01 '16 at 14:37
  • THanks guys. i understand now – dinhvan2804 Jan 02 '16 at 03:56
  • @dinhvan2804: note: if you wan't to be able to write structs to files like this: `myfile << somestruct << someotherstruct` you also need to implement `operator<<` for them. Read about it here: http://stackoverflow.com/questions/476272/how-to-properly-overload-the-operator-for-an-ostream . You just need to change `ostream` to `ofstream`. – Błażej Michalik Jan 02 '16 at 04:07
0

You can use fstream library to programming by operators like << or >>

#include <iostream>
#include <fstream>

using namespace std;
struct date
{
    int day, month, year;
};

struct employee
{
    int ID;
    char name[100];
    date birthdate;
    char address[20];
    char rank[20];
    int money;
};

int main()
{
    char ch;
    ofstream file("fool.txt");
    if (!file)
    {
        cout << ""Cannot open file, press any key to continue ...";
        cin.get();
        exit(0);
    }
    employee nv;
    cout << "\nInput information of an employee:\n";
    cout << "\tInput ID : ";
    cin >> nv.ID;
    cin.ignore();
    cout << "\tInput name : ";
    gets_s(nv.name);
    cout << "\tInput birthdate (Day Month Year) : ";
    cin >> nv.birthdate.day >> nv.birthdate.month >> nv.birthdate.year;
    cin.ignore();
    cout << "\tInput address: ";
    gets_s(nv.address);
    cout << "\tInput rank: ";
    gets_s(nv.rank);
    cout << "\tMoney: ";
    cin >> nv.money;
    cin.ignore();
    file << nv.ID << ' ' << nv.name << ' ' << nv.birthdate.day 
        << ' ' << nv.birthdate.month << ' ' << nv.birthdate.year 
        << ' ' << nv.address << ' ' << nv.rank << ' ' << nv.money << ' ';
    file.close();


    cout << "\nOutput From File : \n";
    ifstream file2("fool.txt");
    file2.get(ch);
    while (!file2.eof())
    {
        cout.put(ch);
        file2.get(ch);
    }
    file2.close();
    cout << "\nOutput Completed";
    cin.get();
}

and pay attention to these hints :

  1. Declare the usage of std namespace in your code first, so you can remove the std:: clauses.

    using namespace std;
    
  2. cin.clear() and cin.sync() are not necessary, just use cin.ignore() after input a integer type and before input a char type

    cin >> nv.ID;
    cin.ignore();
    gets_s(nv.name);
    

    see this post to understand it better

  3. you are collecting char s[20]; from input in some lines. Why?? remove it

  4. in this example and using operators for file programming ( << ) you should add a space character after writing each data to file for separate data

    file << nv.ID << ' ' << nv.name
    
  5. standard functions for input or print char type are gets() and puts(), but you use gets_s() that I think it's because of secure warning, you can disable this error, In this case, if you want your code to use another compiler it will not be a problem. You can only comment one line instead of change many lines

    #pragma warning(disable: 4996)
    
Community
  • 1
  • 1
Arash Hatami
  • 5,297
  • 5
  • 39
  • 59
  • thanks for your time. but if i remove char s[20], it skips my input and jump to next line . I don't really understand that problem but when i add char s[20], it works,. I use gets_s because VS 2015 don't allow me to use gets() – dinhvan2804 Jan 02 '16 at 03:55
  • If you read my hint number 2, I explained that problem. Use cin.ignore() to fix that @dinhvan2804 just try my code and you will see it's work without any problem. I test in VS2015 – Arash Hatami Jan 02 '16 at 04:00