Thread: problem with file I/O, whole code

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    8

    problem with file I/O, whole code

    Hey, so like the descriptions says, this program is supposed to read a file called card.raw which has 30 jpgs on it and the rest is 0s. And then write those jpgs in a folder.

    It's my first time using file I/O so I'm sure I made a bunch of mistakes. The file does compile but it doesn't even create any jpgs and it runs indefinitely. I'm using gdb to debug and I can't find a way to use it that makes sense with this problem.

    My questions is, can you help me fix it? And also for the future, what is a good way to debug a program like this?

    I'm using gcc to compile and OS is fedora.

    Code:
    /* 
     * ====================================
     *  Description: Recovers pictures from card.raw which
     *  contains 30 jpgs in a row, then is blanked out with 0s.
     * ====================================
     */
     
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "bmp.h"
    
    int
    main(void)
    {
        // open card.raw
        FILE *card = fopen("card.raw" , "r");
        if (card == NULL)
        {
            printf("Could not open card.raw");
            return 1;
        }
        
        // jpg number for output name
        int jpg_number = 1;
        
        // look at every byte of card.raw
        BYTE jpg_chunk[512];
        
        while (fread(&jpg_chunk, sizeof(BYTE), 512, card) != 0) // read current 512 byte        
        {    
            // test if that current 512 bytes is start of jpg
            if (jpg_chunk[0] == 0xff && jpg_chunk[1] == 0xd8 && jpg_chunk[2] == 0xff &&
               (jpg_chunk[3] == 0xe0 || jpg_chunk[3] == 0xe01))
            {
                // determine filename
                char *jpg_name = "";
                sprintf(jpg_name, "%d.jpg" , jpg_number);
                
                // create jpg   
                FILE *jpg_write = fopen(jpg_name, "w"); 
                if (jpg_write == NULL)
                {
                    fclose(jpg_write);
                    fprintf(stderr, "Could not create %s.\n", jpg_name);
                    return 2;
                }
                
                do 
                    // write to jpg
                    fwrite(&jpg_chunk, sizeof(BYTE), 512, jpg_write);
                while (jpg_chunk[0] != 0xff && jpg_chunk[1] != 0xd8 && jpg_chunk[2] != 0xff &&
                      (jpg_chunk[3] != 0xe0 || jpg_chunk[3] != 0xe01));
                
                // close finished jpg
                fclose(jpg_write);
                
                // this jpg is done, next jpg
                jpg_number++;
            }
        }
        
        // close card.raw
        fclose(card);
        
        // end
        return 0;
    }
    Last edited by durrr; 10-12-2012 at 01:15 AM.

  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
    > char *jpg_name = "";
    > sprintf(jpg_name, "%d.jpg" , jpg_number);
    You need to allocate some actual space for your string.

    Say
    char jpg_name[100];

    Consider this to start with
    Code:
        while (fread(&jpg_chunk, sizeof(BYTE), 512, card) != 0) // read current 512 byte        
        {    
            // test if that current 512 bytes is start of jpg
            if (jpg_chunk[0] == 0xff && jpg_chunk[1] == 0xd8 && jpg_chunk[2] == 0xff &&
               (jpg_chunk[3] == 0xe0 || jpg_chunk[3] == 0xe01))
            {
                printf("Found the start of a JPG file\n");
            }
        }
    If this doesn't print 30 lines, then you need to think about this some more.
    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
    Long Beach, CA
    Posts
    5,909
    Code:
    /* 
            if (jpg_chunk[0] == 0xff && jpg_chunk[1] == 0xd8 && jpg_chunk[2] == 0xff &&
               (jpg_chunk[3] == 0xe0 || jpg_chunk[3] == 0xe01))
    
                while (jpg_chunk[0] != 0xff && jpg_chunk[1] != 0xd8 && jpg_chunk[2] != 0xff &&
                      (jpg_chunk[3] != 0xe0 || jpg_chunk[3] != 0xe01));
    I don't think 12 bits can fit in a byte. Perhaps you meant 0xe1?

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    8
    thanks for the replies, i have incorporated both suggestions, the result i get is now 37 jpgs (file does contain 37 even if i said 30 in the description in 1st post so that's correct) that are unreadable i also get the code below printed.

    my question: im still not quite sure how to go about debugging the reason why the jpgs aren't being shown properly

    Code:
    found the start of a JPG file
    jpg chunk: ff d8 ff e0
    wrote name: 1.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    wrote name: 2.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    wrote name: 3.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    wrote name: 4.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    wrote name: 5.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    ...
    ...
    wrote name: 36.jpgfound the start of a JPG file
    jpg chunk: ff d8 ff e0
    this is the updated code
    Code:
    /*
     * ========================================================
     *  Description: Recovers pictures from card.raw which
     *  contains **37** jpgs in a row, then is blanked out with 0s.
     * ========================================================
     */
     
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "bmp.h"
    
    int
    main(void)
    {
        // open card.raw
        FILE *card = fopen("card.raw" , "r");
        if (card == NULL)
        {
            printf("Could not open card.raw");
            return 1;
        }
        
        // jpg number for output name
        int jpg_number = 1;
        
        // look at every byte of card.raw
        BYTE jpg_chunk[512];
        
        while (fread(&jpg_chunk, sizeof(BYTE), 512, card) != 0) // read current 512 byte        
        {    
            // test if that current 512 bytes is start of jpg
            if (jpg_chunk[0] == 0xff && jpg_chunk[1] == 0xd8 && jpg_chunk[2] == 0xff && 
               (jpg_chunk[3] == 0xe0 || jpg_chunk[3] == 0xe1))
               
            {
                // determine filename
                char jpg_name[10];
                sprintf(jpg_name, "%d.jpg" , jpg_number);
                
                // create jpg   
                FILE *jpg_write = fopen(jpg_name, "w"); 
                if (jpg_write == NULL)
                {
                    fclose(jpg_write);
                    fprintf(stderr, "Could not create %s.\n", jpg_name);
                    return 2;
                }
                
                // TESTING
                printf("found the start of a JPG file\n");
                printf("jpg chunk: %x %x %x %x\n" , jpg_chunk[0], jpg_chunk[1], jpg_chunk[2], jpg_chunk[3]);
                printf("wrote name: %s" , jpg_name);
    
                
                do 
                    // write to jpg
                    fwrite(&jpg_chunk, sizeof(BYTE), 512, jpg_write);
                while (jpg_chunk[0] != 0xff && jpg_chunk[1] != 0xd8 && jpg_chunk[2] != 0xff &&
                      (jpg_chunk[3] != 0xe0 || jpg_chunk[3] != 0xe1));
                
                // close finished jpg
                fclose(jpg_write);
                
                // this jpg is done, next jpg
                jpg_number++;
            }
        }
        
        // close card.raw
        fclose(card);
        
        // end
        return 0;
    }
    Last edited by durrr; 10-12-2012 at 02:10 AM.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    > fwrite(&jpg_chunk, sizeof(BYTE), 512, jpg_write);
    You only have this inside the "new chunk" code.

    You need to write all chunks to the file.

    In other words, your "new chunk" detection code should do the following
    - close the old file (if appropriate)
    - generate a new filename
    - open a new 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.

  6. #6
    Registered User
    Join Date
    Oct 2012
    Posts
    8
    i don't understand what you mean, i'm closing the file at the end of the loop (line 63) and opening the file at the beginning (line 42) and everything loops until the end of the cards.raw (line 30). anyone can help me with this? i'm still stuck

    Quote Originally Posted by Salem View Post
    > fwrite(&jpg_chunk, sizeof(BYTE), 512, jpg_write);
    You only have this inside the "new chunk" code.

    You need to write all chunks to the file.

    In other words, your "new chunk" detection code should do the following
    - close the old file (if appropriate)
    - generate a new filename
    - open a new file

  7. #7
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Your do while loop writes out the info, in a tight loop. But it doesn't READ any new info, inside that loop.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    You're not writing everything to a file.
    Code:
        while (fread(&jpg_chunk, sizeof(BYTE), 512, card) != 0) // read current 512 byte        
        {    
            // test if that current 512 bytes is start of jpg
            if (jpg_chunk[0] == 0xff && jpg_chunk[1] == 0xd8 && jpg_chunk[2] == 0xff && 
               (jpg_chunk[3] == 0xe0 || jpg_chunk[3] == 0xe1))
               
            {
                // determine filename
                char jpg_name[10];
                sprintf(jpg_name, "%d.jpg" , jpg_number);
                
                // create jpg   
                FILE *jpg_write = fopen(jpg_name, "w"); 
                if (jpg_write == NULL)
                {
                    fclose(jpg_write);
                    fprintf(stderr, "Could not create %s.\n", jpg_name);
                    return 2;
                }
                
                // TESTING
                printf("found the start of a JPG file\n");
                printf("jpg chunk: %x %x %x %x\n" , jpg_chunk[0], jpg_chunk[1], jpg_chunk[2], jpg_chunk[3]);
                printf("wrote name: %s" , jpg_name);
    
                
                do 
                    // write to jpg
                    fwrite(&jpg_chunk, sizeof(BYTE), 512, jpg_write);
                while (jpg_chunk[0] != 0xff && jpg_chunk[1] != 0xd8 && jpg_chunk[2] != 0xff &&
                      (jpg_chunk[3] != 0xe0 || jpg_chunk[3] != 0xe1));
                
                // close finished jpg
                fclose(jpg_write);
                
                // this jpg is done, next jpg
                jpg_number++;
            }
            else
            {
                printf("Non header chunk lost to the sands of time\n");
            }
        }
    Notice I've placed a final else statement.
    Tell us how many times it gets printed, which tells you how many chunks are NOT being written to a 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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 3
    Last Post: 11-21-2006, 07:26 PM
  2. Replies: 3
    Last Post: 10-20-2006, 07:59 PM
  3. File I/O:simple code problem
    By Ardetcho in forum C Programming
    Replies: 4
    Last Post: 07-18-2006, 10:32 AM
  4. Replies: 6
    Last Post: 05-12-2005, 03:39 AM
  5. Replies: 3
    Last Post: 05-03-2003, 12:04 PM