In Dread Ink, the Grave Hand of Barry Schwarz Did Inscribe:
On Wed, 22 Apr 2009 22:38:48 -0700, Franken Sense
getline terminates properly if the input is too long but you do not
inform the user of the condition.
I'm counting on the line being less than 8192 characters, and I'm the user.
If the input did not fit in text, there will be no new line to
separate this output from the next one.
This output is only temporary. Once I really think I've shaken the bugs
out, I'll remove this.
tree_alloc can return NULL.
tree could be NULL.
dupstr can return NULL also.
tree->text could be NULL.
I'm counting on tree being NULL once. I think this addresses the
tree_alloc:
if( tree == NULL )
{
tree = tree_alloc();
if (tree_alloc != NULL)
{
tree->text = dupstr( pc );
tree->count = 1;
tree->left = tree->right = NULL;
}
I assume the NULL happens when dupstr can't malloc, but I don't see what I
can do about it.
If the string is less than 30 characters, you will double space your
output. If more, then single space.
I changed the format specifier to %s, and I think it looks better.
pc can never be NULL; I assume you meant pc2 here.
I think this looks right now:
char *dupstr( char *pc )
{
char *pc2;
pc2 = malloc( strlen(pc) + 1 );
if( pc2 )
{
strcpy( pc2, pc );
}
return pc2;
}
These parentheses are superfluous.
I just realized that this returns the length.
Thanks for your comments, Barry. Here's the latest version:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define text_length 8192
#define my_file "text42.txt"
int getline(FILE *, char *, int );
struct tnode *add_to_tree( struct tnode *, char * );
void print_tree( struct tnode * );
struct tnode *tree_alloc( void );
char *dupstr( char * );
struct tnode
{
char *text;
int count;
unsigned long lineNumber;
struct tnode *left;
struct tnode *right;
};
int main( void )
{
struct tnode *root_node;
char text[ text_length ];
FILE *fp;
int len;
unsigned long lineNumber = 0;
root_node = NULL;
if ((fp = fopen(my_file, "r")) == NULL )
{
fprintf(stderr, "can't open file\n");
exit(EXIT_FAILURE);
}
while((len = getline(fp, text, text_length)) > 0)
{
++ lineNumber;
printf("%lu, %s", lineNumber, text);
root_node = add_to_tree( root_node, text);
}
print_tree( root_node );
return 0;
}
/* adds the text onto the tree */
struct tnode *add_to_tree( struct tnode *tree, char *pc )
{
int match;
if( tree == NULL )
{
tree = tree_alloc();
if (tree_alloc != NULL)
{
tree->text = dupstr( pc );
tree->count = 1;
tree->left = tree->right = NULL;
}
}
else if( 0 == (match = strcmp( pc, tree->text )) )
{
++tree->count;
}
else if( match > 0 )
{
tree->right = add_to_tree( tree->right, pc );
}
else if( match < 0 )
{
tree->left = add_to_tree( tree->left, pc );
}
return tree;
}
/* prints the tree */
void print_tree( struct tnode *tree )
{
if ( tree != NULL)
{
print_tree(tree->left);
printf("%s -- %4d\n", tree->text, tree->count);
print_tree(tree->right);
}
}
/* allocate memory for a node */
struct tnode *tree_alloc( void )
{
return malloc( sizeof( struct tnode ) );
}
char *dupstr( char *pc )
{
char *pc2;
pc2 = malloc( strlen(pc) + 1 );
if( pc2 )
{
strcpy( pc2, pc );
}
return pc2;
}
/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
*p++ = c;
if (c == '\n')
*p++ = c;
*p = '\0';
return p - s;
}
// gcc arnold5.c -Wall -o out
I have at least one question here. As I was cleaning up getline, I
realized that I don't know how to space it because I don't know what's
going on.
Is this equivalent to the above:
/* getline: get line into s, return length */
int getline(FILE *fp, char *s, int lim)
{
char *p;
int c;
p = s;
while (--lim > 0 && (c = getc(fp)) != EOF && c != '\n')
{
*p++ = c;
}
if (c == '\n')
{
*p++ = c;
}
*p = '\0';
return p - s;
}
Eighty degrees and 18 holes of golf of today and a steak waiting for me in
the kitchen. Life is good.