Reading separate components of 8.3 filename into proper filename in C
Here are some things that may help you improve your code.

Avoid "tricky" loops

There is nothing technically wrong with this line:

for(c=0; c &lt; 8 &amp;&amp; filename[c] != '\0'; c++);


However, because one doesn't usually write a for loop with no body, it would probably be useful for your code to call attention to the fact that there's nothing happening within the loop.  You could write it like this:

for(c=0; c &lt; 8 &amp;&amp; filename[c] != '\0'; c++) {
    // do nothing 
}


Or another way:

for(c=0; c &lt; 8 &amp;&amp; filename[c] != '\0'; c++)
    continue;


All will likely compile to the exact same object code.

Don't mix I/O with data operations

Generally speaking having a printf within a data manipulation function such as read_filename is not a good idea.  It makes it harder to reuse the function.  It's OK for diagnostics and for troubleshooting, but it would be better to omit it from the final version.  Similarly, it would be better if the fread would read the entire 8.3 filename into a memory buffer and then pass the memory buffer to code that would do the parsing.  That cleanly separates I/O from data manipulation and is probably more efficient as well.

Return an error code

The read_filename function can detect errors, but summarily exits the entire program rather than returning an error code that would allow the calling function to decide how to handle the error. A more robust design that might allow the code to be reused would return an error code.

Eliminate "magic numbers"

Things like if (argc != 2) are OK, because programmers reading this will know what that code is doing.  However, when you write if(8 != fread(&amp;filename[0], 1, 8, arc)) it's not at all obvious whether 8 is the correct value, or exactly what it represents.  Better would be to use a named const value there such as const size_t FILENAMESIZE = 8;

Be careful with assumptions about argument size

In the fprintf functions, the parameter should be 0x%08lX rather than 0x%08X because ftell() returns a long.

Try this

Here's one way to do this, incorporating all of these suggestions:

// max size of 8.3 filename
const size_t FILENAMELEN = 11u;
const size_t EXTOFFSET = 8u;
const size_t EXTLEN = 3u;

char *read_filename(FILE *arc)
{
    char *filename = malloc(FILENAMELEN+2);
    if (filename == NULL) {
        return filename;
    }
    filename[FILENAMELEN] = '\0';
    if (FILENAMELEN != fread(filename, 1u, FILENAMELEN, arc)) {
        free(filename);
        return NULL;
    }
    return filename;
}

char *parse_filename(char *filename)
{
    if (filename == NULL) {
        return filename;
    }
    // insert the '.'
    memmove(&amp;filename[EXTOFFSET+1], &amp;filename[EXTOFFSET], EXTLEN);
    filename[EXTOFFSET] = '.';
    size_t i;
    for (i=0; filename[i] &amp;&amp; i &lt; EXTOFFSET; ++i) {
    }
    if (i &lt; EXTOFFSET) {
        memmove(&amp;filename[i], &amp;filename[EXTOFFSET], EXTLEN+2);
    }
    return filename;
}