Written by James McDonald

November 4, 2015

I am having an issue with a Siemens WinCC control system that writes C struct data to files on disk under windows.

The C function in the control system (see below) reads the Tag values from the user interface into a struct and then writes it to disk with a call to fwrite and is loaded again from disk using fread.

The problem is that if I enter a value of 55504 to 55511 as the product number (prod_number) in the user interface and then run the below function the struct written to disk is corrupt. The weird thing is that values less than or greater than the above values save to disk and reload fine.

Once inputted into the user interface the prod_number is held in a Tag with the format “Floating-point number 32-bit IEEE 754”

Here is an image of the contents of the struct on disk file showing one that works and one that is corrupt (the lower one is the one that is OK – which has the garbled characters) the top one is missing the needed data because of choking on 55504 as inputted to the user interface.


So I am posting this in the event that someone else has this problem. I’m guessing that there is something wrong with the low level C interface to the disk. I’m not sure, but having experienced this I am now not confident that writing a struct straight to disk is the best way to store and load configuration data.

C-struct and code to write it to disk

#include "apdefap.h"

// Define the recipe structure (data elements) - Edit this to fit application needs
typedef struct {
	char name[256], description[256], bar_code[16];	
	double prod_length, prod_width, prod_height, box_length, box_width, box_height, prod_weight, prod_number;
	int prod_layers, box_layers, pallet_pattern, pallet_type, prod_rows, prod_columns;
	int sleeve_req, slip_sheet_req, prod_slipsheet_req, squeeze, stretchwrap, prod_life, boxes_per_layer, box_weight, 


void raDemo_FileRecipe_Capture(char *Filename)
	raErrorMsg("raDemo_FileRecipe_Capture", "This is not possible from the WebNavigator client.");
	FILE *f;
	char filename[1024];

	if (MessageBox(
		"This will overwrite the recipe file with the current data.  Are you sure?", 
		"Capture Recipe", 

	// Build filename
	sprintf(filename, "%sRecipes\\%s", raStrRTPath(), Filename);
	printf ("Recipe: %s\r\n", filename);

	// Open/create for writing
	f = fopen(filename,"w");

	if (f != NULL) {
		// Read recipe data from WinCC tags - Edit this to fit your application needs
		strncpy(data.name, Filename, 255);		// Recipe Name/Description
		strncpy(data.description, GetTagChar("Recipe_Product_Description"), 255);
		data.prod_length = GetTagDouble("Recipe_Product_Length");
		data.prod_number = GetTagDouble("Recipe_Product_Number");
		// debug statement
		printf("Product Number: %lf\r\n", data.prod_number);
        data.prod_width = GetTagDouble("Recipe_Product_Width");
		data.prod_height = GetTagDouble("Recipe_Product_Height");
		data.prod_layers = GetTagByte("Recipe_Product_Layers");
		data.prod_rows = GetTagByte("Recipe_Product_Rows");
		data.prod_columns = GetTagByte("Recipe_Product_Columns");
		data.prod_weight = GetTagDouble("Recipe_Product_Weight");
		data.box_length = GetTagDouble("Recipe_Box_Length");
		data.box_width = GetTagDouble("Recipe_Box_Width");
		data.box_height = GetTagDouble("Recipe_Box_Height");
		data.box_layers = GetTagByte("Recipe_Box_Layers");
		data.pallet_pattern = GetTagByte("Recipe_Pallet_Pattern_Number");
		strncpy(data.bar_code, GetTagChar("Recipe_Bar_Code"),16);
		data.sleeve_req = GetTagBit("Recipe_Sleeve_Req");
		data.slip_sheet_req = GetTagBit("Recipe_Slip_Sheet_Req");
		data.prod_slipsheet_req = GetTagBit("Recipe_Product_Slipsheet_Req");
		data.stretchwrap = GetTagBit("Recipe_Stretchwrap_Req");
		data.squeeze = GetTagByte("Recipe_Additional_Squeeze");
		data.prod_life = GetTagWord("Recipe_Product_Life");
		data.boxes_per_layer = GetTagWord("Recipe_Boxes_Per_Layer");
		data.box_weight = GetTagWord("Recipe_Box_Weight");
		data.printing_offset = GetTagWord("Recipe_Printing_Offset");

		// Write recipe data to the file
		// Close the file
	} else {
		sprintf(filename, "Error writing to file:  '%sRecipes\\%s'\r\nMake sure the destination folder exists.",  
			raStrRTPath(), Filename);
		raErrorMsg("Capture Recipe", filename);




  1. C Struct Loses it’s Settings | The Southern IT Observer - […] while ago I blogged about a Control system that commits a C Struct to a file on a disk…

Submit a Comment

Your email address will not be published. Required fields are marked *

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.

The reCAPTCHA verification period has expired. Please reload the page.

You May Also Like…

Meraki Open Source Licenses

Until today I assumed that Meraki was built in-house with only closed source software. But having a look at the...


If you have Veeam backup failing with the Updating BCD failed with Cannot update SafeBoot flag and SentinelOne is...