-1

I program small devices, which communicate with each other and I need to label every action (and there are a lot) with an unique ID. Because of the architecture I can't use anything bigger than int (4 byte). So I had the idea to store the ID as a char array which I increment every time I call a certain function in a scenario like this:

void increaseIDByOne(char *ID){
  //increase "string"
}

int main (int argc, char *argv[]){
  char ID [12] = "00000000000";
  while(true){
    doStuff(&ID); 
    increaseIDByOne(&ID);
  }
}

The problem I have is, that I don't know how to manipulate the "string" without casting it temporarily to a arithmetic type. After reaching the value "99999999999" as an ID, the system then should have a solution, by allocating more space for the number or by using some other solution to prevent overflows or doubled IDs. I hope that you can provide me with the right ideas, so I can find a solution for my problem.

schande
  • 576
  • 12
  • 27

2 Answers2

1

The absence of negative numbers made the problem quite simpler. Simplr use realloc whenever there is a chance of overflow:

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

void increaseIDByOne(char *ID){
  //increase "string"
  size_t len = strlen(ID);
  int all9 = 1;
  //int carry = 0;
  for(size_t i=0;i<len;i++)
  {
    if(ID[i]=='9')
        continue;
    else
    {
        all9 = 0;
        break;
    }
  }
  if(all9)
  {
    ID = realloc(ID, len + 2);
    ID[len] = '0';
  }
  len = strlen(ID);
  for(size_t i=len-1;i>=0;i--)
  {
    if(ID[i]=='9')
    {
        ID[i] = '0';
    }
    else if(ID[i]<'9')
    {
        ID[i]++;
        return;
    }
    //printf("%c\n", ID[i]);
  }
}

int main (int argc, char *argv[]){
  char *ID = malloc(12);
  strcpy(ID, "99999999995");
  while(1){
    //doStuff(&ID); 
    increaseIDByOne(ID);
    printf("%s\n",ID);
  }
}

Output:

99999999996
99999999997
99999999998
99999999999
999999999991
999999999992
999999999993
999999999994
999999999995
999999999996
999999999997
999999999998
999999999999
9999999999991
9999999999992
9999999999993
9999999999994
9999999999995
9999999999996
9999999999997
9999999999998
9999999999999
99999999999991
99999999999992
99999999999993
99999999999994
99999999999995
99999999999996
99999999999997
99999999999998
99999999999999
and so on...
Abhishek Keshri
  • 3,074
  • 14
  • 31
  • Nope, the PO want to have memory allocation in case of overflow ;) Even if it's "useless" since it can go on "overflow" for quite a time. – Tom's Apr 24 '18 at 16:20
  • nope, the memory is fixed. the OP doesn;t want memory allocation – Abhishek Keshri Apr 24 '18 at 16:21
  • Quoting PO : After reaching the value "99999999999" as an ID, the system then should have a solution, by allocating more space for the number or by using some other solution to prevent overflows or doubled IDs. – Tom's Apr 24 '18 at 16:22
  • Well, no. What come after "99999999999" is not "999999999991" but "100000000000". You're not so far ;) – Tom's Apr 25 '18 at 07:33
  • I think that's irrelevant if we are going to use it as an id, but that will be logical. I will edit it as soon as I am free. – Abhishek Keshri Apr 25 '18 at 07:35
0

This is one implementation possible :

#include <stdlib.h>
#include <stdio.h>
#include <stddef.h>
#include <stdbool.h>
#include <string.h>
#include <errno.h>

typedef struct id {
    char   *str;
    size_t strLen;
} id_s;

#define ID_CONSTRUCTOR {.str    = NULL,\
                        .strLen = 0}

void Id_Constructor(id_s *self)
{
    id_s tmp = ID_CONSTRUCTOR;

    *self = tmp;
}

void Id_Destructor(id_s *self)
{
    free(self->str);
}

bool Id_Init(id_s *self, size_t nbDigit)
{
    // Checking (assert ?)
    if (nbDigit == 0) {
        fprintf(stderr, "%s : nbDigit can't be 0.\n", __func__);
        return (false);
    }
    // Memory allocation
    free(self->str);
    if (!(self->str = malloc(nbDigit + 1))) {
        fprintf(stderr, "%s : malloc(nbDigit + 1) : nbDigit=%zu, errno='%s'.\n", __func__, nbDigit, strerror(errno));
        return (false);
    }
    // initialization
    self->strLen = nbDigit;

    self->str[0] = self->strLen == 1 ? '0' : '1';
    for (size_t i = 1; i < self->strLen; ++i) {
        self->str[i] = '0';
    }
    self->str[self->strLen] = '\0';

    return (true);
}

bool Id_Increment(id_s *self)
{
    char *idTmp;

    for (int i = self->strLen - 1; i >= 0; --i) {
        if (self->str[i] == '9') {
            self->str[i] = '0';
        } else {
            ++self->str[i];
            return (true);
        }
    }

    if (!(idTmp = realloc(self->str, self->strLen + 2))) {
        fprintf(stderr, "%s : realloc(self->str, self->strLen + 2) : self->str='%s', self->strLen=%zu, errno='%s'.\n", __func__, self->str, self->strLen, strerror(errno));
        return (false);
    }
    self->str = idTmp;
    self->str[0] = '1';
    self->str[self->strLen] = '0';
    self->str[self->strLen + 1] = '\0';
    ++self->strLen;
    return (true);
}

int main (void)
{
    id_s id = ID_CONSTRUCTOR;

    if (!Id_Init(&id, 1)) {
        printf("Unable to initialize id.\n");
        return (1);
    }

    printf("%s\n", id.str);
    for (int i = 1; i < 101; ++i){
        Id_Increment(&id);
        printf("%s\n", id.str);
    }

    Id_Destructor(&id);
    return (0);
}
Tom's
  • 2,448
  • 10
  • 22