I make a lab in the university. There are structures whose data is entered from the keyboard, then written to the file using the fwrite() function. Until now, he worked only with fstream , and there were no problems. Here, too, it seems like I did everything correctly, but I get the device.txt file on the exhaust, and in it there are solid kryakozyabry. I collect from under g ++ Linux. The whole program is on the https://github.com/rotenbergwitalik/laba6.git

code with main:

 #include <iostream> #include <cstdio> #define DEVICE_NAME_LEN 30 #define MEASUREVALUE_NAME_LEN 30 using namespace std; struct powerSource { float voltage; float amperage; float periodicity; }; struct measuredValue { char measuredValueName[MEASUREVALUE_NAME_LEN]; float lowBorder; float highBorder; float inaccuracy; }; struct device { char deviceName[DEVICE_NAME_LEN];// float devicePrice; int guarantee; //in month struct powerSource devicePowerSource; struct measuredValue deviceMeasureValue; }; int main() { struct device labaDevice; cout<<"Write name of device: "; cin>>labaDevice.deviceName; cout<<"Write price of device in $: "; cin>>labaDevice.devicePrice; cout<<"Write guarantee in month: "; cin>>labaDevice.guarantee; cout<<"Write power source for device: "<<endl; cout<<"\tVoltage: "; cin>>labaDevice.devicePowerSource.voltage; cout<<"\tAmperage: "; cin>>labaDevice.devicePowerSource.amperage; cout<<"\tPeriodicity: "; cin>>labaDevice.devicePowerSource.periodicity; cout<<"Write measure value for device: "<<endl; cout<<"Write name of measure value: "; cin>>labaDevice.deviceMeasureValue.measuredValueName; cout<<"\tLow border: "; cin>>labaDevice.deviceMeasureValue.lowBorder; cout<<"\tHigh border: "; cin>>labaDevice.deviceMeasureValue.highBorder; cout<<"\tInaccuracy: "; cin>>labaDevice.deviceMeasureValue.inaccuracy; FILE* outFile; if ((outFile = fopen("device.txt", "wb")) == NULL) { cout<<"Con not open the file"<<endl; return 1; } fwrite(&labaDevice, sizeof(device), 1, outFile); fclose(outFile); return 0; } 

    3 answers 3

    I think that you just previously displayed the fields using the operator to output to the stream << , i.e. in text form. fwrite writes data in binary form as is. The wt mode changes one thing - processing \n . If you want to receive all data in text form, use fprintf - type, instead of

     outStream << "guarantee = " << labaDevice.guarantee << endl; 

    use

     fprintf(outFile,"guarantee = %d\n",labaDevice.guarantee); 

    But note that if later it will be necessary to read it, then it will also be necessary to read it textually. And if you use fwrite in binary mode, then you will immediately pull in the whole structure with one fread in the same binary mode ...

    • and if it doesn’t, you can use a piece of code on how to correctly apply fread () and fwrite () in my case. Or at least a reference to a good manual in order to understand. But it is not very clear about the binary mode. - V. Rotenberh
    • @ V.Rotenberh Yes, just fwrite - a record of everything that was said as it is in memory. Numbers - in their binary representation, etc. And you read it the same way - only with the fread function, into a prepared place (the same structure). Only the file must be open in binary mode (c "b" in the opening mode line) - so that it lies in the memory and goes to the file. - Harry
    • Wouldn't it be possible to write when writing with these functions anyway, to see the text in the file in a normal view? - V. Rotenberh
    • one
      @ V.Rotenberh only when writing normal lines with text. - Harry
    • thanks, seem to understand. - V. Rotenberh

    "Kokozyabry" depend on the browser with which you are watching this file. Most of them are trying to determine the encoding machine. But since the file is written not as a text file but binary, errors are quite possible. If under linux, then from the console you can see the same mc F3. After opening Alt + E and choose the one that you have is utf-8, for example. Yes, and it is better to switch to HEX - mode, so that the viewer does not try to interpret the values ​​from the float or int as text. :)

    By the way, keep in mind that if you have utf-8 encoding and you use non-ascii characters, for example, Russian, then the length of the string in bytes can increase by a factor of 3. So when entering a name from 10-15 characters, you can wipe the rest of the structure junk or grab a stack overflow. :)

    • Yes, the problem is as simple as a mop: binary data, numbers, are written as binary data. What other utf-8? What have they got to do with ... ... - Harry
    • 2
      The author writes: "but on the exhaust I get the file device.txt, and in it are solid kryakozyabry." So he opens it with some kind of text viewer or editor (file extension * .txt), which shows "kryakozyabry". Which is quite natural, since the file is not a text file but a binary one. As for utf-8, we look at the structures and see fields with the type char [...NAME_LEN] . Judging by the questions, the author is not very strong in encodings, so I warned him where there could be problems with overflow if using utf-8, because there is no verification in the code. - tonal
    • Before this same viewer, he opened the exact same file ... - Harry
    • This question is not. And according to the phrase "Until now, he worked only with fstream, and there were no problems." one can only guess what this "work" was. :) - tonal
    • In encodings it is not strong. Opened to all, to what hands reached out. But thanks harry figured out. - V. Rotenberh

    It is necessary to correct the line (opening a file in binary mode)

     if ((outFile = fopen("device.txt", "wb")) == NULL) { 

    on line:

     if ((outFile = fopen("device.txt", "wt")) == NULL) { 

    After that, you must manually display all the fields of the structure like this:

     fwrite("labaDevice.deviceName = ", sizeof("labaDevice.deviceName = "), 1, outFile); fwrite(labaDevice.deviceName, sizeof(labaDevice.deviceName), 1, outFile); 
    • one
      Well, what will a person get when outputting fwrite(labaDevice.guarantee, sizeof(labaDevice.guarantee),1,outFile); ? - Harry