Создание функции atoi

Я пытаюсь создать свою собственную функцию atoi. Со следующим я получаю возвращаемое значение 0. Что бы я ни изменил числовую переменную внутри функции, это то, что я получаю в качестве возвращаемого значения. Есть предложения по изменению кода?

//my atoi function
int atoi_me(char *numstring)
{
    int number = 0;
    while((*numstring >= '0') && (*numstring <= '9'))
    {
        number = (number * 10) + (*numstring - '0');
        numstring++;
    }

    return number;
}

int main()
{
    char *number[MAXSIZE];
    int num;

    printf("Please enter a number:\n");
    scanf("%c", &number);
    num = atoi_me(*number);
    printf("%d", num);
    return 0;
}

person KryptNick    schedule 17.04.2013    source источник
comment
Что вы используете в качестве ввода?   -  person Fred Larson    schedule 17.04.2013
comment
Выражение number = (number * 10) всегда будет 0.   -  person    schedule 17.04.2013
comment
@htor, только в первый раз.   -  person Carl Norum    schedule 17.04.2013
comment
@KryptNick, ты уверен, что это твой настоящий код? Мне это кажется прекрасным и хорошо работает в тестовой программе. Какой ввод вы используете?   -  person Carl Norum    schedule 17.04.2013
comment
Мне кажется, все в порядке. У вас нет под рукой отладчика?   -  person Jonathan Wood    schedule 17.04.2013
comment
Я попробовал это, и это сработало нормально.   -  person Fred Larson    schedule 17.04.2013
comment
Это должно работать, какую строку вы передаете ему?   -  person parkydr    schedule 17.04.2013
comment
попробуйте число = (число * 10) + ((int)(*numstring - '0'));   -  person Infested    schedule 17.04.2013
comment
Кажется, у меня все работает нормально, можете ли вы привести несколько проблемных примеров ввода?   -  person Kninnug    schedule 17.04.2013
comment
@infested, этот тип ничего не даст. *numstring и '0' оба уже повышены до int до того, как произойдет вычитание. Код OP в порядке, его ввод должен быть неправильным.   -  person Carl Norum    schedule 17.04.2013
comment
Я передаю указатель char из основной функции. Я собираюсь попробовать запустить в другом компиляторе.   -  person KryptNick    schedule 17.04.2013
comment
Если вы не передаете что-то вроде +1234 или -1234 или 1234 (т.е. начальный символ не является цифрой) - ваша программа должна работать нормально. Каков ваш вклад? Вставьте свой вызов функции ine - это, вероятно, проблема   -  person user93353    schedule 17.04.2013
comment
int main() { char *number[MAXSIZE]; целое число; printf(Пожалуйста, введите число:\n); сканф(%с, &число); число = atoi_me (* число); printf(%d, число); вернуть 0; }   -  person KryptNick    schedule 17.04.2013
comment
@KryptNick, другой компилятор не имеет значения. Ваша программа является вполне приемлемым стандартным кодом C. Не могли бы вы показать свою программу main()? Может быть, мы сможем помочь вам найти вашу ошибку там.   -  person Carl Norum    schedule 17.04.2013
comment
char number[MAXSIZE]и scanf("%s", number)и atoi_me(number)   -  person BLUEPIXY    schedule 17.04.2013
comment
Пожалуйста, отредактируйте этот main обратно в исходный вопрос. Проблема действительно есть.   -  person Carl Norum    schedule 17.04.2013
comment
не будет ли %c получать только один символ? и почему у du есть char *number[] как 2D-массив?   -  person Infested    schedule 17.04.2013


Ответы (5)


  1. Вы объявляете массив char *, то есть массив строк, а не одну строку. Вы, вероятно, хотите:

    char number[MAXSIZE];
    
  2. Ваша строка формата scanf неверна. Если вы хотите прочитать строку, вы должны использовать %s. %c читает только один символ.

  3. Ваш параметр scanf неверен - передайте сам number (или &number[0], если хотите), а не &number.

  4. Параметр, который вы передаете atoi_me, неверен. Назовите его с помощью number (или эквивалентно &number[0]), а не *number.

Собрав все это вместе, у вас должна получиться примерно такая процедура main:

int main(void)
{
    char number[MAXSIZE];
    int num;
    printf("Please enter a number: ");
    scanf("%s", number);
    num = atoi_me(number);
    printf("%d\n", num);
    return 0;
} 

Примечания редактора: У вас есть потенциальное переполнение буфера со строкой scanf. Лучше использовать такую ​​функцию, как fgets(3), которая упрощает защиту от такая проблема.

atoi(3) также традиционно поддерживает отрицательные числа (с ведущим -) и необязательным ведущим + для положительные числа, которые ваша реализация не обрабатывает.

person Carl Norum    schedule 17.04.2013
comment
я думаю, что иметь число в порядке, так как scanf хочет ссылку на переменную no? - person Infested; 17.04.2013
comment
@Infested, number - это массив, поэтому при использовании в этом контексте он превращается в указатель на его первый элемент. Я не совсем понимаю, о чем вы спрашиваете. - person Carl Norum; 17.04.2013
comment
@Infested, тогда я действительно не понимаю. Об этом говорит мой ответ, не так ли? - person Carl Norum; 17.04.2013
comment
Хм, я не помню, чтобы писал что-то другое. Может быть, я поправил его где-то по ходу. - person Carl Norum; 17.04.2013
comment
+1, это был принятый ответ, и он все еще должен быть. Я не собирался воровать его. - person jxh; 17.04.2013
comment
Спасибо @ user315052. Нет кожи с моего носа. - person Carl Norum; 17.04.2013
comment
@Carl Norum Извините, я новичок на этом сайте и подумал, что могу выбрать более одного ответа. Ваш ответ исправил мою проблему - person KryptNick; 18.04.2013

Как я и думал, проблема в твоем звонке.

Измените свой основной на.

int main()
{
    char number[MAXSIZE];
    int num;

    printf("Please enter a number:\n");
    scanf("%s", number);
    num = atoi_me(number);
    printf("%d", num);
    return 0;
}

Помимо этого, не рекомендуется использовать scanf - http://c-faq.com/stdio/scanfprobs.html . В этом случае вы должны использовать fgets.

person user93353    schedule 17.04.2013
comment
@KryptNick - что ты имеешь в виду под «запиранием». Во всяком случае, я пропустил изменение вызова atoi_me. Изменил это сейчас после того, как Карл Норум указал на это. - person user93353; 17.04.2013
comment
извините за это... это не будет продолжаться в функции после ввода. Он просто разбился - person KryptNick; 17.04.2013

Это была не проблема с вашей функцией atoi_me(), а проблема с тем, как вы получили свой ввод. Ваша реализация показывает некоторую слабость в вашем понимании того, как работает scanf(). Это не проблема сама по себе, в конце концов, ошибки — это часть процесса обучения.

Как правило, безопаснее сначала собрать ввод в буфер, потому что scanf() из стандартного ввода слишком сильно зависит от пользователя программы, чтобы ввести ввод именно так, как вы ожидаете. В этом случае особого вреда не будет, так как вам нужна только одна строка ввода. Но, как правило, программа обрабатывает несколько строк ввода, и scanf() может застрять при возникновении ошибки. Итак, вы можете использовать что-то вроде этого, чтобы вместо этого получить строку ввода:

char line[MAXLINESIZE];

if (fgets(line, MAXLINESIZE, stdin) == 0) {
    fprintf(stderr, "no input was provided!\n");
    return 0;
}

Как упоминалось в другом месте, %c — это неправильный спецификатор формата, который следует использовать для ввода, которое вы собираете. Поскольку вам нужны десятичные цифры, семейство *scanf() имеет спецификатор формата, позволяющий собирать только эти символы.

char number[MAXSIZE];

if (sscanf(line, " %[0-9]", number) != 1) {
    fprintf(stderr, "no number found in input: %s", line);
    return 0;
}

Здесь я использую line, полученный с помощью fgets(), и анализирую часть ввода, содержащую цифры. Ведущий пробел заставляет sscanf() пропускать символы пробела, ведущие к цифрам.

person jxh    schedule 17.04.2013
comment
Спасибо за этот пост. Я вижу, что хорошее знание библиотечных функций определенно может избавить от головной боли. - person KryptNick; 17.04.2013
comment
Я не хотел красть принятый ответ у @CarlNorum. Эта информация дополняет его ответ. - person jxh; 17.04.2013

Поскольку number должен быть массивом символов,

  • вы должны объявить его как char number[MAXSIZE];,
  • вы не должны вызывать свою функцию с &number, но с number напрямую: atoi_me(number);
person Fabien    schedule 17.04.2013

Некоторые комментарии:

int atoi_me(const char *numstring)...

Лучше использовать указатель типа const, так как вы не собираетесь изменять содержимое строки.

int main()
{
    char number[MAXSIZE]; // array of chars
    int num;

    printf("Please enter a number:\n");
    scanf("%s", number);     // enter a string, not a char
    num = atoi_me(number);   // pointer to char, not pointer to pointer
    printf("%d", num);
    return 0;
}
person Valeri Atamaniouk    schedule 17.04.2013