uint64_t в массив - C язык - PullRequest
       62

uint64_t в массив - C язык

2 голосов
/ 22 марта 2020

Я попытался разобрать массив uint64_t в массив символов char (результат в десятичном виде, разделенных запятой).

Я использовал memcpy, каждый раз, когда получаю случайные значения. Функция iota () конвертирует максимальные значения uint32_t. Я пробовал отделить uint64_t от 2 uint32_t, но я никогда не получил правильный результат.

    uint64_t numbers[10] = { 201234567890123456, 
                           12345678901234567890, 
                           98765432109876543, 
                           65432109887, 
                           12345234512345,
                           217631276371261627,
                           12354123512453124,
                           2163521442531,
                           2341232142132321,
                           1233432112 };
    char array[1000] = "";

Ожидаемый результат:

array = "201234567890123456,12345678901234567890,98765432109876543,65432109887,12345234512345,217631276371261627,12354123512453124,2163521442531,2341232142132321,1233432112"

Я пробовал int64ToChar из this topi c, но результат:

    void uint64ToChar(char a[], int64_t n) {
         memcpy(a, &n, 10);
    }

    uint64_t number = 12345678900987654;
    char output[30] = "";

    uint64ToChar(output, number);

    Result:
    �g]T�+

Спасибо за любую помощь.

Ответы [ 4 ]

2 голосов
/ 23 марта 2020

Если все данные доступны во время компиляции, нет очевидной причины, по которой вам следует использовать медленные функции преобразования во время выполнения, такие как s * printf. Просто сделайте все это на этапе препроцессора:

#define INIT_LIST           \
  201234567890123456,       \
  12345678901234567890,     \
  98765432109876543,        \
  65432109887,              \
  12345234512345,           \
  217631276371261627,       \
  12354123512453124,        \
  2163521442531,            \
  2341232142132321,         \
  1233432112

#define STR_(...) #__VA_ARGS__
#define STR(x) STR_(x)

int main (void)
{
  uint64_t numbers[10] = { INIT_LIST };
  char array[] = STR(INIT_LIST);
  puts(array);
}

Возможны более сложные альтернативы с «макросами X», если вы хотите микроуправлять запятой и пробелом между числами et c.

Обратите внимание, что 12345678901234567890 слишком велико, чтобы быть действительной целочисленной константой со знаком в моей 64-битной системе, максимальное значение равно 2^63 - 1 = 9.22*10^18, но это число 12.34*10^18. Я должен изменить его на 12345678901234567890ull, чтобы эта программа компилировалась, так как максимальное число тогда будет 18.44*10^18.

2 голосов
/ 22 марта 2020

Ue snpintf() для преобразования 64-битных чисел:

#include <inttypes.h>
#include <stdio.h>
#include <stdint.h>

int main() {
    uint64_t numbers[10] = { 201234567890123456, 
                             12345678901234567890, 
                             98765432109876543, 
                             65432109887, 
                             12345234512345,
                             21763127637126371627,
                             12354123512453124,
                             2163521442531,
                             2341232142132321,
                             1233432112 };
    char array[1000];
    size_t i, n = sizeof(numbers) / sizeof(numbers[0]), pos = 0;

    for (i = 0; i < n && pos < sizeof(array); i++) {
        pos += snprintf(array + pos, sizeof(array) - pos, "%"PRIu64"%s", numbers[i],
                        i < n - 1 ? "," : "");
    }
    printf("%s\n", array);
    return 0;
}
1 голос
/ 22 марта 2020

Функция memcpy копирует побайтно из одного места в другое. То, что вы пытаетесь сделать, - это взять 10 байтов 64-битного числа (которое содержит только 8 байтов) и заново интерпретировать каждый из них как символ ASCII. Это не только не даст ожидаемых результатов, но вы также вызовете неопределенное поведение , читая за пределами памяти объекта.

Гадать, что делают функции, это плохо способ выучить C. Вам нужно прочитать документацию по этим функциям (запустите "man имя_функции" на Linux для рассматриваемой функции или найдите docs.microsoft.com для MSV C), чтобы понять, что они делают.

Если Вы используете функцию sprintf, вы можете преобразовать 64-битное целое число в строку. Идентификатор %lld принимает long long int, который по крайней мере такой же большой, как uint64_t.

sprintf(a, "%lld", (unsigned long long)n);
1 голос
/ 22 марта 2020

Вы можете выполнить sh, используя sprintf_s в for l oop.

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

#define BUFSIZE 22                  /* string buffer size to support a single 64 bit unsigned integer */
#define ARRSIZE 10                  /* size of the unsigned integer array */
#define STRSIZE BUFSIZE * ARRSIZE   /* max size of the string of unsigned integer array */

int main()
{
    int i;
    char num_str[STRSIZE] = "";
    uint64_t num_arr[ARRSIZE] = {
        201234567890123456,
        12345678901234567890,
        98765432109876543,
        65432109887,
        12345234512345,
        2176312763712637162,
        12354123512453124,
        2163521442531,
        2341232142132321,
        1233432112
    };

    for (i = 0; i < ARRSIZE; i++)
    {
        /* convert an unsigned integer to a string and concatenate to previous string every loop */
        sprintf_s(num_str + strlen(num_str), BUFSIZE, "%llu,", num_arr[i]);
    }

    num_str[strlen(num_str) - 1] = 0;   /* truncate the trailing comma */

    printf("%s", num_str);

    return 0;
}

В результате:

num_str = "201234567890123456,12345678901234567890,98765432109876543,65432109887,12345234512345,2176312763712637162,12354123512453124,2163521442531,2341232142132321,1233432112"
...