As the comments say, fread reads bytes in your file without any interpretation. The clients.txt file consists of 50 characters, 16 in the first line, plus 14 in the second, plus 18 in the third line, plus two newlines. (Your .txt client does not contain a new line after the third line, as you will see soon.) The new line character is one byte \n on UNIX or Mac OS X computers, but (possibly) two bytes \r\n on Windows machines - hence the 50 or 51 characters. Here is a sequence of ASCII bytes in hexadecimal format:
3130 3020 4a6f 6e65 7320 3536 342e 3930 100 Jones 564.90 0a32 3030 2052 6974 6120 3534 2e32 330a \n200 Rita 54.23\n 3330 3020 5269 6368 6172 6420 2d34 352e 300 Richard -45. 3030 00
Your fread statement copies these bytes without any interpretation directly into your rec1 data rec1 . This structure begins with int account; which says to interpret the first four bytes as int . As noted in one comment, you run your program on a machine with small names (most likely on an Intel machine), so the low byte is the first and most significant byte - the fourth. So your fread said to interpret the four-character ASCII sequence "100 " as a four-byte integer 0x20303031 , which is the decimal value of 540028977 . The next member of your structure is char name[100]; , which means that the next 100 bytes of data in rec1 will be name . But fread told to read sizeof(rec1)=112 bytes (4 bytes, 100 bytes, 8 bytes). Since your file is only 50 (or 52) characters, fread can only fill as many bytes of rec1 . The return value of fread , if you had not canceled it, would tell you that the reading has ceased to exceed the number of bytes requested by you. Since you get into EOF, the feof call breaks out of the loop after this first pass, consuming the whole file in one gulp.
All your output was made by the first and only call to fprintf . The number 540028977 and the following space were created by the argument "%d " and rec1.account . The next bit is only partially defined, and you're in luck: the specifier "%s" and the corresponding argument rec1.name will print the following characters as ASCII until the byte \0 is found. Thus, the output will begin with the remaining characters 50-4 (or 52-4 ) of your file - including two lines of a new line - and possibly continue forever, since your file does not have (t227) bytes (or any text file), which means that after printing the last character of your file, what you see means that all the garbage occurred in the automatic variable rec1 when your program started. (Such an unintended conclusion is similar to the famous OpenSSL heart attack bug.) You are lucky that the garbage turned on the \0 byte after only a few dozen characters. Note that printf does not know that rec1.name declared as soon as a 100-byte array - it received only a pointer to the beginning of name - you should have guaranteed that rec1.name contains the trailing byte \0 , and you did not.
We can say a little more. The number -9.2559631349317831e61 (which is pretty ugly in the "%f" format) is the value of rec1.balance . The 8 bytes for this double value on an IEEE 754 machine (for example, Intel and all modern computers) are in hexadecimal format 0xcccccccccccccccc . Sixty-four distinctive characters ╠ appear on the output "%s" corresponding to rec1.name , while only 100-46 = 54 characters remain out of 100, so your output "%s" ended at the end of rec1.name , and includes rec1.balance into the transaction, and we find out that your terminal program interpreted the non-ASCII 0xcc character as ╠ . There are many ways to interpret bytes larger than 127 (0x7f); in Latin-1 this would be, for example, Ì . The graphic symbol ╠ is a representation of the 0xcc (204) byte in the ancient MS-DOS character set, the code page of Windows 437. Not only do you work on an Intel machine, but also on a Windows machine (of course, basically a Probable opportunity to start with).
This answers your first two questions. I'm not sure I understand your third question. I hope the "flaws" are obvious.
As for how to fix this, there is no easy enough way to read and interpret a text file using fread . To do this, you will need to duplicate most of the code in the libc fscanf function. The only sensible way is to use fwrite first to create the binary; then fread will work naturally to read it. Thus, there should be two programs: one for writing the clients.bin binary file, and one for reading. Of course, this does not solve the problem of where the data for the first program should come first. This can happen when reading clients.txt using fscanf . Or it can be included in the source code of the fwrite program, for example, by initializing the struct rec array as follows:
struct rec recs[] = {{100, "Jones", 564.90}, {200, "Rita", 54.23}, {300, "Richard", -45.00}};
Or it can come from reading a MySQL database or ... One place that is unlikely to occur is in a binary (easy) readable by fread .