0

I am reading data from Intel hex format file after opening it in binary mode and then creating a data (unsigned char)buffer and storing all the data in that (unsigned char)buffer in hex format.

I'm facing issue when the length of the data line is even (not including ':') program is adding 1 extra 0 at the end of the data.

//Returns content of firmware file in line by line fashion
unsigned char * readline(FILE *fp, unsigned char *buffer)
{
    unsigned int ch, iterator_i = 0;
    size_t buff_len = 0;

    buffer = malloc(buff_len + 1);
    if (!buffer) return NULL;  // Out of memory

    while ((ch = fgetc(fp)) != '\n' && ch != EOF)
    {
        buff_len++;
        void *tmp = realloc(buffer, buff_len + 1);
        if (tmp == NULL)
        {
            free(buffer);
            return NULL; // Out of memory
        }
    buffer = tmp;

    buffer[iterator_i] = (char) ch;
    iterator_i++;
    }
    buffer[iterator_i] = '\0';

    // Detect end
    if (ch == EOF && (iterator_i == 0 || ferror(fp)))
    {
        free(buffer);
        return NULL;
    }
    return buffer;
}

int main(){
    unsigned int i, len, temp;
    unsigned char * str = NULL, buf[3] = {'\0'}, data[22] = {'\0'}, *ptr = NULL, fn[30] = {'\0'}, ch;
    FILE *fp = NULL;


    printf("Enter FileName: ");
    scanf("%s", fn);

    fp = fopen(fn, "rb");
    while ((str = readline(fp, 0)) != NULL)
    {
        printf("string: %s\n", str);
        if(str[0] == ':' || strlen(str) <= 44){
            len = strlen(str) - 1;
            temp = 0;
            for(i = 1 ; i < len-1 ; i += 2){
            strncpy(buf, &str[i], 2);
                buf[2]='\0';
                data[temp] = (unsigned char) strtoul(buf,(char ** __restrict__) &ptr, 16);
                temp++;
            }
            if(len % 2 == 1){
                buf[0] = '0';
                strncpy(&buf[1], &str[i],1);
            }
            else{
                strncpy(buf, &str[i],2);
            }
            buf[2]='\0';
            data[temp] = (unsigned char) strtoul (buf,(char ** __restrict__) &ptr, 16);
            temp += 1;
            data[temp] = '\0';
            for(i = 0 ; i < temp ; i++ ){
                printf("%X", data[i]);
            }
            printf("\n");
        }
        else{
            printf("Error in hex record; file is corrupt.");
            exit(1);
        }

    }
    return 0;
}

So, when the value of str is ":DEAD" my output should be "DEAD" but I'm getting "DEAD0" as output.

I've tried checking my logic several times but was not able to find the fault.. Please help me.

Thanks in advance.

  • Why doing a realloc at each character ? You just have to read the 2 first ascii char after the `:`and convert them to the number of bytes in the line – Guillaume Petitjean Nov 28 '19 at 08:36
  • The length of the data field of a line of data is necessarily even: one byte of data is represented by two hexanumeric characters and then two ascii characters – Guillaume Petitjean Nov 28 '19 at 08:41
  • You want to convert a line `:DEAD`in an array of two chars `[0xDE, 0xAD]` right ? – Guillaume Petitjean Nov 28 '19 at 08:51
  • Should be easy to find the bug, if youd debug step by step. – Guillaume Petitjean Nov 28 '19 at 08:53
  • I want to read a hex file in line by line manner (in binary mode) and then write it to another hex file (in binary mode). – HARSH GUPTA Nov 28 '19 at 09:30
  • When the length of string is odd for example ```:ABC``` then the code is working properly but if the length is even ```:ABCD```, then the program is writing ```ABCD0``` to the file. And I'm not able to find extra null (If I'm writing it). or what else is going wrong – HARSH GUPTA Nov 28 '19 at 09:32
  • Then why do you convert ascii characters to unsigned ling with strtoul ? Just copy the line to another ascii file. What you want to do is not clear – Guillaume Petitjean Nov 28 '19 at 09:35
  • In a real hex file I don't think you may have odd length lines – Guillaume Petitjean Nov 28 '19 at 09:36
  • Please provide a [example] for us to see the problem demonstrated. If you're working on Windows for example, there is most probably a '\r' before the '\n'. – the busybee Nov 28 '19 at 17:45

0 Answers0