Преобразование строки в число с плавающей точкой или целое число без использования встроенных функций (например, atoi или atof) - PullRequest
0 голосов
/ 08 октября 2018

Я новичок в C ++, и наш учитель попросил нас получить функцию, которая выполняет вышеуказанный заголовок.Пока у меня есть функция, которая преобразует строку в целое число, но я понятия не имею, как изменить , чтобы она работала, если числа в строке будут представлять число с плавающей точкой.

int convert(char str[], int size) {
    int number = 0;
    for (int i = 0; i < size; ++i) {
        number += (str[i] - 48)*pow(10, (size - i - 1));
    }
    return number;
}

Если я бегу:

char myString[] = "12345";
convert(myString, 5);

Я получаю:

12345

Но если я бегу:

char myString[] = "123.45";
convert(myString, 5);

Я получаю:

122845

Как я могу изменить свою программу для работы с плавающими тоже?Я знаю, что функция convert предназначена для возврата типа int, так что мне следует использовать еще две функции?

Я думал о том, что определяет, предназначена ли строка для преобразования в целое число или строку, и о другом, который фактически преобразует строку в число с плавающей точкой.

Ответы [ 3 ]

0 голосов
/ 08 октября 2018

Для части с плавающей запятой: как насчет регулярных выражений?Это также своего рода встроенная функциональность, но общего назначения, не предназначенная для вашей конкретной задачи, поэтому я надеюсь, что ваш учитель будет в порядке с этой идеей.

Вы можете использовать следующее регулярное выражение: [+-]?([0-9]*[.])?[0-9]+ (Я получил от этот ответ ), чтобы определить, является ли предоставленная строка числом с плавающей запятой.Затем вы можете немного изменить выражение, чтобы захватить знаки +/- и части до / после разделителя точек.После того как вы извлечете эти функции, задача должна быть относительно простой.

Также, пожалуйста, измените сигнатуру вашего метода на: float convert(const std::string& str).

0 голосов
/ 08 октября 2018

Попробуйте это:

int convert(char str[], int size) {
    int number = 0;
    for (int i = 0; i < size; ++i) {
        number += (str[i] - 48)*pow(10, (size - i - 1));
    }
    return number;
}

int pow10(int radix)
{
    int r = 1;
    for (int i = 0; i < radix; i++)
        r *= 10;
    return r;
}

float convert2float(char str[], int size) {       //size =6
    // convert to string_without_decimal
    char str_without_decimal[10];
    int c = 0;
    for (int i = 0; i < size; i++)
    {
        if (str[i] >= 48 && str[i] <= 57) {
            str_without_decimal[c] = str[i];
            c++;
        }
    }
    str_without_decimal[c] = '\0';      //str_without_decimal = "12345"

    //adjust size if dot present or not.  If no dot present => size = c
    size = (size != c ?) size - 1 : size;      //size = 5 = 6-1 since dot is present

    //convert to decimal
    int decimal = convert(str_without_decimal, size);  //decimal = 12345

    //get divisor
    int i;
    for (i = size; i >= 0; i--) {
        if (str[i] == '.') break;
    }
    int divisor = pow10(size - i);     //divisor = 10;
    return (float)decimal/(float) divisor;  // result = 12345 /10
}

int main()
{
    char str[] = "1234.5";
    float f = convert2float(str, 6);
    cout << f << endl;
    return 0;
}
0 голосов
/ 08 октября 2018

Вот функция для этого ...

template<class T, class S>
T convert_string_to_number(S s)
{
    auto result = T(0.l);
    if (s.back() == L'F' || s.back() == L'f')
        s = s.substr(0u, s.size() - 1u);
    auto temp = s;
    auto should_add = false;
    if (!std::is_floating_point<T>::value)
    {
        should_add = temp.at(temp.find_first_of(L'.') + 1) >= '5';
        temp.erase(temp.begin() + temp.find_first_of(L'.'), temp.end());
    }
    else if (temp.find_first_of(L'.') != S::npos)
        temp.erase(temp.begin() + temp.find_first_of(L'.'));
    for (int i = temp.size() - 1u; i >= 0; --i)
        if (temp[i] >= L'0' && temp[i] <= L'9')
            result += T(std::powl(10.l, temp.size() - i - 1.l) * (temp[i] - L'0'));
        else
            throw std::invalid_argument("Invalid numerical string!");
    if (s.find(L'-') != S::npos)
        result = -T(std::fabs(result));
    if (s.find(L'.') != S::npos && std::is_floating_point<T>::value)
        result /= T(std::powl(10.l, s.size() - s.find(L'.') - 1.l));
    return std::is_floating_point<T>::value ? T(result) : T(result + T(should_add));
}

Просто используйте его, как обычно ...

auto some_number = convert_string_to_number<float>(myString); ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...