0

I have a pseudoheader in a string, the first 12 bits are the file size, the next 4 are the buffer size, and the last 12 are an offset. I want to store each one of this in a variable, I could get the string values, but atoi is not working properly when converting those to integers The program looks like this:

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

void readheader(char header[29], int filesize, int buffersize, int offset) {
  char fsize[13], bsize[5], oset[13];
  memcpy(fsize, &header[0], 12);
  fsize[12] = '\0';
  memcpy(bsize, &header[12], 4);
  bsize[4] = '\0';
  memcpy(oset, &header[16], 12);
  oset[12] = '\0';
  printf("String Values: filesize: %s, buffersize: %s, offset: %s\n", fsize, bsize, os$
  filesize = atoi(fsize);
  buffersize = atoi(bsize);
  offset = atoi(oset);
}

void main() {
  char test[] = "0000000051422048000000004096";
  int a, b, c;
  readheader(test, a, b, c);
  printf("Integer values: filesize: %d, buffersize: %d, offset: %d\n", a, b, c);
}

And the output looks like this:

String Values: filesize: 000000005142, buffersize: 2048, offset: 000000004096
Integer values: filesize: 0, buffersize: -1036019427, offset: 22039
Gustavo Marin
  • 49
  • 1
  • 7
  • 5
    Remember that arguments to functions are passed *by value*. That means the value is *copied* into the local argument variables, and modifying the local argument variables will not modify the original values. Please do some research about *emulating pass by reference in C* for a way to solve your problem. – Some programmer dude Sep 18 '19 at 08:50
  • As a possible other way to solve your problem, how about creating a `struct` with the `filesize`, `buffersize` and `offset` as members? Then you can `return` a copy of that structure. – Some programmer dude Sep 18 '19 at 08:51
  • 1
    You have leading zeros in the example, so you are not getting a problem, but you should be aware that the maximum integer in a 32 bit system is `2147483647` and a 12 byte string can exceed this. – Rishikesh Raje Sep 18 '19 at 08:58
  • @Someprogrammerdude Thanks, I solved it using pointers. I would have loved a clearer answer though, I'm still new to C. – Gustavo Marin Sep 18 '19 at 09:13
  • @GustavoMarin You can post an answer to your own question. https://stackoverflow.com/help/self-answer – chux - Reinstate Monica Sep 18 '19 at 09:39
  • 1
    [Why shouldn't I use atoi()? (duplicate)](https://stackoverflow.com/q/17710018/995714), [atol() considered harmful](https://blog.mozilla.org/nnethercote/2009/03/13/atol-considered-harmful/) – phuclv Sep 18 '19 at 09:50
  • In case you didn't read @phuclv links: never use `atoi()`. It has **NO** way to indicate any error in parsing its input, thus making error detection literally impossible. – Andrew Henle Sep 18 '19 at 11:21

1 Answers1

0

Arguments in c are passed by value, if you want to modify a variable passed to a function, you need to pass it's memory location instead, then you can modify it

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

/* Using int pointer type instead of int */
void readheader(char header[29], int* filesize, int* buffersize, int* offset) {
  char fsize[13], bsize[5], oset[13];
  memcpy(fsize, &header[0], 12);
  fsize[12] = '\0'; 
  memcpy(bsize, &header[12], 4);
  bsize[4] = '\0';  
  memcpy(oset, &header[16], 12);
  oset[12] = '\0';  
  printf("String Values: filesize: %s, buffersize: %s, offset: %s\n", fsize, bsize, oset);
  /* Dereferencing the pointers */
  *filesize = atoi(fsize); 
  *buffersize = atoi(bsize);
  *offset = atoi(oset);
}

void main() {
  char test[] = "0000000051422048000000004096";   
  int a, b, c;
  /* Passing by reference */
  readheader(test, &a, &b, &c);
  printf("Integer values: filesize: %d, buffersize: %d, offset: %d\n", a, b, c);
}
Andre Augusto
  • 84
  • 1
  • 8