user834826
user834826

Reputation: 1

How do I print certain parts of a string array?

I'm writing a function that dumps a file into octal. After it reaches the limit for amount of characters on a line, it is suppose to print out the printable characters of file being passed into.

For some reason my program always prints the first 16 characters of the text file, how would i print the rest of the characters in the file?

Here is the text file i'm using to test:

 ?asdfadsbgasdfassadfasdfsadfads
 asdf
 asdf
 asd
 v
 asdf
 asdf
 asd
 f
 asdf

Here is the output to stdout:

   0000000 77 141 163 144 146 141 144 163 142 147 141 163 144 146 141 163  | ?asdfadsbgasdfas
   0000020 163 141 144 146 141 163 144 146 163 141 144 146 141 144 163 15  | ?asdfadsbgasdfas
   0000040 12 141 163 144 146 15 12 141 163 144 146 15 12 141 163 144  | ?asdfadsbgasdfas
   0000060 15 12 166 15 12 141 163 144 146 15 12 141 163 144 146 15  | ?asdfadsbgasdfas
   0000100 12 141 163 144 15 12 146 15 12 141 163 144 146 15 12 ?asdfadsbgasdfa
   0000120

Here is my code:

void octaldump(FILE * fp)
{
    int c;
    size_t linecount = 0, index = 0, i;
    long int address = 0;
    char temp [LINESIZE];

    while((c = fgetc(fp)) != EOF)
    {
        if(linecount == 0)
        {
            printf("%07o ", address);
            address += 16;
        }
        temp[index] = c;
        index++;

        printf("%02o ", c);
        linecount++;

        if(linecount == 16)
        {
            printf(" | ");
            for(i = 0; i < linecount; i++)
            {
                if(temp[i] <= 32)
                {
                    printf(".");
                }
                else
                {
                    printf("%c", temp[i]);
                }
            }
            printf("\n");
            linecount = 0;
        }
    }

    if(linecount < 16)
    {
        for(i = 0; i < linecount; i++)
        {
            if(temp[i] <= 32)
            {
                printf(".");
            }
            else
            {
                printf("%c", temp[i]);
            }
        }
    }

    printf("\n%07o ", address);
}

Upvotes: 0

Views: 1072

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 755094

Your problem is that you don't set index back to zero after the linecount == 16 code. Amongst other things, that means you have a horrendous buffer overflow.

In the trailing data processing, you should first print out enough blanks for the missing characters that the printable characters are aligned with the other sets. I mentioned in a comment using "%03o" in place of "%02o" to give consistent alignment. Also, using isprint() from <ctype.h> would improve things.


This works reasonably well for me - tested on its own source code:

#include <ctype.h>
#include <stdio.h>

enum { LINESIZE = 16 };

void octaldump(FILE * fp)
{
    int c;
    size_t linecount = 0, index = 0, i;
    unsigned long address = 0;
    char temp [LINESIZE];

    while ((c = fgetc(fp)) != EOF)
    {
        if (linecount == 0)
        {
            printf("%07lo ", address);
            address += 16;
        }
        temp[index] = c;
        index++;

        printf("%03o ", c);
        linecount++;

        if (linecount == 16)
        {
            printf(" | ");
            for (i = 0; i < linecount; i++)
                printf("%c", isprint(temp[i]) ? temp[i] : '.');
            printf("\n");
            linecount = 0;
            index = 0;
        }
    }

    if (linecount < 16)
    {
        for (int j = linecount; j < 16; j++)
            printf("    ");
        printf(" | ");

        for (i = 0; i < linecount; i++)
            printf("%c", isprint(temp[i]) ? temp[i] : '.');
        printf("\n");
    }

    printf("%07lo\n", address);
}

int main(void)
{
    octaldump(stdin);
    return 0;
}

Upvotes: 3

Related Questions