Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!brl-adm!brl-smoke!smoke!moss@BRL.ARPA From: moss@BRL.ARPA (Gary S. Moss (SLCBR-VLD-V)) Newsgroups: net.unix-wizards Subject: Re: Help with tsearch (3C) in sysV Message-ID: <2440@brl-smoke.ARPA> Date: Mon, 21-Jul-86 11:30:48 EDT Article-I.D.: brl-smok.2440 Posted: Mon Jul 21 11:30:48 1986 Date-Received: Tue, 22-Jul-86 00:15:45 EDT Sender: news@brl-smoke.ARPA Lines: 71 Herman, I wrote my own tsearch(3C) before we got our system V sources, so I have an opinion of how it is supposed to work, even though I never tried it. You should not need to define a record type as this is supposed to be trans- parent to the application. That is why all pointers are cast to "char *" or "char **" when passed in to the library. Your use of key appears correct, assuming that your strcompar function knows how to order strings and returns the appropriate values. Your use of rootp does not seem correct; its hard to tell since you didn't declare it. Rootp should be declared as a variable (some kind of pointer), initialized to NULL, and its address should be passed in. Here is an example. #include extern char *malloc(), *tsearch(); char *rootp = NULL; char line[MAXLINE]; char *ptr, *datum; int strcompar(); while( fgets( line, MAXLINE, file ) ) { datum = malloc( strlen( line ) + 1 ); if( datum == NULL ) { (void) fprintf( stderr, "Malloc() no more core.\n" ); return 1; } (void) strcpy( datum, line ); ptr = tsearch( datum, &rootp, strcompar ); } The first time through the loop, rootp is NULL indicating to tsearch() that the tree is empty, and a NULL pointer will be returned indicating the same, while rootp's contents will be altered to contain the address of the datum (line) at the new root of the tree. On subsequent loops, the address of the datum (line) will be returned by tsearch. I assume that the datum is not copied into the tree structure, so you must allocate space for it and pass its address in, a simple test should confirm this. If you wish, you can store more complex data types: struct rec { int key; double xyz[3]; } node, *datum, *rootp = NULL, *ptr; int compar( datum1, datum2 ) char *datum1, *datum2; { return (struct rec *) datum1->key - (struct rec *) datum2->key; } ... while( fread( (char *) node, sizeof(struct rec), 1, stdin ) == 1 ) { datum = (struct rec *) malloc( sizeof(struct rec) ); if( datum == NULL ) { (void) fprintf( stderr, "Malloc() no more core.\n" ); return 1; } *datum = node; ptr = (struct rec *) tsearch( (char *) datum, (char **)&rootp, compar ); } ... Be careful when using twalk(), that you pass rootp, NOT ITS ADDRESS. Good luck, -moss