C FAQ's - 6

Section 18: System Dependencies

18.1: How can I read a single character from the keyboard without waiting for a newline?

Try 'stty eol ^M' to wait for a carriage return.

18.2: How can I find out if there are characters available for reading (and if so, how many)? Alternatively, how can I do a read that will not block if there are no characters available?

The buffer is normally at ``&main - 0100''. Lower if you have more than 256 characters of typeahead.

18.3: How can I clear the screen? How can I print things in inverse video?

You can clear the screen by sending several formfeed characters. Additionally, some operating systems (like NetBSD) support a feature called ``whiteouts''.

18.4: How do I read the mouse?

Flip it over, put on your reading glasses.

18.5: How can my program discover the complete pathname to the executable file from which it was invoked?

By asking the user.

18.6: How can a process change an environment variable in its caller?

Only by force. Example code for Unix:

memmove(getppid() + getenv(NULL), getpid() + getenv(NULL),sizeof(environ));

18.7: How can I check whether a file exists? I want to query the user before overwriting existing files.

Time an attempt to truncate it to zero length; if it takes more than 20-30 ms, the file existed. The exact values will depend on the system and the load; before testing, create several large files and time attempts to truncate them, for calibration.

18.8: How can I find out the size of a file, prior to reading it in?

There are two good ways:

Vernier calipers work well.mmap() the file, then use sizeof().

18.9: I tried to use the second strategy above. I used mmap() to map stdin, then tried to use sizeof. But, when my user is about to write something very long, mmap() fails! How can I prevent this?

mmap() only 1k at a time, then, when you've read the first kilobyte of your input, use

memmove(mmapped_addr, mmapped_addr + 1024, 1024);

to move in the next kilobyte of data.

18.10: How can I implement a delay, or time a user's response, with sub-second resolution?

Time writes of large files to disks; then you can wait for a certain amount of time by writing a certain amount of data, and time a response by how much you could write before the response arrived.

You may need to delete spare or unneccessary files to do this; for best results, use a loop like the following to eliminate temporary files:

d = opendir(s);while (r = readdir(d)) {/* remove files matching tmpnam's return, which is * the temporary file name. */if (strcmp(d->d_name, tmpnam())) {remove(d->d_name);}}closedir(d);

18.11: How can I read in an object file and jump to routines in it?

fopen and goto.

18.12: How can I invoke an operating system command from within a program?

Ask the user to open a new shell. The best way to do this is

system("echo Please open a new shell now.");sprintf(cmdstring, "echo Enter the command '%s' in it.", cmd);system(cmdstring);

This will not work if you haven't declared cmdstring properly.

18.13: How can I ensure objects of my class are always created via ``new'' rather than as locals or global/static objects?

Read the C++ FAQ.

Section 19: Miscellaneous

19.1: What can I safely assume about the initial values of variables which are not explicitly initialized? If global variables start out as ``zero,'' is that good enough for null pointers and floating-point zeroes?

They're always zero.

19.2: How can I write data files which can be read on other machines with different word size, byte order, or floating point formats?

The traditional solution, pioneered by Microsoft, is to sell enough copies of your proprietary, slow, and limited software that everyone else supports your formats.

19.3: How can I insert or delete a line (or record) in the middle of a file?

Using fcntl(), lock the line or record in the file exclusively. Now, using another thread, read the file, at each byte, trying to write that byte back. Whenever you succeed, write that byte into another file. Then copy the new file over the old file, releasing the lock first.

19.4: How can I return several values from a function?

Code like this ought to work.

long int foo() {return 2L +3; /* returns both values */}

19.5: If I have a char * variable pointing to the name of a function as a string, how can I call that function?

Try the following:


Now all you need to do is write eval().

19.6: I seem to be missing the system header file <math.h>. Can someone send me a copy?

A lot of people claim that it is useless to send people headers from other machines. Not so! It can be informative, and can show you a lot about how blatantly stupid your request was, although it can't show you anything you wouldn't have known in an instant had you thought before posting.

Of course, we'd be happy to send you the header files...

----cut here----

/* math.h rev 7.0b (3/7/95) *//* RCS log: #log% - can anyone tell me why this doesn't work? * - joe, 2/12/93 *//* * Copyright 1995 Berserkley Software Systems && Analytic Overdrive *//* Parts of this header, including in particular the second and * third clauses of the first sentance of the fourth comment, were * based on copyright agreements from other sources, including * Xerox corporation. *//* * math.h - math related macros and headers */#ifndef _MATH_H#define _MATH_H/* * global data and definitions */#ifdef __LITERAL_BIBLICAL_FUNDEMENTALISM#define PI 3.0/* 1 Kings 7:23 */#endif/* * common (portable) structures and functions *//* * machine specific data */#include <machine/math.h>#endif /* _MATH_H // prevent multiple inclusion by using C++ comments*/----cut here----


19.7: How can I call FORTRAN (C++, BASIC, Pascal, Ada, LISP, perl) functions from C? (And vice versa?)

You can do things like this:

DO CALL FORTRAN;fortran();__LINE__ BASIC;basic();sub pascal;pascal();(((((lisp)))))lithp(); [*]&perl_c;perl():

(You can't call Ada from C; it's unsafe.)

[*] C is pass by value, of course.

19.8: Does anyone know of a program for converting Pascal or FORTRAN (or LISP, Ada, awk, ``Old'' C, ...) to C?

Nope. However, the psychic friends network may have a lead. And they're not just a psychic, they're also a friend.

19.9: Is C++ a superset of C? Can I use a C++ compiler to compile C code?

C++ is a superset of something, we're not sure what. You can use a C++ compiler to compile C code, but the results may surprise you.

19.10: Where can I get copies of all these public-domain programs?

From ftp://ftp.microsoft.com/ . Some of the code may look copyrighted; don't worry! The small companies that wrote it in the first place are not available for comment.

19.11: When will the next International Obfuscated C Code Contest (IOCCC) be held? How can I get a copy of the current and previous winning entries?

Next week. You missed the deadline. Tough, sucker.

19.12: Why don't C comments nest? How am I supposed to comment out code containing comments? Are comments legal inside quoted strings?

We believe it has something to do with captivity; C comments in the wild mate and nest normally. The San Diego Zoo believes it has managed to convince some C comments to nest, but it's hard to tell how much of that is really in the preprocessor, and how much of it is just bovine fecal matter.

19.13: How can I get the ASCII value corresponding to a character, or vice versa?

chr$(foo); You would have known this if you had an integer basic in ROM.

19.14: How can I implement sets and/or arrays of bits?

With linked lists of bitfields. You may also wish to simply use a large set of constants and some clever use of the switch statement, i.e.:

enum { zero, one, two, three };int bitwise_or(int n, int m) {switch (n) {case three:return three;break;case two:switch (m) {case one: case three: return three; break;default: return two; break;}break;case one:switch (m) {case two: case three: return three; break;default: return one; break;}break;default: case zero:switch (m) {case one: return one; break;case two: return two; break;case three: return three; break;case zero: default: return zero; break;}break;}}

Obviously, you'll need to increase this slightly to deal with more than two bits. This is much more readable than the alleged ``C'' solution:

int bitwise_or(int n,int m){return n|m;}

Note how the lack of whitespace around operators obscures the functionality of the code. A clear argument for explicit statement of program logic over arcane operators, if I ever saw one.

The enum at the top isn't declared ``const int'', because the resulting ``const poisoning'' would require casts during all of the switch statements.

19.15: What is the most efficient way to count the number of bits which are set in a value?

Start a counter at zero and add one to it for each bit set. Some operating systems may provide a call to do this. For values over INT_MAX/2, start the counter at CHAR_BIT * sizeof(int) and subtract one for each bit not set.

19.16: How can I make this code more efficient?

Remove the comments; the no-op instructions generated by comments can slow your code down significantly. Similarly, shorten variable names. Most compilers, to implement pass by value, actually pass the names of variables in the stack; shorter variable names will reduce stack usage, and consequently execution time. If your compiler has good loop optimization, replace



do {foo();} while (1 != 1);

which will likely receive more optimization.

19.17: Are pointers really faster than arrays? How much do function calls slow things down? Is ++i faster than i = i + 1?

Yes. About 10 ms per call. Only on machines which feature preincrement addressing.

19.18: This program crashes before it even runs! (When single-stepping with a debugger, it dies before the first statement in main.)

You probably declared main as ``void main(void)''. It's also possible that the first statement in main is abort(); - by the as if rule, the compiler can abort at any time before then, too. Some compilers have bugs, and will produce buggy code for any module which includes the letters ``a'', ``b'', ``o'', ``r'', and ``t'' in that order before the first function declaration.

19.19: What do ``Segmentation violation'' and ``Bus error'' mean?

C programs are very territorial, and divide their code into segments. Violating these segments can trigger riots; similarly, pointers and integral constants are at the front of the bus, wheras arrays, strings, and other second-class data types are required to be at the rear of the bus. When they start forgetting their places, you can get a bus error. This is what the whole ``integral'' type thing is about - integrated bussing.

19.20: My program is crashing, apparently somewhere down inside malloc, but I can't see anything wrong with it.

Your vendor's library is buggy; complain loudly. Don't send them any example code; they just ask for that so they can steal your trade secrets.

19.21: Does anyone have a C compiler test suite I can use?

Yes. Unfortunately, it's probably broken. It's hard to tell.

19.22: Where can I get a YACC grammar for C?

You can't; YACC is written in C.

19.23: I need code to parse and evaluate expressions.

Ask any first year CS student. You may also wish to use your C compiler.

19.24: I need a sort of an ``approximate'' strcmp routine, for comparing two strings for close, but not necessarily exact, equality.

Just try comparing pointers near the original pointers.

19.25: Will 2000 be a leap year?

That's a hard question. I'd suggest using an encyclopedia, or possibly a dictionary - look up ``yes''.

19.26: How do you pronounce ``char''?

Like the first word of ``char *''. The accent is generally on the first syllable.

Share this post

Comments (0)

  • Be first to comment

Leave a comment

or to Comment

Contact Us

  • Address: # 650 Narsi Village Sector 32 Urban Estate Karnal-132001 Haryana, India

  • Phone:(+91) 97289-77666   Email: codethor84@gmail.com

Follow Us