• C

DOS v. Unix/Linux

Ok, so I've been programming C in Unix/Linux for awhile, on and off.  My main interest is file I/O, parsing, scanning, etc. However, I now have an assignment (not school related, so don't worry) to write a DOS-based parser in C (for a predefined file schema). However, since I've not written any DOS programs before (other than batch file or QBasic programs), I'm not exactly sure where to start...

I've always used "gcc -ansi -pedantic -Wall -O2" for my Unix work (along with splint/lint), so I don't think non-standard grammar or syntax would be an issue. However, I make a lot of I/O calls that would seem rather specific to Unix. My main question is what do I need to know that is different from Unix to DOS? Is I/O relatively the same (other than file system structure)? Does anyone have good links to DOS C tutorials, particularly with I/O? Is this a question better meant for the C++ section (please don't make me write C++!)? Am I being weird and not realizing that all I/O calls are the same?

I'm reading/writing regular text files, and binary files, so I need to know about both of them. If you could offer any assitance before I just start coding away without direction, I'd much appreciate it!
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kent OlsenDBACommented:

The good news is, most I/O is common to *nix and DOS.   :)

The bad news is, there are differences.     :(

Perhaps the biggest difference is that DOS differentiates between binary and text files.  When you open files in *nix, there's not a lot of difference between binary and text.  Many of the I/O routines simply don't care how you intend to use the file.  The routine is simply handling bytes.

But DOS does care.  One of the reasons is that DOS text files are CR/LF delimited.  (Yes, DOS requires TWO bytes to denote end-of-line.)  When files are opened in text mode, the I/O routines will automatically strip the extra character on a read-line operation (leaving the string exactly as it would look if it had been read on a unix system) and append the extra character on a write operation.  To the programmer, it looks very similar to write *nix code.

For the most part, I'd suggest that if you use open(), read(), write(), etc you won't see much difference.

However, when you open a file for use as a stream using fopen(), append a 'b' or 't' to the mode string to inform the I/O library whether the file is binary or text.  It will make most of the stream library very compatible with what you are used to.

fopen ("FileName.txt", "rt");   /*  Open the file FileName.txt for reading as text  */

fopen ("NewFile.dat", "wb");  /*  Open the file NewFile.dat for writing as binary  */

Good Luck!!!


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Kent OlsenDBACommented:

Apologies for not quite finishing the answer.  (The wife was ready for dinner.....)

open() also has mode flags that need to be utilized.

open ("FileName.txt", O_TEXT|O_RDONLY);  /*  Open the file FileName.txt for reading as text  */

open ("NewFile.dat", O_BINARY|O_WRONLY);  /*  Open the file NewFile.dat for writing as binary  */

Of course, all of the other flags (O_CREAT, O_APPEND, etc) can be used in combination as necessary.


Kent has said it all

Since you have been using gcc -ansi -pedantic -Wall -O2, you need not worry about the "standard" that I/O calls follow ... they are the same (and you do not have to turn to C++)

the only difference is in treatment of text and binary files ... a common mistake that a *nix programmer does is to open all files in the same fashion without caring for the type ... this on DOS can make you pull your hair out ...

I rememeber atleast 3-4 such questions (error due to opening file with wrong type on DOS) in my brief stay at EE ...

apart from that open,read,write,seek,close,fopen,fread,fwrite etc. all remain the same
Thriving as a woman in IT

The IT workforce is diversifying, but the gender gap in tech remains very real. Overcoming stereotypes, and the glass ceiling is important not only for individual women working in the field but for the industry as a whole. Here are eight things women in IT do to succeed.

Yeah, I loaded up Borland C++ compiler, set it on Ansi C, and realized I didn't have to change much at all! So this is better than I thought. Good notice about the binary/text deal, I'll have to pay special attention if/when I run into any problems.

Luckily, my current assignment gives me a file without any newline characters, so I should be fine there.

And what about the FILE * functions, such as mainly getc/putc? Do they still work the same way (provided I open it as text/binary correctly)? If I use the getc method, casting the things I get to the types I need, would it work correctly? Or does the binary/text deal affect character-by-character I/O as well?

I'm just glad I don't have to use C++ instead...
The one thing you have to watch out for when parsing in DOS is line terminators.  DOS tends to use \r\n whereas Unix uses \n.
Kent OlsenDBACommented:

Hi Generic/Devoted.

This is going off topic for a second, but it's pretty important here on the boards -- the membership agreement prohibits any individual from having multiple signons and it appears that you've posted to this thread as both GenericUserName and devoted2christ.  Since these two IDs were created in May and June, it's time to ask a moderator to delete one of them.

Back on topic.

If you're going to use one of Borland's compilers :) life just got easier.  (I'm a big Borland fan!)

There is a global variable _fmode that is the default open mode.  You can set the behavior anywhere in your program and all subsequent opens will result in the file being opened in your default mode unless you explicitly open it otherwise.

extern int _fmode;

int main()
  int InputHandle;
  int OutputHandle;

  _fmode = O_BINARY;                                                       /*  Set the default open mode to binary  */
  InputHandle = open ("MyFile.dat", O_READ);                      /*  Open for read in the default mode, BINARY  */
  OutputHandle = open ("NewFile.dat", O_WRITE|O_TEXT);  /*  Open for write explicitly setting TEXT mode  */

Oh, and if you're still at Georgia Tech, say "Hi" to Dr. Riley for me.  We go back a long ways.  (Well, back long enough that everyone just called him "George".)  :)


Yeah, I just noticed I had two names! I remember I created one at work for a co-worker, and it had automatically logged me in as that at work. As long as the co-worker doesn't need it anymore, I'll ask for its deletion... It confused me for a second. I never even noticed; I don't usually post from work...

That global variable definitely looks good. I have two header files depending on whether I want binary I/O or text I/O, so that will save me a bit of time by including it in that. And Borland is definitely treating me well; I've always just used Emacs, which is great, but I like the simplicity and functionality of that Borland IDE (it's the old DOS/Win95 IDE, running on XP in compatibility mode). I've been happy with the results, especially the way it handles/marks errors in code. Do you know if there exist any Windows/DOS-based tools like 'lint' or 'splint' on *nix? I just prefer not using compilers to debug; old habit.

And I think I remember going to a lecture from Dr. Riley my freshman year. I was Computer Engineering then, so I think that's who it would have been. I don't remember what it was about, unfortunately...
Kent OlsenDBACommented:

Can't help with the tools.

You should give the Borland debugger a try.  F6, F7, F8, and F9 are your friends.  :)   If the application gets too big for the IDE to debug, Turbo Debugger will run in stand-alone mode and get you about another 100K of memory.

F1 and CTL-F1 (or Alt-F1, I don't recall) are instant help.  F1 for help with the IDE, CTL-F1 for language help on the item under the cursor.

Also, the IDE is itself a 16-bit program.  Any single source file that you want to open in the editor must be under 65K!

GenericUserNameAuthor Commented:

Sorry, I've been out of town, but I appreciate your help! My program works great (it seems like DOS is a little bit more forgiving than *nix so far), so here are your points!

It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today

From novice to tech pro — start learning today.