Q&A, Miscellanea

This week I'm mainly going to be answering any questions you may have: questions about the homework, calls used in the homework, c, Unix, etc. Other than that, I'll talk about the following useful miscellanea.

C String Functions

Since you are all used to using the string class, there are some things that you will expect to be easy to do with strings but aren't with C-strings (char*s). This is a list of some functions that you might want to look into (see man pages or a C reference to see how to use them). In parenthesis is the C++ equivalent.

strcpy is used to duplicate a string (=)
strcat is used to concatenate strings (+)
strcmp is used to test string equality (==, <=, >=)
strlen is used to find the length of a string (.size())

Note that when I say "equivalent", I mean that in a very rough sense. The biggest difference to remember is that C-string sizes are not dynamically adjusted, they are just arrays of characters, so you must always have enough memory allocated to do what you want. E.g. trying to append " world!" to a string containing "hello" will fail unless the string storing "hello" is an array of at least size 14 (don't forget you always need to leave room for the NULL character at the end!)

If you want to convert non-string values to string form, the easiest way is to use sprintf, which works exactly like printf except that you add a destination char* as the first argument, and the result will go there instead of stdout. So sprintf(s, "abc%i", 123) would fill s in with the string "abc123" (again, that's assuming you have allocated at least 7 characters for s).

Files: open, fopen, fdopen, fprintf, and fscanf

open (man -s 2 open) and fopen (man fopen) are basic commands for opening files, and although similar they are slightly different. fopen is commonly used for general read/writes, as it returns a file pointer, which can be passed to fprintf to print to a file. Here's a snippet of code showing how basic file I/O can work:

FILE *fout;
if ((fout=fopen("user.info","w"))==NULL) //check for successful fopen
   fprintf(stderr, "Cannot open %s\n", "user.info");
else {
   fprintf(fout, "Hello World!"); //write to a file
fclose(fout)

open, on the other hand, returns a file descriptor (int), which you will need to pass to the fcntl call. However, you can easily convert from a file descriptor to a file pointer using the fdopen call. I'm not sure at the moment how easy it is to go the other way, but I'll look into it.

Both open and fopen take flags to control behavior like read-only, write-only, append, create if it doesn't exist, etc. Unfortunately, the flags themselves are done very differently in the two commands; open uses bitwise or-ed constants (e.g. O_WRONLY | O_CREAT) whereas fopen uses strings (e.g. "w+"). All the flag are described in the man pages, but you'll only deal with a few in general use.

Now that you have a file open, you can fscanf and fprintf to read and write. Both work just like their non-f counterparts, except that the take an extra parameter at the beginning; a file pointer to the file. printf and scanf are just special cases, in fact, with stdout as their file pointer.

Don't forget to close/fclose your files when you are done with them!

Stuart Morgan, 2003