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 IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Problem with file conversion program

Status
Not open for further replies.

johnncc

MIS
Oct 2, 2002
15
US
Hello,
I have written a simple program to convert a tab delimited file into a fixed length file. It works for the most part but the results are no what I expect. There are 16 fields and it prints all 16 fields but all the fields past the second one have the same info in them. Example: A file with the info:

ref - REC00004A1
clNum - hosway
clName - wayne general
acct - 100023

The first field would print as REC00004A1, the second field would print -hosway- and all swubsequent fields will also print -hosway- no matter what I try. I hope I have explained my problem well enough. Can anyone help? Here is my code:

Code:
// this program will open a tab file and save as fixed length
#include <stdio.h>
#include <stdlib.h>
#include <string.h>



int main()

{


	// set file pointers
	FILE *dialPtr;
	FILE *smartPtr;

	//input tab file name
	char myFile[32];
	
	//input file to convert
	printf("Enter the file to convert: (dialer.txt).\n> ");
	scanf("%s", myFile);

	//check if files are open
	if ((dialPtr = fopen (myFile, "r")) == NULL)
	
	//if not open
	{
		printf("Unable to open %32s.\n", myFile);
	}
	if ((smartPtr = fopen ("smartout.txt", "w")) == NULL)

	{
		printf("Unable to open smartout.txt\n\n");
	}

	else{

		//process files
		char line[4096];


		while (fgets(line, sizeof(line), dialPtr) != NULL)
		{


			char *rec;
			char *clNum;
			char *clName;
			char *acct;
			char *dbtr;
			char *addy;
			char *phone;
			char *pt;
			char *assign;
			char *stat;
			char *desk;
			char *tot;
			char *lstPay;
			char *lstWork;
			char *state=line;//buffer			

			//extract info from buffer
			rec = "REC00004A1";
			clNum = strtok(state, "\t");
			clName = strtok(state, "\t");
			acct = strtok(state, "\t");
			dbtr = strtok(state, "\t");
			addy = strtok(state, "\t");
			phone = strtok(state, "\t");
			pt = strtok(state, "\t");
			assign = strtok(state, "\t");
			stat = strtok(state, "\t");
			desk = strtok(state, "\t");
			tot = strtok(state, "\t");
			lstPay = strtok(state, "\t");
			lstWork = strtok(state, "\t\r\n");

			//send to file
			fprintf(smartPtr, "%-10s%-10s%-30s%-10s%-10s%-30s%-25s%-10s%-30s%-6s%3s%-5s%5s%-8s%14s%-6s\n", rec, clNum, clName, phone, acct, dbtr, addy, phone, pt, assign, stat, desk, tot, tot, lstPay, lstWork);
		}
	
		//close files
		fclose(smartPtr);
		fclose(dialPtr);
	}

	//success
	return 0;
}
 
I think you have a very unstable (and cumbersome) algorithm. Get a line with less than 16 fields - and you have a total crash because of strtok() returns null pointers then you pass them to the credulous printf...
Try (or compare;) this improvisation:
Code:
#define BSZ (1024*16)
#define LSZ 4096

static const char delim[]   = "\t\r\n";
static const char BadFile[] = "*** Unable to open %s\n";

int DoThat(const char* fnin, const char* fnto,
           const int fwdth[], int nflds)
{
  int	i;
  int	n = 0;
  int   k = 0;
  FILE* fin = 0;
  FILE* fto = 0;
  char* pline = 0;
  char* p; /* for strtok() */
	
  if (!fnin)
     fin = stdin; /* Some sugar... */
  else
  {
     fin = fopen(fnin,"r");
     if (!fin)
     {
	printf(BadFile,fnin);
	return 0;
     }
  }
  if (!fnto)
     fto = stdout;
  else
  {
     fto = fopen(fnto,"w");
     if (!fto)
     {
        if (fnin)
           fclose(fin);
        printf(BadFile,fnin);
        return 0;
     }
     if (fnin)
        setvbuf(fin,0,_IOFBF,BSZ); /* May increase speed */
     setvbuf(fto,0,_IOFBF,BSZ);     /* ...dramatically... */
  }
  pline = (char*)malloc(LSZ); /*better new if C++ compiler*/
  if (!pline)
     printf("Can\'t obtain buffer[%d]\n",BSZ);
  else /* Let's go... */
  for (k = n = 0; fgets(pline,LSZ,fin); ++k)
  {
    p = strtok(pline,delim);
    for (i = 0; p && i < nflds; ++i)
    {
      fprintf(fto,"%-*.*s",fwdth[i],fwdth[i],p); /* *.* ! */
      p = strtok(0,delim);
    }
    fputc('\n',fto); /* endl... */
    if (i == nflds)
       ++n; /* processed */
    else
    {
	fprintf(stderr,"*** Bad line %d\n",k+1);
        /* break or continue? */
    }
  }
  /* Epilogue... */
  if (fnin && fin)
     fclose(fin);
  if (fnto && fto)
     fclose(fto);
  free(pline); /* or delete if C++ new was used */

  return n; /* processed lines counter */
}

int main()
{
  int	flds[3] = { 8, 16, 12 }; /* Test case... */
  DoThat("junktab.txt","junkfix.txt",flds,3);
  ...
See setvbuf() - always use explicit bufferization (>=16K bytes) in that cases...
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top