Intractable fwrite problem in C! Please help! - Page 1
Forum section: electronics / projects

author: PauloConstantino
author_rank: Regular Contributor
timestamp: May 30, 2017, 11:38:27 am
content: Hello. I've been having the most non sense problem ever in a C program.This program is a simple compiler that compiles a sequence of 0's and 1's and creates a binary file that contains these sequences.An example of what it compiles is this:0x19: 00001010;It reads the 0x19, and records it. It's the instruction code. Then it starts reading the sequence of 4 blocks of 0's and 1's.It saves these into arrays, and then uses fwrite to write the sequences to a binary file. The dilema is that the array itself is correct, but when the binary file is created the error occurs. The array has all the correct elements in order. I've tried writing one char at a time with a loop rather than writing the whole array at once with fwrite, but the same happens.My problem is that the function writes the binary file correctly up to a point, but it writes the last bytes incorrectly. It puts a 0D in front of the numbers it is supposed to write. I have no idea why this is happening and I been trying to solve this for days now.The corresponding line in the binary file is: 0D 0AAs you can see there's a 0D in front of 0A. That should not be there at all.I don't know if fwrite is making a confusion and writing an integer rather than a char to the file at that point. All my variables are unsigned chars, and I declare them as chars in fwrite.Can anyone please shed me a light on what might be happening?My code is a bit too complex to post here. It's an interpreter to interpret the text and write the bin file.Thank you a lot if you can help

author: amyk
author_rank: Super Contributor
timestamp: May 30, 2017, 11:53:17 am
content: Open file in binary mode. You are seeing consequence of using regular ("text") mode and newline translation.https://stackoverflow.com/questions/229924/difference-between-files-writen-in-binary-and-text-mode

author: PauloConstantino
author_rank: Regular Contributor
timestamp: May 30, 2017, 11:57:37 am
content: You are spot on. I had just found the problem a while ago! I was using w+ rather than w+b. Been struggling for days with this trying to find what it could possibly be !!!Thank you anyway. You would have saved me anyway. I REALLY appreciate it.!!!!!!!!!!!!!!!!!!!!

author: Mechatrommer
author_rank: Super Contributor
timestamp: May 30, 2017, 12:01:13 pm
content: 0D0A is windows text format for line feed, carriage return (0D) is required upfront "\r\n". in linux, only line feed (0A) is required "\n"...

author: PauloConstantino
author_rank: Regular Contributor
timestamp: May 30, 2017, 12:10:14 pm
content: Well the 0A was expected. It was what was compiled. The problem was the 0D which was being added in front of it.... Sometimes it also added 00 00. and sometimes 0D 00 00.

author: brucehoult
author_rank: Super Contributor
timestamp: May 30, 2017, 03:34:03 pm
content: Quote from: PauloConstantino on May 30, 2017, 11:38:27 amahahahahaThis is what you get for trying to write programs on Windows/DOS instead of a programmer's machine running some kind of Un*x (Linux, OSX, BSD, blah blah blah).As other have said, you need binary mode.Everything except Microsoft (ok, or RSTS/E or VMS on ancient DEC hardware) *only* has binary mode.

author: helius
author_rank: Super Contributor
timestamp: May 30, 2017, 03:49:05 pm
content: Quote from: brucehoult on May 30, 2017, 03:34:03 pm... until it connects to the internet and issues an HTTP request or sends a SMTP message. All the internet protocols require CR/LF because that was the original way lines were formatted before Unix changed it.

author: brucehoult
author_rank: Super Contributor
timestamp: May 30, 2017, 04:03:52 pm
content: Quote from: helius on May 30, 2017, 03:49:05 pmThat's ok because you just explicitly code "HELO\r\n" or whatever and everyone is happy.The other fun thing is *reading* a file, and having everything grind to a halt because there's an 0x1A byte in your binary data. Or, possibly, 0x00.

author: Zero999
author_rank: Super Contributor
timestamp: May 30, 2017, 05:56:12 pm
content: Quote from: helius on May 30, 2017, 03:49:05 pmYes, it sounds plausible that UNIX is the OS which is 'wrong' or messed up here. Teletype machines and line printers need a CR/LF to be sent to start a new line too. If you only sent a LF then then it would scroll down one line and continue printing in the same position but one line down the page. Sending "X/LF X/LF X/LF" would result in a diagonal line of X's on the page.

author: helius
author_rank: Super Contributor
timestamp: May 30, 2017, 06:04:24 pm
content: I said it changed the convention, not that it's necessarily wrong! Having a single symbol represent a new line is much nicer for a range of reasons. It happens not to be the same as the standard practice that evolved in the 1960s (based on devices like teletypes) and was embedded in the internet protocols from the very beginning until today.Only a few years after the arpanet project began, CRT terminals were widespread that could just as easily use a single symbol line separator. The fact that we now have CR/LF for all the internet protocols could be viewed as an unhappy accident.

author: free_electron
author_rank: Super Contributor
timestamp: May 30, 2017, 07:02:40 pm
content: Quote from: brucehoult on May 30, 2017, 03:34:03 pmnOPE. UNIX HAS IT WRONG.CR (0X10) Is just that : carriage return. move the print head to beginning of line .LF (0x13) is Line Feed : move to next line.if you just keep sending one of them you either get all output overwriting the same line orCode:textthatlookslikethisso you do need a CR LF pair. to move to beginning of next line.

author: brucehoult
author_rank: Super Contributor
timestamp: May 30, 2017, 08:33:15 pm
content: Quote from: free_electron on May 30, 2017, 07:02:40 pmDon't forget to put a few NULs after that LF, to give the print head time to get back to the left side, sepending on how long the previous line was.OR, we could forget about the foibles of a 1950s teletype and just use an abstract interface for end of line and let each device driver implement it in the most appropriate way.The number of times you actually want to drop to the next line and continue printing from the same character position is basically zero. On the other hand, it used to be reasonably common to overprint things to make bold type. So it makes some kind of sense at least to have LF go to the start of the next line, and CR go to the start of the same line. In that case LF can be the normal line separator, but extra CRs along with it, either before or after, don't hurt anything. drawing diagonal lines. But only in one direction unless you put in a few backspaces. In which case you're probably going to want to have reverse-LF available as well.

author: Mechatrommer
author_rank: Super Contributor
timestamp: May 30, 2017, 08:57:02 pm
content: Quote from: brucehoult on May 30, 2017, 08:33:15 pmno worry modern teletypes have enough cache to store commands and wait the sensor to detect head's position. for a simple CR can get into OS warcraftlets be fair, CR has been misused in simple text format, without it txt files can be a bit smaller in bytes size, this put linux txt format some advantage. what i hate most is i have to translate linux txt to win txt everytime i want to view it in my xp notepad

author: free_electron
author_rank: Super Contributor
timestamp: May 30, 2017, 09:56:05 pm
content: Quote from: brucehoult on May 30, 2017, 08:33:15 pmque : unix and 'c' ... both old muckery on obsolete hardware. ( both were designed on teletypes... )CR and LF are incorporated in the ASCII standard ... you can't willly nilly go redefining that... Cr and LF are for printer/screen controlin 'c' syntax' :CR : \RLF : \Nnew line : \R\N

author: helius
author_rank: Super Contributor
timestamp: May 30, 2017, 10:11:48 pm
content: Quote from: free_electron on May 30, 2017, 09:56:05 pmSo are the other 30 defined control codes. Do you feel a pang that Unit Separator or End Of Medium are no longer recognized, too?

author: DBecker
author_rank: Frequent Contributor
timestamp: May 30, 2017, 11:14:12 pm
content: I find it amusing that this line of argument was dead and buried when I started using Unix... 35 years ago. It was the role of the tty driver to translate from the control symbol the to the output character.A C implementation was free to select what '\n' was stored as, at the cost of doing extra work in the library to match the underlying implementation. C and Unix were developed simultaneously, so they avoided making implementation choices that resulted in extra work. MSDOS had the fortune of years of experience, but still chose poorly (and stuck with their bad decision with religious fervor).

author: Mechatrommer
author_rank: Super Contributor
timestamp: May 30, 2017, 11:28:27 pm
content: Quote from: helius on May 30, 2017, 10:11:48 pmwell you dont take it seriously when a sharp hardware guy went nuts on some computing standards, most probably due to past experience trauma on some other specific OS. we all went through this kind of experience at some point in our life, at some other aspects in one way or another.

author: Fungus
author_rank: Super Contributor
timestamp: May 31, 2017, 09:24:33 am
content: Writing CRLF in text files is one of the most boneheaded decisions ever taken in computing history.It's caused decades of bugs and extra, unnecessary code (and it's not finished yet!)There was never a time where the printer driver couldn't be configured to send CRLF when the hardware required it. Some printers even had switches to select what they received.nb. Thecorrectcharacter to use to start a new line is LF. Therearelegitimate cases when you would want to send a CR without a LF (mostly on CRTs, eg. for a progress counter where you want to overwrite the current line). I can't think of a reason you'd want to send LF without a CR./rant

author: helius
author_rank: Super Contributor
timestamp: May 31, 2017, 03:17:10 pm
content: By the time terminals evolved beyond the "glass TTY" stage to fully-addressable displays (before the 1980s), they had large command sets to output characters in any desired pattern, along with multiple fonts, text styles, and even graphics, in a standard format over the ASCII serial port. No control codes were used for these features except ESC: the older meanings were already obsolete. Many of their features are not even supported in today's terminal emulators (like double height or width characters). This was all 40 years ago.