Thread: Incorrect output with FILE*

  1. #1
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32

    Incorrect output with FILE*

    I'm still new to C programming and i wanted to try and use files for input and output back to files. My friend told me to try http://dwite.ca/questions/show_me_the_money.html to test out my skills. I've been stumped on it at first because it requires each line to be separated so I searched a bit and found that FILE* would work for me. It doesnt seem to process correctly and i'm not too sure what is going on so any help would be appreciated.

    Here is the code in question:

    Code:
    #include <stdio.h>
    
    int main(int argc, char** argv)
    {
    	const char filename[] = "DATA2.txt";
    	const char filename2[] = "OUT2.txt";
    	int balance = 0;
    	FILE *INSTREAM = fopen( filename, "r"); /* input file */
    
    	if (INSTREAM == NULL) /* if the file doesn't exist or is NULL */
    	{
    		printf("File appears empty, please check if the file is there or that something is written in the file, then re-load this program.");
    		return -1;
    	}
    
    	FILE *OUTSTREAM = fopen( filename2, "w"); /* output file */
    	int count = 0; 
    	int BUFFER = 255; 
    	char line[BUFFER]; /* char array for pointers to each character  in INSTREAM*/
    	
    	if (INSTREAM != NULL)
    	{
    		while (fgets (line, sizeof line, INSTREAM) != NULL) /* grabs pointers for line[] */
    		{
    			while(count <= sizeof line)
    			{
    				if (line[count] == '-') /* if the pointed character is "-" */
    				{
    					balance--; /* minuses 1 from balance */
    					if (balance < 0) /* if balance is under 0 */
    					{
    						fprintf(OUTSTREAM, "%s", "\nOH NOES!\n"); /* prints out low balance */
    						balance = 0; /* returns balance back to 0 */
    						break; /* breaks the string loop and grabs a new string (because rules say to disregard the entire string is the balance is under 0 */
    					}
    					else
    					{
    						fprintf(OUTSTREAM,"%d", balance); /* else, print current balance */
    					}
    				}
    				else if (line[count] == '+') /* if the pointed character is "+" */
    				{
    					balance++; /* add 1 to balance */
    					fprintf(OUTSTREAM,"%d", balance); /* print out current balance */
    				}*/
    				count++; /* adds 1 to count and continues the while loop */
    			}
    		}
    	}
    	return 0;
    }

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > while(count <= sizeof line)
    What is the value of count on the 2nd line?

    You only initialise it once BTW.

    Also, you should do this
    while( line[count] != '\0' )
    so you stop at the end of the valid data, and not process whatever junk is in the buffer beyond what was read from the file.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32
    i just realized that my code only points to the first line and doesnt take in any other lines. i commented out the processing and added:

    Code:
    while(count <= sizeof line) {
    
    	while(line[count] !='\0') {
    
    		printf("%p\n", line[count]);
    	}
    }
    and the output was:
    Code:
    0000002B
    0000002B
    0000002B
    0000000A
    which is "+++" and line termination. This means it did not pick up the second line or further. If i were to take out while(line[count] !='\0') the first 4 outputs would be the same, but the next outputs upto 255 (see, BUFFER) is random hex

    my question now is..how do i get my code to get to the next line?

  4. #4
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Like I said, your count runs to the end of the buffer and then stops there.

    And please read up on how to use printf. Using %p to print chars is just dumb.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32
    i realize this, but what exactly would i do now to have it take in a second, third, etc... line?

    again, im still new to C programming so i have no clue, and yes ill read up on printf more.

    EDIT: thanks for the tip, ill use "%c" next time.
    Last edited by patrink; 11-05-2010 at 04:51 PM. Reason: added a line

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    while fgets...

    count = 0;

    while count <

    See?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32
    to be honest, not really.

  8. #8
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    What Salem is saying is that there are a couple logical error in you code.

    The first is that you are only processing one line. The second is that you are printing garbage after the line is done being processed.

    Let's break down the code in question:
    Code:
    	int count = 0;
    Initialize count to zero.
    Code:
    	int BUFFER = 255;
    Initialize BUFFER to 255 (this should probably be a #define at the top of the file since you don't need or want BUFFER to be a variable).
    Code:
    	char line[BUFFER]; /* char array for pointers to each character  in INSTREAM*/
    Declare line as a character array of length BUFFER (255).
    Code:
    	if (INSTREAM != NULL)
    	{
    Check INSTREAM. I think this should be OUTSTREAM since you already checked instream higher up in your code.
    Code:
    		while (fgets (line, sizeof line, INSTREAM) != NULL) /* grabs pointers for line[] */
    		{
    Get up to sizeof(line) - 1 characters from INSTREAM and store them in line. I recommend you read up a little on exactly what will be in line if you have a line in the file that is right around limit you passed to fgets. I like the following site for quick, basic info on the standard C libraries: The C Library Reference Guide.
    Code:
    			while(count <= sizeof line)
    			{
    For each element of line (regardless of whether you read 2 characters or 254), process the character and print some output.
    Code:
                                    ...
    				count++; /* adds 1 to count and continues the while loop */
    			}
    		}
    	}
    Increment count and terminate loops/if-blocks.

    The problems you're having both lie around this line:
    Code:
    			while(count <= sizeof line)
    The first time you hit this loop, count is 0, and gets incremented until the loop terminates, meaning that count is 256. You finish processing the line and read another line. For all lines other than the first, when you hit this loop, count is already 256 (you reached the end of the first line and never reinitialized count for the new line), and thus this whole loop gets skipped. You need a count = 0 between the while(fgets... loop and the while(count... loop, as Salem suggested
    Code:
    		while (fgets (line, sizeof line, INSTREAM) != NULL) /* grabs pointers for line[] */
    		{
                            count = 0;
    			while(count <= ...
    That while(count... loop is also the problem with your garbage variables.

    Remember that line is a array of 255 characters, thus sizeof(line) is equivalent to sizeof(char) * 255, or 255 bytes, regardless of how much you read in from a given file. As a matter of fact, line would still be 255 bytes if you never read a single thing in. the sizeof operator only tells you how much memory that variable requires, not how much significant info is stored in it. Read up on sizeof.

    The fgets function doesn't necessarily read in 255 characters (even though you passed in sizeof(line) for the second parameter), it's may stop when it gets an EOL or EOF. Note that line will always be null terminated whether it reads 2 characters or 254. You only care about what it read from the file, not every character in the array. The null character fgets put in line is to tell you where the significant info stops. Everything after it is garbage.

    Thus, to avoid all the garbage hex values you see, change your code to something like:

    Code:
    while(count <= strlen(line))
    That fix should get rid of all the garbage, but I let you take a crack at getting rid of the newline character you're seeing in your output.

  9. #9
    Registered User
    Join Date
    Nov 2010
    Location
    In my house
    Posts
    32
    Thanks for the explanation. My program seems to work fine, just i need to change things around to print every line rather than for every character, but this shouldn't be too hard for me.

    Thanks everyone.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String incorrect for output command target
    By DarkAlex in forum C++ Programming
    Replies: 16
    Last Post: 08-19-2008, 09:32 PM
  2. strange virtual function output
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 02-08-2008, 08:08 AM
  3. Trying to store system(command) Output
    By punxworm in forum C++ Programming
    Replies: 5
    Last Post: 04-20-2005, 06:46 PM
  4. String output, sometimes incorrect
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 03-14-2002, 08:46 AM
  5. Incorrect Output
    By Nutshell in forum C Programming
    Replies: 2
    Last Post: 01-07-2002, 09:11 AM