Использование itoa () приводит к: «присваивание делает указатель из целого числа без приведения» - PullRequest
1 голос
/ 08 февраля 2011

Я работаю над BCD (Binary Coded Decimal) в C и отвечаю за написание различных функций bcd.

Мне нужно закодировать целое число i в буферные символы * s размера n.Функция возвращает 0 в случае успеха или -1 в случае переполнения (для кодирования i требуется буфер больше n).

Вот функция: int bcd_encode(int i, int n, char *s)

и пример ввода:assert(bcd_encode(a, 128, s) == 0);

Я пишу код для функции bcd_encode и исправляю меня, если я ошибаюсь, но я верю в функцию и только в функцию, если у вас есть func(char x[]) и символ func(char *x)они будут одним и тем же?Таким образом, вы можете смотреть на них обоих как на массив символов.Если бы это было вне определения функции, char x[]; был бы массивом символов, а char *x; был бы указателем.

int bcd_encode(int i, int n, char *s){  
    int j = 0;  
    s = itoa(i, s, n+1);  
}

Но это возвращает предупреждение «присваивание делает указатель из целого числа без преобразования» инеопределенный символ для itoa.Я пробовал несколько разных вариантов от

* s = itoa (i);s = итоа (i);s = itoa (i, s, n + 1);

Любая помощь будет принята с благодарностью.Заранее спасибо!

Ответы [ 4 ]

1 голос
/ 08 февраля 2011

Функция возвращает 0 в случае успеха или -1 в случае переполнения (для кодирования i требуется буфер больше n).

И все же вы этого не делаете.

int j = 0;

Зачем это?

s = итоа (i, s, n + 1);

Почему вы назначаете на s?

Я пробовал несколько разных вариантов от

* с = итоа (i); s = итоа (i); s = итоа (i, s, n + 1);

Попытка чего-либо случайным образом до тех пор, пока вы не наткнетесь на тот, который работает, не является хорошим подходом к программированию.

Присвоение или s или * s здесь неуместно и показывает плохое понимание C; Я настоятельно рекомендую получить больше инструкций по языку. После этого вы можете использовать snprintf, например,

#include <stdio.h>
int bcd_encode(int i, int n, char *s){  
    int r = snprintf(s, n, "%d", i);
    return r < n? 0 : -1;  
}

при условии, что s должен заканчиваться NUL и что n включает NUL - эти детали не указаны в вашем описании.

Кстати, это не то, что означает "BCD" - см. http://en.wikipedia.org/wiki/Binary-coded_decimal

1 голос
/ 08 февраля 2011

Вы сказали:

... и поправьте меня, если я ошибаюсь, но я верю в функцию и только в функцию, если бы у вас были некоторые func (char x []) и char func (char * x), они были бы одинаковыми вещь? Таким образом, вы можете смотреть на них обоих как на массив символов. Если бы это было вне определения функции char x []; будет массивом char и char * x; будет указатель.

Было бы лучше рассматривать их как указатели (а не как массивы) внутри функции, но у вас есть ключевой момент - в списках аргументов функции различия между массивами и указателями размыты, но в других местах указатели и массивы разные.

В коде, поскольку предполагается, что itoa() возвращает целое число при отсутствии информации об обратном, вы не можете сохранить это в указателе или в качестве указателя (без использования кувалды, что приведет к повреждению вашего кода ).

Что возвращает itoa()? Это не стандартная функция C (как, ни в ISO / IEC 9899: 1999, ни в POSIX). Википедия предполагает, что он не возвращает значения, поэтому вам не следует нигде присваивать его значение. Linux имеет нестандартное расширение в <stdlib.h> с другим интерфейсом, который возвращает char * (что является значением его второго аргумента). Вы можете смело игнорировать возвращаемое значение; на самом деле, вы также можете выполнить назначение (после включения заголовка), но назначение не разрешено. Вам нужно знать, что функция нестандартна, что у нее есть множество определений, и поэтому вы должны знать, что подходит для вашей платформы, или избегать ее использования (возможно, с помощью snprintf() вместо).


Цитирование связанной страницы руководства Linux:

char* itoa (int __val, char * __s, int __radix)

Преобразовать целое число в строку.

Функция itoa () преобразует целочисленное значение из val в представление ASCII, которое будет храниться в s. Вызывающий отвечает за обеспечение достаточного хранения в с.

Примечание:
Минимальный размер буфера s зависит от выбора radix. Например, если основание равно 2 (двоичное), вам нужно предоставить буфер с минимальной длиной 8 * sizeof (int) + 1 символов, то есть один символ для каждого бита плюс один для ограничителя строки. Использование большего радиуса потребует меньшего минимального размера буфера. Внимание:
Если буфер слишком мал, вы рискуете переполнить буфер. Преобразование выполняется с использованием основание радиуса, которое может быть числом от 2 (двоичное преобразование) до 36. Если основание больше 10, следующей цифрой после «9» будет буква «а».

Если основание равно 10, а значение val отрицательно, знак минус будет добавлен.

Функция itoa () возвращает указатель, переданный как s.

Вы не хотите использовать n+1 как основание.

1 голос
/ 08 февраля 2011
#include <stdlib.h>

Без этого включения компилятор ничего не знает о itoa() и будет считать, что он возвращает int.

0 голосов
/ 08 февраля 2011

itoa () не определено означает, что вам не хватает заголовочного файла

 #include < stdlib.h> 

Если это не определено, компилятор предполагает, что неизвестная функция itoa () возвращает int (по глупым историческим причинам).

Всегда слушайте предупреждения компилятора - они ваши друзья!

...