1

Included is the main and then the implementation of the hex and binary dump, my main concern is with the main. The code is in C. It compiles without error. Im being told to add more details because the post is mostly code but i thought i got my point across. Im looking for whatever is causing the segmentation fault.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xbd.h"
#include "xbd.c"

int main(int argc, char *argv[]){
    int i;
    int counter = 0;
    char *addy;
    char buffer[16];

    //If the user wishes for binary output command arg 2 will be '-b'
    if(strcmp(argv[1], "-b") == 0){
        FILE *f = fopen(argv[2], "r");
        addy = (char*) f;
        //Check for valid file
        if(f == NULL){
            printf("Error: File Empty.\n");
            return(-1);
        }
        //print starting address, faults before this print
        printf("%p: ", (void*)&f);
        while((i = fgetc(f)) != EOF){
            //While there are contents in the file, dump in binary groups of 6 chars
            if(counter == 6){
                //print human readable string here
                printf(" ");
                for(int i = 0; i < 6; i++){
                    printf("%s", buffer[i]);
                }
                printf("\n");
                printf("%p: ", (void*)&addy);
                counter = 0;
            }
            buffer[counter] = binForm(i);
            counter++;
            addy++;
        }
        fclose(f);
    }
    //If not binary, output will be in Hex
    else{
        FILE *f = fopen(argv[1], "r");
        //addy = (char*) f;
        //Check for valid file
        if(f == NULL){
            printf("Error: File Empty.\n");
            return(-1);
        }
        //Print starting address, faults before this print
        printf("%p: ", (void*)&f);
        while((i = fgetc(f)) != EOF){
            //While file has contents, dump in hex groups of 16 chars
            if(counter == 16){
                printf(" ");
                //print human readable string here
                for(int i = 0; i < 16; i++){
                    printf("%s", buffer[i]);
                }
                printf("\n");
                printf("%p: ", (void*)&addy);
                counter = 0;
            }
            if(counter%2 == 1){
                buffer[counter] = hexForm(i);
                printf(" ");
            }
            else{
                buffer[counter] = hexForm(i);
            }
            counter++;
            addy++;
        }
        fclose(f);
    }
}

char hexForm(int current_byte){
    //Print hex digits for one byte
    printf("%X", current_byte);
    //If unprintable, convert to '.'
    if(current_byte < 33)
        current_byte = 46;
    return (char)current_byte;
}
char binForm(int current_byte){
    //Print binary digits for one byte
    while (current_byte) {
    if (current_byte & 1)
        printf("1");
    else
        printf("0");

    current_byte >>= 1;
    }
    //If unprintable, convert to '.'
    if(current_byte < 33)
        current_byte = 46;
    return (char)current_byte;
}

Why is it faulting? I tried commenting some of the early stuff out to see if it goes through but the first couple lines of code result in seg fault. The purpose of the program is to read a file and then changed the text to hex or binary coded output depending on command line argument "-b".

Anon
  • 31
  • 2
  • How do you run it? – Eugene Sh. Feb 19 '19 at 22:00
  • 1
    `if (argc > 2)` seems like it should have an appropriate home somewhere before you use those `argv` dereferences, don't you think? Regardless, a *debugger* is a tool literally *made* for rooting out problems like this. Use one. – WhozCraig Feb 19 '19 at 22:01
  • What is it even supposed to do? You read a character into `i`, but then you use it as a loop counter. – Eugene Sh. Feb 19 '19 at 22:01
  • 4
    `printf("%s", buffer[i]);` - You are passing a `char` instead of `char*`. Please don't tell me there is no warnings about it. – Eugene Sh. Feb 19 '19 at 22:02
  • 1
    the management concerning _addy_ is out of my imagination, in the best case you initialize it with the FILE * (on the 'else' branch it is not initialized) then you print it and increment it each time you read a char in the file, do you think to increment a FILE * has a meaning ? – bruno Feb 19 '19 at 22:09
  • in your code `fopen() == NULL` => `printf("Error: File Empty.\n")` ! – bruno Feb 19 '19 at 22:11
  • [How to debug a segfault](https://stackoverflow.com/q/33047452/10396) – AShelly Feb 19 '19 at 22:14
  • `faults before this print` No, it almost certainly **doesn't**. `printf()` to `stdout` is buffered, so the output won't be printed until the output buffer is flushed. – Andrew Henle Feb 19 '19 at 22:23
  • OT: regarding: `#include "xbd.c"` Never include a *.c file. Rather compile the *.c files separately then link them together – user3629249 Feb 21 '19 at 06:55
  • OT: never access beyond `argv[0]` with out first checking `argc` to assure the user actually entered the desired command line parameter(s) – user3629249 Feb 21 '19 at 06:59
  • OT: regarding: `printf("Error: File Empty.\n");` error messages should be output to `stderr`, not `stdout` and when the error indication comes from a C library function should also output (to `stderr`) the text reason the system thinks the error occurred. The function: `perror()` outputs both your error message and the text reason the system thinks the error occurred – user3629249 Feb 21 '19 at 07:06
  • when `#include`ing any home grown header files, always post the contents of those files as part of your question. – user3629249 Feb 21 '19 at 07:08
  • Please correct your posted code until it cleanly compiles. When compiling, always enable the warnings, then fix those warnings. (for gcc, at a minimum use: -Wall -Wextra -Wconversion -pedantic -std=gnu11 ) Note other compilers use different options to perform the same results – user3629249 Feb 21 '19 at 07:12

1 Answers1

1

I cleaned up your compiler warnings. Seems the code now works as expected. In the future, clean up your compiler warnings and learn to use gdb or other debugger.

Also, before you use argv[] you MUST check to make sure enough arguments are actually provided on the command line.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char hexForm(int current_byte);
char binForm(int current_byte);



int main(int argc, char *argv[]){
    int i;
    int counter = 0;
    char *addy;
    char buffer[16];

    if(argc < 2 )  /* the actual correct usage here is left up to OP */
    {
        printf("Invalid parameters\n")
        return(0);
    }


    //If the user wishes for binary output command arg 2 will be '-b'
    if(strcmp(argv[1], "-b") == 0){
        FILE *f = fopen(argv[2], "r");
        addy = (char*) f;
        //Check for valid file
        if(f == NULL){
            printf("Error: File Empty.\n");
            return(-1);
        }
        //print starting address, faults before this print
        printf("%p: ", (void*)&f);
        while((i = fgetc(f)) != EOF){
            //While there are contents in the file, dump in binary groups of 6 chars
            if(counter == 6){
                //print human readable string here
                printf(" ");
                for(int i = 0; i < 6; i++){
                    printf("%c", buffer[i]);
                }
                printf("\n");
                printf("%p: ", (void*)&addy);
                counter = 0;
            }
            buffer[counter] = binForm(i);
            counter++;
            addy++;
        }
        fclose(f);
    }
    //If not binary, output will be in Hex
    else{
        FILE *f = fopen(argv[1], "r");
        //addy = (char*) f;
        //Check for valid file
        if(f == NULL){
            printf("Error: File Empty.\n");
            return(-1);
        }
        //Print starting address, faults before this print
        printf("%p: ", (void*)&f);
        while((i = fgetc(f)) != EOF){
            //While file has contents, dump in hex groups of 16 chars
            if(counter == 16){
                printf(" ");
                //print human readable string here
                for(int i = 0; i < 16; i++){
                    printf("%c", buffer[i]);
                }
                printf("\n");
                printf("%p: ", (void*)&addy);
                counter = 0;
            }
            if(counter%2 == 1){
                buffer[counter] = hexForm(i);
                printf(" ");
            }
            else{
                buffer[counter] = hexForm(i);
            }
            counter++;
            addy++;
        }
        fclose(f);
    }
}

char hexForm(int current_byte){
    //Print hex digits for one byte
    printf("%X", current_byte);
    //If unprintable, convert to '.'
    if(current_byte < 33)
        current_byte = 46;
    return (char)current_byte;
}
char binForm(int current_byte){
    //Print binary digits for one byte
    while (current_byte) {
    if (current_byte & 1)
        printf("1");
    else
        printf("0");

    current_byte >>= 1;
    }
    //If unprintable, convert to '.'
    if(current_byte < 33)
        current_byte = 46;
    return (char)current_byte;
}
Chimera
  • 5,884
  • 7
  • 49
  • 81