[prog] learning c
Alice Moomlyn
alice_moomlyn at yahoo.com
Sat Mar 27 07:59:50 EST 2004
Hello Everybody.
I am teaching myself c and would like it if anybody
who has time would be able to look over what I've
written and give me some feedback.
At the moment I'm trying to get my head around strings
and pointers so I've written a little program that
reads in a string and reverses it (using two different
methods) and then prints it out again.
I don't really know what I'm doing so any and all
comments/suggestions/criticisms would be very helpful!
Sincere apologies for the formatting.
Blame yahoo.
.....................................................
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BUFFSIZE 20 /* size of initial buffer */
#define MAXBUFF 20 /* maximum number of buffers */
/* start function prototypes---------------------*/
/* returns a pointer to a string read from standard
input, of maximum length 20,971,500 characters.
This function uses malloc so it may fail if there
isn't
enough memory, in which case it will return a NULL
pointer.
The function will also return NULL if the input is
longer than 20,971,500 characters.
It is the responsibility of the programmer using the
function to free() the returned string when
finished.*/
char *alice_getstring();
/* searches through a string for the newline
character,
returns the number of characters searched if found,
or 0 if not found. */
int alice_endline(char *string, int size);
/* returns the length of the character string pointed
to by s, (including the NULL terminator) or 0 if s is
not properly NULL terminated
The characters which are valid for strings are asci
32-126 (inclusive) plus tab (ascii 9)
If the string contains any other characters, including
'\n' and '\r' it will return 0 */
int alice_length(char *s);
/* returns a new string which contains letters in the
reverse order of the original string. The function
uses malloc to allocate memory for the new string. If
malloc fails the function will return NULL
It is the responsibility of the programmer who uses
the function to free() the returned string after use.
*/
char *alice_reverse1(char* string, int size);
/* same as alice_reverse1 but uses pointer notation
instead of array notation */
char *alice_reverse2(char* string, int size);
/* end function prototypes-------------------------*/
int main(void)
{
char *s1, *s2, *s3;
puts("Enter a string of any length: ");
if ((s1 = alice_getstring()) == NULL)
{
puts("Out of memory!");
return -1;
};
puts("\nThis is the string you entered:");
puts(s1);
if ( (s2 = alice_reverse1( s1, alice_length(s1) ) )
== NULL)
{
puts("Out of memory!");
return -1;
};
puts("\nReversed using array notation:");
puts(s2);
if ( (s3 = alice_reverse2( s1, alice_length(s1) ) )
== NULL)
{
puts("Out of memory!");
return -1;
};
puts("\nReversed using pointer notation:");
puts(s3);
free(s1);
free(s2);
free(s3);
return 0;
}
char *alice_getstring()
{
/* start variable declarations ------------*/
int buffsize = BUFFSIZE; /* size of first buffer
*/
int totalbuff = 0; /* variable to keep track of
number of characters already
read */
int counter = 0; /* variable to keep track of
number of buffers used */
/* This variable will be True, only when an
'\n' has been read */
enum { FALSE, TRUE } finished = FALSE;
/* an array of pointers to character strings */
char *p[MAXBUFF];
int endline; /* stores number of position
actually used to store input
in the final buffer
(the rest will be garbage) */
int loopvar; /* used for looping over the
number of buffers */
char *result; /* will contain the complete
string */
/* end variable declarations ----------------*/
/* start 'read' loop ------------------------*/
/* Begins by reading into a buffer of size
BUFFSIZE.
If no newline encountered, creates a new buffer
of size 2*BUFFSIZE and reads into that. If still
no newline encountered, creates a buffer of size
4*buffsize and reads into that, etc..
Each new buffer is twice the size of the last
one, and the maximum number of buffers is
MAXBUFF
If malloc failes or all the buffers are filled,
returns NULL */
while ((finished == FALSE) && (counter < MAXBUFF))
{
/* malloc memory for next buffer */
if ( ( p[counter] = malloc(
buffsize*sizeof(char) ) ) == NULL )
{
/* out of memory - do some cleanup, then
return NULL */
loopvar = 0;
while (loopvar < counter)
free( p[loopvar] );
return NULL;
};
/* read into next buffer */
p[counter] = fgets( p[counter],
buffsize*sizeof(char), stdin );
/* check for newline character */
endline = (alice_endline(p[counter],buffsize));
if (endline == FALSE) /* still more input */
{
totalbuff += buffsize; /* keep track of
number
of characters read */
buffsize *= 2; /* double the size of
next buffer */
counter++; /* keep track of
number
of buffers used */
}
else /* end of input */
{
totalbuff += endline; /* the last buffer
will
probably not be full
*/
finished = TRUE; /* break out of 'read'
loop */
}
};
/* end 'read' loop
-----------------------------------------------------*/
/* start highly unlikely scenario that input more
than 20 million chars */
if (finished == FALSE)
{
/* cleanup then return NULL */
loopvar = 0;
while (loopvar < MAXBUFF)
free ( p[loopvar] );
return NULL;
};
/* end highly unlikely scenario
--------------------------------------*/
/* start 'combine' loop
---------------------------------------------*/
/* make us a buffer big enough to hold the entire
string */
if ( ( result = realloc( p[0],
totalbuff*sizeof(char) ) ) == NULL )
{
/* out of memory - do some cleanup, then return
NULL */
loopvar = 0;
while (loopvar <= counter)
free( p[loopvar] );
return NULL;
};
/* If the whole string fitted into the first buffer
then we're done */
if (counter == 0)
{
result[totalbuff] = '\0'; /* add NULL terminator
*/
return result;
};
/* otherwise contcatenate the remaining buffers
into one */
/* start from 1 because we already handled the
zeroth buffer */
loopvar = 1;
/* we need to know how big each buffer is */
buffsize = BUFFSIZE;
while (loopvar < counter)
{
/* calculate size of next buffer */
buffsize *= 2;
/* append next buffer to end of result string
*/
result = strncat(result, p[loopvar], buffsize);
/* free memory used by temporary buffer */
free(p[loopvar]);
/* get next buffer */
loopvar++;
}
/* the last buffer will probably not be full
so it needs to be handled specially */
result = strncat(result, p[loopvar], endline);
free(p[loopvar]);
/* end 'combine' loop
----------------------------------------------*/
result[totalbuff] = '\0'; /* Add NULL terminator
*/
return result;
}
/*
--------------------------------------------------------------------*/
int alice_endline(char *string, int size)
{
int counter = 0;
while (counter < size)
{
if (string[counter] == '\n')
return counter;
else
counter++;
};
return 0; /* newline not found */
}
/*
----------------------------------------------------------------------*/
int alice_length(char *s)
{
char *ptr = s;
int counter = 0;
while ((*ptr <= 126) && ((*ptr >= 32) || (*ptr ==
9)))
{
ptr++;
counter++;
}
if (*ptr == 0)
return counter;
else;
return 0;
}
/*
----------------------------------------------------------------------*/
char *alice_reverse1(char* string, int size)
{
char* result;
int i, j;
if ((result = malloc(size*sizeof(char))) == NULL)
{
printf("Out of memory!");
return NULL;
};
for (i=0, j=(size-2); i < (size-1); i++, j--)
{
result[i] = string[j];
};
result[size-1] = '\0';
return result;
}
/*
---------------------------------------------------------------------*/
char *alice_reverse2(char* string, int size)
{
char *result, *rptr, *sptr;
result = malloc(size*sizeof(char));
rptr = result;
sptr = string;
sptr += size - 2;
while (sptr >= string)
{
*rptr = *sptr;
rptr++;
sptr--;
};
rptr = '\0';
return result;
}
/*
----------------------------------------------------------------------*/
P.S If anybody knows how to instruct yahoo NOT to add
its own newline characters to cut-and-pasted text,
please let me know, or would I be better off sending
example code as an attatchment?
=====
"the only way to learn how to be clever is to say stupid things" - anon
__________________________________
Do you Yahoo!?
Yahoo! Finance Tax Center - File online. File on time.
http://taxes.yahoo.com/filing.html
More information about the Programming
mailing list