From: CSBVAX::MRGATE!@KL.SRI.Com:leichter@venus.ycc.yale.edu@SMTP 18-SEP-1987 04:15 To: EVERHART Subj: re: 2 C questions Received: from venus.ycc.yale.edu by KL.SRI.COM with TCP; Thu 17 Sep 87 11:56:03-PDT Date: 17 Sep 87 14:55:00 EDT From: "Jerry Leichter" Subject: re: 2 C questions To: "steinberger" cc: info-vax@kl.sri.com Reply-To: "Jerry Leichter" Question 1: I wrote a short main routine ... to test a function. One of the inputs is an integer... and the next a filename.... [T]he scanf that reads the number apparently leaves a LF character in a buffer that is then read by the code that is expecting the filename.... Why does scanf leave a LF character, or am I misinterpreting what's going on? Are there solutions other than using a getchar() call? ... printf("\nEnter a string size: "); scanf("%d",&n_chars); /* clear NEWLINE char left after scanf */ i = getchar(); /* WHY DO I NEED THIS ? */ printf("\nEnter a file to use: "); for (i=0; (input_file[i] = getchar()) != '\n'; i++); input_file[i] = '\0'; You've been bitten by a very common Unix programming "gotcha'". The problem is that you are thinking of scanf() as operating on lines - a seemingly natural way to look at things, because after all you are typing one value per line. Unfortunately, that's NOT the way scanf() is actually defined; it reads streams of bytes, and attaches no special significance to the end of an input line - as far as it is concerned, '\n' is just another whitespace character. You've provided nothing to "swallow" that whitespace character, so it remains in the buffer, ready to screw up the next input request. There are two work-arounds. A direct, strange-looking, and not very good technique is to provide something to "swallow" the newline. Since a SPACE in the format specification matches zero or more whitespace characters in the input, you need merely change your scanf() call to: scanf("%d ",&n_chars); (Actually, scanf("%d\n",&n_chars); is equivalent and looks a bit better.) The big problem with this technique is that it will keep reading input until it sees a non-whitespace character (which it will unget()). This is fine for reading files, terrible for inter- active input. So, scratch the direct approach. The RIGHT way to solve this problem is to forget about scanf() entirely. You want line-at-a-time parsing, which scanf doesn't give you - but you can easily build it: Use gets() or fgets() to read a line, then use sscanf() to parse it. (In fact, my advice - it's not just mine, my Unix-oriented officemate agrees - is that you'll probably be happiest if you take your manual and ink out the entries for scanf() and fscanf(). Actually, he says he wouldn't be at all unhappy if sscanf() suddenly vanished at the same time....) Question 2: I am trying to read and write binary files similar to ones created by FORTRAN open statements (that produce sequential, unformatted, fixed recordsize files). Specifying "rb" in an fopen statement seems to be enough to access existing files (using an fread call). If I want to create a new binary file with fixed-length records, which if any, of the keywords on p 4-5 of the C RTL Ref Man are appropriate? Is "rfm=fix" enough? Do I need "mrs=size" as well, and if so, is size in units of bytes, or longwords (like Fortran)? Yes, you must specify "mrs=512" as well. (The size is in bytes.) You may also need to specify the carriage control attributes (as none, probably) - check a full directory listing of a FORTRAN file. Note: You can specify one setting per argument to open/fopen. That is: fopen("foo","w","rfm=fix","mrs=512"); /* Correct */ fopen("foo","w","rfm=fix,mrs=512"); /* **WRONG** */ While the documentation says this, it's easy to misunderstand. Also, is there any reason to use the chapter 4 open and read or write functions instead of the chapter 2 functions (fopen, fread and fwrite)? open/read/write may be somewhat faster; I have no idea if the difference would be noticeable. I'd probably use them for clarity - I use the Chapter 2 functions when I want their "added value". In using the Chapter 4 ones, I'm saying that I'm NOT thinking of the files as Unix-style byte streams. -- Jerry ------