Part 2 :
@ledow, et al
this is a ANSI C program that is portable so you can compile it if you wish
Code:
//re-testing parse_text for WATT
#include <stdio.h>
#include <string.h>
// original design setting:
#define PARSE_SIZE_LIMIT 81
short int string_parser(char *, char *, char, short int);//TEXT_PARSER
short int kfgets(char *);//KFGETS
short int ynreturn(void);//yes/no option
int main (void)
{
char target[PARSE_SIZE_LIMIT]; target[0] = '\0';
char worda[PARSE_SIZE_LIMIT]; worda[0] = '\0';
char uword[PARSE_SIZE_LIMIT]; uword[0] = '\0';
short int count,countb,x,y;
do
{
do
{
printf("\n#>");
kfgets(target);
count = string_parser(target,worda,'#',-1);
if(count == 0) { printf("you must enter something using \'#\'\n"); }
} while (count == 0);
string_parser(target,worda,'#',0);
printf("you entered : %s\n",worda);
//count # parts
printf("found %d parts by \'#\'\n\n",count);
for(x = 1;x <= count;x++)
{
string_parser(worda,uword,'#',x);
printf("part#%d : %s\n",x,uword);
}
//count spaced parts
count = string_parser(worda,uword,' ',-1);
printf("found %d parts by \' \'\n\n",count);
for(x = 1;x <= count;x++)
{
string_parser(worda,uword,' ',x);
printf("part#%d : %s\n",x,uword);
}
printf("\ntest again (y/n)?");
} while((ynreturn()) == 1);
return 0;
}
short int string_parser(char *userstring, char *target, char magic, short int word)
{
//subject must be static
static char subject[PARSE_SIZE_LIMIT];//stores 80 chars +1 for the null character
char *w = &magic;//assign the address of magic to w
char a = 0,b = 0,c = 0,x = 0,z = 0;//temp variables
short int length = 0,orig = 0;// get the length of the string
short int offset = 0,y = 1;//segment control
char *p;//used for assigning pointer address returned by strtok()
//** format subject array of 'natural' garbage **
for (x = 0;x < PARSE_SIZE_LIMIT; x++) { subject[x] = ' '; }
x = 0;
orig = strlen(userstring);//get size length target array
//offset the copy of the userstring by 1 if the first character is not magic
//if(userstring[0] != magic)
//{
//printf("offset detected\r\n");//temp
//offset = 1;
//subject[0] = magic;
//}
//copy and reformat the userstring into, 0 - PARSE_SIZE_LIMIT ; format.
//for lines larger or equal than the size limit....
if (orig >= (PARSE_SIZE_LIMIT - 1))
{
for (x = 0; x <= (PARSE_SIZE_LIMIT - 1); x++)
{ subject[x] = userstring[x]; }
}
//for lines less than the size limit....
if (orig < (PARSE_SIZE_LIMIT - 1))
{
for (x = 0; x <= orig; x++)
{ subject[x] = userstring[x]; }
}
subject[x+1] = '\0';//add terminating null character
//if (word == -1) { printf("<%s> ",subject); }//temp - keep
length = strlen(subject);//get string length of subject[];
//count where all the "magic" characters are
for(x = 0;x < length;x++)
{
//if the subject character = "magic" character then count it
if(subject[x] == magic)
{
a = x;//set a to x , to match where x is currently at.
// check for no words between spaces if x > 0
// if x = 0 then do nothing....
if(x > 0)
{
c = a - b;// c = the new count (of x) - the old count (of x)
//a magic character must have a difference between it's last
//position (if there is one) and its new position greater
//than 1 character to be counted as magic character.
//Therefore, if "#" is a magic character and a string is,
//"##magic:" it would be discounted. A string such "# #magic:"
//would be counted as two magic characters
if(c > 1) { y++; } /* if c > 1 then add 1 to y */
}
b = a;//set b to a , to save the previous count.
}
}
//if the original length of the userstring is (PARSE_SIZE_LIMIT - 1)
//then subtract 1
if (orig >= (PARSE_SIZE_LIMIT - 1)) { y -= 1; }
//return the number parts in the string
if(word == -1)
{
//printf("= %d\r\n",y);//temp - keep
return y;
}
//return the modified user string
if(word == 0) { strcpy(target,subject); }
Before I had DJGPP - was using a really old ( obsolete ) compiler , Borland Turbo C++ for DOS v3.0 which used the code as an example on how to use strtok(); but it works even under DJGPP
so to continue the rest of my function listing ....
Code:
//copy the first word in the string (must be done to find the next words)
if(word == 1)
{
p = strtok(subject,w);
strcpy(target,p);
}
//copy all the next words (sequencially) in the string
if(word > 1)
{
p = strtok(NULL,w);
strcpy(target,p);
}
return 0;
}
//generic string prompt - size was eliminated for TC++
short int kfgets(char *target)
{
short int a;//temp. variables
char line[81];//temp string storage
//user must provide prompt for whatever information wanted from the user
//format the strings
for(a = 0;a < 81; a++) { line[a] = '\0';}
fgets(line , 81, stdin);
a = strlen(line);
line[a-1] = '\0';//get rid of the newline character added by fgets
strcpy(target,line);// copy line to the target array
return 0;
}
short int ynreturn(void)
{
short int result = 0;
char x[3];
while (fgets(x,3,stdin) != NULL && x[1] != '\n');
switch(x[0])
{
case('Y'):
case('y'):
{
result = 1;
break;
}
case('N'):
case('n'):
{
result = 0;
break;
}
default:
{
result = 0;
break;
}
}
return result;
}
so what I am trying to do in my bigger program is break up strings by '#' and then by ' '.....
so in my big program a text line such as :
#clear:
...causes
#newline: 1
...to be parsed as :
#newline:
using the '#' as the token
before its parsed with ' ' as the token
The reason that I started this post as undefined behavior is that DJGPP was compiling my big program to allow parsing of the text line
#newline: 1
as
#newline: 1
other compiliations via DJGPP would do the previous behavior even though the only change
I was doing was commenting out cprintf statements that would show me what the value of
what was going on durring the process as a means of debugging my larger program.
So the way my bigger program works
is that in text file is that #newline: 1 is parsed as #newline: 1 if it comes before #clear: which
is parsed as #clear using '#' as the token. if the two lines are switched the other way around then
the problem occurs.
In the end, my bigger program compiles fine no matter what ... which makes trying to find what IS causing the undefined behavior to be troublesome
Im going to be posting my bigger program source code listing on sourceforge as soon I finish understanding git. I actually have a functioning program that I saved that was compiled with
the Borland compiler, that works.