Использование itoa () приводит к следующему: назначение делает указатель из целого числа без приведения

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

Мне нужно закодировать целое число i в буферные char * размера 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[]) и char 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 = itoa (i); s = itoa (i, s, n + 1);

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


person Grant    schedule 08.02.2011    source источник
comment
Может быть, вы хотите вернуть int в конце функции?   -  person Peyman    schedule 08.02.2011
comment
itoa только MSVC ++ (AFAIK). Это не стандартный C.   -  person Mateen Ulhaq    schedule 08.02.2011
comment
Это не стандартный C, но он широко применяется.   -  person payne    schedule 08.02.2011


Ответы (4)


Вы сказали:

... и поправьте меня, если я ошибаюсь, но я верю в функцию и только в функцию, если бы у вас были некоторые функции 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.

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

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

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

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

person Jonathan Leffler    schedule 08.02.2011
comment
Ах, спасибо, что поправили меня в первой части. Я полагал, что itoa() вернет значение char. - person Grant; 08.02.2011
comment
Вместо того, чтобы верить во что-то, поищите их. Вы будете намного счастливее от этого, как и ваши работодатели, коровы и клиенты. - person Jim Balter; 08.02.2011

#include <stdlib.h>

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

person payne    schedule 08.02.2011
comment
хм, у меня был stdio.h, а не stdlib, но он все еще выдает ошибку (так что я буду продолжать копать) - person Grant; 08.02.2011
comment
Это не стандартный C, поэтому расположение #include может отличаться. См. Документацию для вашей системы / компилятора. - person payne; 08.02.2011

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

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

int j = 0;

Что то, что для?

s = itoa (i, s, n + 1);

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

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

* s = itoa (i); s = itoa (i); s = itoa (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

person Jim Balter    schedule 08.02.2011

itoa () undefined означает, что вам не хватает файла заголовка

 #include <stdlib.h> 

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

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

person Martin Beckett    schedule 08.02.2011
comment
Я учился больше прислушиваться к ошибкам компилятора. Несмотря на то, что я добавил ‹stdlib.h›, он все равно выдает ту же ошибку ... Я думаю, что это что-то с моим char * s - person Grant; 08.02.2011
comment
это означает, что у вас нет itoa () - проверьте документацию вашего компилятора, у вас, вероятно, есть что-то с похожим именем, например. _itoa () - person Martin Beckett; 08.02.2011