Solved

DOS v. Unix/Linux

Posted on 2003-12-04
9
373 Views
Last Modified: 2010-04-15
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!
0
Comment
Question by:GenericUserName
9 Comments
 
LVL 45

Accepted Solution

by:
Kdo earned 200 total points
Comment Utility


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!!!

Kent
0
 
LVL 45

Expert Comment

by:Kdo
Comment Utility

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

0
 
LVL 45

Expert Comment

by:sunnycoder
Comment Utility
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
0
 
LVL 2

Expert Comment

by:devoted2christ
Comment Utility
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...
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 11

Expert Comment

by:cup
Comment Utility
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.
0
 
LVL 45

Expert Comment

by:Kdo
Comment Utility

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".)  :)


Kent

0
 
LVL 2

Expert Comment

by:devoted2christ
Comment Utility
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...
0
 
LVL 45

Expert Comment

by:Kdo
Comment Utility

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!


Kent
0
 
LVL 1

Author Comment

by:GenericUserName
Comment Utility
Kent,

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!

David
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
This is a short and sweet, but (hopefully) to the point article. There seems to be some fundamental misunderstanding about the function prototype for the "main" function in C and C++, more specifically what type this function should return. I see so…
Video by: Grant
The goal of this video is to provide viewers with basic examples to understand and use nested-loops in the C programming language.
The goal of this video is to provide viewers with basic examples to understand opening and reading files in the C programming language.

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

15 Experts available now in Live!

Get 1:1 Help Now