Mailing Label Program - Input & Output Files

This is a discussion on Mailing Label Program - Input & Output Files within the C Programming forums, part of the General Programming Boards category; Hello, You guys have been a great help for a few posts I've made, so I've come back for more ...

  1. #1
    Registered User
    Join Date
    Jul 2011
    Location
    Irvine, CA
    Posts
    13

    Mailing Label Program - Input & Output Files

    Hello,

    You guys have been a great help for a few posts I've made, so I've come back for more sage advice. The following program is not operating as I think it should, so I'm certainly missing some knowledge or have misconceptions about how fprintf and fscanf work. I've even read through the stdio.h section of P.J. Plauger's "The Standard C Library" book to try and understand better, but something isn't sinking in.

    The gist of the program is to generate an output file of formatted mailing labels based on an input file of differently formatted text. The input file contains a single line (ending with a newline) with all the data for a single mailing label:

    Input:
    FirstName;LastName;Address1;Address2;City;State;Zi p\n

    Output:
    FirstName LastName
    Address 1
    Address 2
    City, State Zip


    I'm just getting gibberish in my output file. Thanks in advance for your advice!

    P.S. I created an array of mail_list structs, because my original algorithm had me iterating through the array. Instead of changing it for my new (and obviously still incorrect) algorithm, I just stored the values in the first index.

    Code:
    /********************************************************************************
    *	pcp14_6		--	Design a file format to store a person's name, 				*
    *					address, and other information. Write a program to			*
    *					read this file and produce a set of mailing labels.			*
    *																				*
    *	CLI Format: pcp14_6 <input_filename> <output_filename>						*
    *																				*
    *	Input File Format:															*
    *						FirstName;LastName;Address1;Address2;City;State;Zip\n	*
    *																				*
    *	Output File Format:															*
    *						FirstName LastName\n									*
    *						Address1\n												*
    *						Address2\n (if not NULL)								*
    *						City, State ZIP\n										*
    ********************************************************************************/
    #include <stdio.h>
    
    #define	MAX_LABELS	8
    
    int main(int argc, char *argv[])
    {
    	// Mailing list structure
    	struct mail_list
    	{
    		char f_name[30];	/* first name */
    		char l_name[30];	/* last name */
    		char address1[60];	/* Street address */
    		char address2[60];	/* Additional address info (e.g. apt #) */
    		char city[40];		/* City */
    		char state[4];		/* Two char (not-string) abbreviation */
    		char zip[8];		/* Zip code */
    	}ml[MAX_LABELS];
    
    	FILE	*in_file;		/* text file used for input */
    	FILE	*out_file;		/* mail file output from text file */
    	int		c;				/* Character input */
    
    	in_file = fopen(argv[1], "r");
    	out_file = fopen(argv[2], "w");
    
    	if(in_file == NULL)
    	{
    		fprintf(stderr, "%s does not exist.\n", argv[1]);
    		exit (8);
    	}
    	else
    	{
    		while((c = fgetc(in_file)) != EOF)
    		{
    				fscanf(in_file, "%s;%s;%s;%s;%s;%s;%s\n",
    						ml[0].f_name, ml[0].l_name, ml[0].address1,
    						ml[0].address2, ml[0].city, ml[0].state, ml[0].zip);
    
    				fprintf(out_file, "%s %s\n%s\n%s\n%s, %s %s\n",
    						ml[0].f_name, ml[0].l_name, ml[0].address1,
    						ml[0].address2, ml[0].city, ml[0].state, ml[0].zip);
    		}
    	}
    
    	fclose(in_file);
    	fclose(out_file);
    
    	return 0;
    }

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    %s will stop at whitespace. Try %[^;] instead of %s, except for the zip code.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Apr 2006
    Posts
    2,021
    Never use scanf "%s" or %[] without a width specifier:
    Code:
    fscanf(in_file, "%29[^;]",ml[0].f_name);
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #4
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    First question, why do you think you need to keep an array of lables in memory? What you're doing is a simple translation that can be read into a single struct then passed out to the new file... no need for arrays at all.

    Using fgetc() to test for eof actually displaces your input file pointer by 1 byte... meaning it will likely misalign the data in the output file.

    You would be smarter to use fgets() then sscanf() to pick your data out of the input file.

    To know when to quit, test the return value of fgets().

  5. #5
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    FILE *fin, *fout;
    if( (fin=fopen( ... )) && (fout=fopen( ... )) )
    {
        int byte, semi = 0;
        while( (byte = fgetc( fin )) != EOF )
        {
            if( byte == ';' )
            {
                semi++;
                if( semi == 1 || semi == 5 || semi == 6 )
                {
                    if( semi == 5 )
                        fputc( ',', fout );
                    byte = ' ';
                    if( semi == 6 )
                        semi = 0;
                }
                else
                    byte = '\n';
            }
            fputc( byte, fout );
        }
        fclose( fin );
        fclose( fout );
    }
    Looks about right.


    Quzah.
    Hope is the first step on the road to disappointment.

  6. #6
    Registered User
    Join Date
    Jul 2011
    Location
    Irvine, CA
    Posts
    13
    Quote Originally Posted by CommonTater View Post
    First question, why do you think you need to keep an array of lables in memory? What you're doing is a simple translation that can be read into a single struct then passed out to the new file... no need for arrays at all.

    Using fgetc() to test for eof actually displaces your input file pointer by 1 byte... meaning it will likely misalign the data in the output file.

    You would be smarter to use fgets() then sscanf() to pick your data out of the input file.

    To know when to quit, test the return value of fgets().
    Thanks for the feedback everyone. I'll take a look at this program again tomorrow with your advice in mind.

    As for the array... when I came up with my original algorithm, I had it in my head that I needed to write each line into it's own array index or else the previous data would be overwritten and the output would be incorrect. Just a newb trying to figure things out.

    Thanks again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. input/output files
    By thescratchy in forum C Programming
    Replies: 8
    Last Post: 02-09-2010, 02:35 PM
  2. Input/Output Files
    By zrsmith2 in forum C Programming
    Replies: 3
    Last Post: 06-15-2008, 10:30 PM
  3. Input and Output files
    By matrixhelp in forum C Programming
    Replies: 1
    Last Post: 03-10-2008, 02:07 AM
  4. Help with input/output files
    By aldin176 in forum C++ Programming
    Replies: 5
    Last Post: 11-06-2006, 08:04 AM
  5. input/output files question
    By ssjnamek in forum C++ Programming
    Replies: 2
    Last Post: 04-22-2005, 12:38 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21