使用指针逐位将整数转换为动态分配的Char数组

时间:2017-01-04 10:29:17

标签: c pointers dynamic-arrays dynamic-allocation

我需要将Integer转换为Char,我只能使用没有数组索引的指针。必须动态分配字符数组。任何人都可以查看我的代码并告诉我我做错了什么吗?

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

int main(){

    int myNumber = 1234;
    char *myString = (char*)malloc(2 * sizeof(char));  //memory for 1 char and '\0'
    int i = 0; //parameter for tracking how far my pointer is from the beggining

    if (myNumber < 0){
        *myString = '-';    //if myNumber is negative put '-' in array
        *myString = *(myString + 1);    //move pointer to next position
        i++;
    }

    while (myNumber != 0){

        myString = (char*)realloc(myString, (i + 2) * sizeof(char));    //increse memory =+1
        *myString = (myNumber % 10) + '0'; //put digit as char to array
        myNumber /= 10;

        *myString = *(myString + 1);    //move pointer to next position

        i++;
    }
    *myString = '\0';   //mark end of string
    *myString = *(myString - i);    //move pointer back to the beggining of string

    printf("\n%s", *myString); // print char array (not working..)

    return 0;
}

我知道有更好的方法将Int转换为String(sprintf),但我的任务是这样做。 在上面的代码中,我从Int向后取数字,可以按正确的顺序完成吗?

修改。正如评论中提到的部分:

*myString = *(myString + 1);

错误,将指针重定向到一个空格的正确方法是:

myString++;

同样:

*myString = *(myString - i);    //wrong
myString -=i;    //ok

EDIT2: 现在我的代码工作了!但我需要考虑如何纠正数字的顺序。

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

int main(){

    int myNumber = 1234;
    char *myString = (char*)malloc(2 * sizeof(char));  //memory for 1 char and '\0'
    char * position = myString;

    int i = 0;

    if (myNumber < 0){
        *position = '-';    //if myNumber is negative put '-' in array
        position += i;  //move pointer to next position
        i++;
    }

    while (myNumber != 0){

        myString = (char*)realloc(myString, ((i + 2) * sizeof(char)));  //increse memory =+1
        position = myString + i; // getting current position after reallocating
        *position = (myNumber % 10) + '0'; //put digit to array
        myNumber /= 10;

        position++; //move pointer to next position

        i++;
    }
    *position = '\0';   //mark end of string

    char * temp = myString;

    while (*temp != '\0'){      
        printf("%c", *temp); // print char array (not working..)
        temp++;
    }

    return 0;
}

编辑3问题解决了,感谢您的评论,我发布代码以防任何人寻找类似的解决方案。

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

// move each character in array one place to the right
// we need to make place for new character on the left
void moveArrayElementsRight(char *ptr, int len) {
    for (int j = len; j > 1; j--) {
        *(ptr + j - 1) = *(ptr + j - 2);
    }
}

void intToStr(int myNumber, char* myString){
    int i = 1;    //track size of allocated memory
    bool isMinus = false;

    if (myNumber < 0) {

        myNumber *= -1;    //without this (myNumber % 10) + '0' wont work
        isMinus = true;
    }

    if (myNumber == 0){    //special case for 0

        myString = (char*)realloc(myString, ((i + 1) * sizeof(char)));
        *myString = '0';
        *(myString + 1) = '\0';
    }

    while (myNumber != 0) {

        myString = (char*)realloc(myString, ((i + 1) * sizeof(char)));  //increse memory =+1 for next digit
        i++;
        moveArrayElementsRight(myString, i);
        *myString = (myNumber % 10) + '0'; //put digit to array
        myNumber /= 10;
    }

    if (isMinus) {

        myString = (char*)realloc(myString, ((i + 1) * sizeof(char)));  //increse memory =+1 for '-' sign
        i++;
        moveArrayElementsRight(myString, i);
        *myString = '-'; //put sign at the beginning
    }
}

int main() {

    int numberToConvert = -10;
    char *numberAsString = (char*)malloc(sizeof(char));  //create empty array, with place only for '\0'
    *numberAsString = '\0';    //mark the end of array

    intToStr(numberToConvert, numberAsString);

    printf("%s", numberAsString);

    return 0;
}

1 个答案:

答案 0 :(得分:0)

SPOILER:如果您不想要解决方案,请不要阅读或复制。

以下是使用递归的实现示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <string.h>
#include <time.h>
#include <errno.h>

static size_t int_to_str_size(int n, size_t acc, int base_size) {
  int next = n / base_size;
  if (next != 0) {
    return int_to_str_size(next, acc + 1, base_size);
  } else {
    return n < 0 ? acc + 2 : acc + 1;
  }
}

static void int_to_str_write(int n, char *str, char *base, int base_size) {
  *str = base[abs(n % base_size)];

  int next = n / base_size;
  if (next != 0) {
    int_to_str_write(next, str - 1, base, base_size);
  } else {
    if (n < 0) {
      *(str - 1) = '-';
    }
  }
}

static char *int_to_str(int n, char *base) {
  size_t base_size = strlen(base);
  if (base_size < 2 || base_size > INT_MAX) {
    errno = EINVAL;
    return NULL;
  }

  size_t size = int_to_str_size(n, 0, (int)base_size);
  char *str = malloc(size + 1);
  if (str == NULL) {
    return NULL;
  }

  str[size] = '\0';
  int_to_str_write(n, str + size - 1, base, (int)base_size);

  return str;
}

int main(void) {
  srand((unsigned int)time(NULL));

  for (uintmax_t i = 0; i < 42; i++) {
    int n = rand() % 2 ? rand() : -rand();

    char *str = int_to_str(n, "0123456789");
    if (str != NULL) {
      printf("%d == %s\n", n, str);

      free(str);
    } else {
      perror("int_to_str()");
    }
  }
}