Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Help with this code, no compile errors 3

Status
Not open for further replies.

rouge03

Programmer
May 5, 2003
16
PH
The fuction of the codes below is to parse strings from a text file. An example of a string in the input file would be:

Entry=1
Name=Archie S. Andrews

When I compile the the following codes in either Borland C++ 4.5 or Microsoft Visual C++ 6, I get no errors. However when I try to run them I get different results. With Borland, I get a "Could not create process" message. With Microsoft I'm able to run it but then I get additional characters printed out in the 'mi' character. It prints out garbage.
I can't pinpoint what is causing the problem. Please help.

#include "stdio.h"
#include "conio.h"
#include <io.h>
#include <string.h>
#include <process.h>

main()
{
FILE *fhandle_in, *fhandle_out;
char *ptr,buffer[80],name[80],lname[20],mi[2];
int acc_no=0;
clrscr();
if ((fhandle_in = fopen("train1.txt", "r")) == NULL)
{
printf("cannot open file");
exit(1);
}
if ((fhandle_out = fopen("jenny.txt","w")) == NULL)
{
printf("cannot open file");
exit(1);
}

while (!feof(fhandle_in))
{
if (fhandle_in!=NULL)
{
fgets(buffer,80,fhandle_in);
if ((ptr=strstr(buffer,"Entry="))!=NULL) //get value for Accession number
{
acc_no++;
printf("$001:%010d",acc_no);
ptr-=6;
}

// Name segment
if ((ptr=strstr(buffer,"Name="))!=NULL)
{
ptr+=5;
strcpy(name,ptr);
if (name[strlen(name)-1]=='\n')
name[strlen(name)-1]='\0'; // remove newline character
ptr=strrchr(name,'.');
ptr+=2;
strcpy(lname,ptr);
ptr -=3;
strncpy(mi,ptr,2); // get the middle initial

printf("$100:%s, %s",lname,mi);
}
}
}
getch();
fclose(fhandle_out);
fclose(fhandle_in);
return 0;
}


Thanks
 
Insert printf's into your code 1 line at a time and see where it stops.
This is an easy way to see how far you get before things die.
At that point, print out all relevant variables and see which looks wrong before you use them.
 
Ah, i think i got it!

You reserve 2 bytes för 'mi' but nothing for the trailing zero!

Reserve ALWAYS room for the text + 1 trailing zero!!!

Try

char *ptr,buffer[81],name[81],lname[21],mi[3];
in stead of:
char *ptr,buffer[80],name[80],lname[20],mi[2];



Totte
Keep making it perfect and it will end up broken.
 
May I interject and offer some suggestions? Hope you don't mind.

When you open the second file for writing, if it fails, you may want to close the already open input file handle fhandle_in.

Inside your while loop, you check if fhandle_in!=NULL, but fhandle_in is never assigned anything after it is open. This check will never fail... even after it is closed. This "if" statement can be safely removed.

Inside your loop, you have two "if" statements checking for how the line starts ("Name=" or "Entry="). Unless you can put both of these on a single input line in your file, you should use "else if" for the second "if" statement to avoid redundant checking. This means you can remove the p-=6 as well.

Newlines in Windows consists of 2 characters. "\n" is 2 characters while '\n' is one. "\n" is the same as \r\n.
So to remove end of lines, you should check for both.

int endline = strlen(name)-1;
while ((endline>=0)&&((name[endline]=='\r')||(name[endline]=='\n')))
{
name[endline]='\0';
endline--;
}

I usually use a version of this as a macro to strip newlines.

When you scan for '.' to find the middle initial and the last name, you don't check if it's NULL. Do you have names that don't have middle initials? For example, in my real name, I don't have a middle name. Strange, I know, but I don't have one. If I entered my real name in your list, your program would fail.

I agree with the above post that you must reserve 3 characters for mi. After this line,

strncpy(mi,ptr,2);

Insert the following line to append the terminating nul.

mi[2] = '\0';

BTW, I hope you don't take any of this in a negative way. The only major flaw was the last nul termination. Most of it is only nitpicking anyways, and my only wish is that it may help some people realise what kind of work goes into even a simple program.

Cheers


A programmer is a device for converting Coke into software.
 
Thank you all the informative posts you have put in here. Actually, through some more research I have been able to pinpoint the problem. Its with the usage of strncpy. It does not append a null at the end of the new string. That's why I resorted to just using strncat.


temp[0]=NULL;
fname[0]=NULL;

// for Name segment
if((ptr=(strstr(buffer,"Name=")))!=NULL) {
ptr+=6;
strcpy(check,ptr);
strcpy(temp,--ptr);
if (check[0]=='\0') {
err_no++;
fprintf(fileOUT,"$100:<error:No name>");
}
else {
temp[strlen(temp)-1]='\0'; // remove \n character
ptr=strrchr(temp,'.');
strcpy(nemp,--ptr);
strncat(fname,temp,(strlen(temp)-strlen(nemp)));
strcpy(lname,ptr+3);
strncpy(mi,ptr--,1);
mi[1]='\0'; // string terminator must be appended to avoid garbage characters
fprintf(fileOUT,"$100:%s, %s %s.",lname,fname,mi);
}
}

For the mi, I could still use the strncpy because I would know how many character(s) this character array will hold.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top