Функция atoi

Рейтинг: 0Ответов: 3Опубликовано: 07.06.2011

Проблема вся в том, что atoi преобразует мне строку из цифр в коды таблицы ascii. К примеру, если строка = "7", то он мне преобразует эту строку в число 55, если число однозначное, то, конечно, можно вычитать 48 и все совпадет. Но если число двухзначное, то так уже не сделать. Дальше приведен кусок когда где я это использую.

void ReadListP(int* masP, char* cListP, int sizeP)
{
    int i=0;
    int j=0;
    char temp[100]="";
    char str[100]="";
    char symbol=',';
    for(int j=0; j<=sizeP; j++){
            if(cListP[j]!=symbol){
                sprintf_s(temp, "%d", cListP[j]);
                strcat_s(str,temp );                
            }
            else{
                sprintf_s(temp,"%d",str);
                masP[i]=atoi(temp);
                sprintf_s(str,"%d","");
                i++;            
            }
            j++;
        }
    masP[i]=atoi(str);
}

Что-то читал про использование юникода, но так и не понял, при чем тут это... Кто знает, подскажите, пожалуйста, что я не так делаю?

Ответы

▲ 3

Это потому, по-моему, что вы вот тут (temp, "%d", cListP[j]) переводите символы в их коды (%d - трактовать аргумент как целое число), которые с помощью atoi превращаются обратно в числа =D Смотрите неправильно работающий код в отладчике - там такое видно.

То есть, вы неправильно разделяете строку на элементы. К слову, сделать это можно гораздо проще и без таких загогулин с пользованием sprintf и strcat.

▲ 2

Ну, для начала, Вы с аргументами sprintf_s() напутали. Не понимаю почему не ругается компилятор.

Должно быть sprintf_s (char result_buf, int bufsize, char format [, аргумент]...)

Если допустить, что где-то есть #define sprintf_s sprintf, то становится ясно (по крайней мере для одного единственного символа '7' в cListP[0]).

В sprintf_s(temp, "%d", cListP[j]) (на самом деле, как я понимаю sprintf()) Вы записываете в temp cListP[j], как десятичные цифры (для "7" получим "55") а потом добавляете эти "55" в str. После цикла в str как раз и будет "55".

Так что atoi(str) работает правильно !!!

▲ 2

Вариант 1.

/* допустимый вход - числа, разделенные символами ,.- 
   если изменить delim в аргументе strtok - можно изменить символы-разделители
   например, добавить буквы :-)
   Также ф-ция не проверяет размерности аргументов.
   Предполагается, что cLisP - стандартная 0-terminated C-string,
   а masP - указывает на массив int'ов, причем заведомо бОльший, чем необходимо    */
void ReadListP(int *masP, char* cListP)
{
    char *pch;
    pch = strtok(cListP, ",.- "); // вытаскиваем первый токен до разделителя
    while (pch!=NULL) // пока есть токены
    {
        sscanf(pch, "%i", masP++); // запихаем очередное число в массив.
        // вместо sscanf легко применить atoi
        pch = strtok(NULL, ",.- "); // вытаскиваем следующий элемент строки
    }
}

Вариант 2.

/* допустимый вход - любой поток символов
   ф-ция выдерет все числа из этого потока
   т.е., например, "fdsfds2324" будет обработано как десятичное 2324.    */
std::string x;
int n;
std::getline(std::cin, x, '\n'); // получим строчку до символа перевода строки
std::stringstream y(x); // сделаем удобную штуку - превратим строчку в поток
do
{
    y>>n; //ВНИМАНИЕ! atoi не нужен! как и sscanf! Все делает operator >>
    std::cout<<n<<" "; // выведем число для отладки на экран
    if (y.fail()) // если облажались с выборкой числа и получили что-то несусветное,
    // в n пишется 0 и устанавливает флаг ошибки.
    {
        y.clear(); // очищаем флаг(и) ошибок
        y.ignore();// снимаем с буфера один символ
    }           
}
while (y.good()); // пока есть дата