#c
#c
Вопрос:
using namespace std;
float str_to_float(char x[]) {
int j;
float val1 = x[0] - '0';
float val2=0,factor=1;
for (int i = 1; x[i] != '.'; i ) {
val1 = (val1 * 10) (x[i] - '0');
j = i;
}
for (int k = j 2; k != ''; k ) {
**val2 = val2 (x[k] - '0')*factor;**
factor /= 10;
}
return val1 val2;
}
int main() {
char x[1000];
cin.getline(x, 1000);
cout<<str_to_float(x);
return 0;
}
Эта функция должна возвращать значение с плавающей запятой строки, содержащей число с плавающей запятой.
При отладке «нарушения доступа для чтения» в строке, выделенной жирным шрифтом (во втором цикле for), возникает ошибка
Комментарии:
1.
k != ''
На самом деле вы не хотите сравнивать индекс в массиве со значением char из массива.2. Какое значение будет
j
иметьx[1]
десятичная точка (например, если пользователь вводит1.23
)?3. Как вы думаете, что будет делать первый цикл, если строка вообще не содержит десятичной точки? Например
"2"
.4. С точки зрения стиля, вам не нужно
i
иk
. Просто используйтеj
в качестве управляющей переменной цикла в обоих циклах. Таким образом, вам не нужно копировать значения вокруг:for (j = 1; x[j] != ‘.’; j)
, затем между двумя циклами увеличивайтеj
значение после десятичной точкиj;
, а затем запускайте второй циклfor ( ; x[j] != ‘’; j)
.5. Кроме того, эти повторяющиеся деления на 10 приводят к накоплению ошибок округления. Вы получите более точный результат, если просто сложите цифры справа от десятичной запятой в виде целого значения, как и в первом цикле, затем разделите на
std::pow(10, n)
, гдеn
— количество цифр, которые вы видели.
Ответ №1:
Есть 2 ошибки:
- Для второго цикла измените условие на
x[k] != ''
. - Переменная
factor
должна быть инициализирована0.1
.
Кроме того, чтобы избежать некоторых ошибок во время выполнения (например, в случае 0.908), запустите первый цикл из index 0
, чтобы переменная j
имела допустимое значение перед запуском второго цикла.
Взгляните на следующую реализацию:
#include <iostream>
#include <iomanip>
double str_to_double(char x[]) {
int j;
double val1 = 0, val2 = 0.0, factor = 0.1;
for (int i = 0; x[i] != '.'; i ) {
val1 = (val1 * 10) (x[i] - '0');
j = i;
}
for (int k = j 2; x[k] != ''; k ) {
val2 = val2 (x[k] - '0')*factor;
factor /= 10;
}
return val1 val2;
}
int main() {
char x[1000];
std::cin.getline(x, 1000);
std::cout<<std::setprecision(15)<<str_to_double(x);
return 0;
}
Тестовые примеры:
- Тестовый пример 1: ввод:
34.908
, вывод:34.908
- Тестовый пример 2: ввод:
0.908
, вывод:0.908
- Тестовый пример 3: ввод:
000006795.989090877700000
, вывод:6795.9890908777
PS: При больших значениях float
и double
может быть потеря точности. Прочитайте эту статью.