抛出未处理的异常:读取访问冲突。 x 是 0x20B4112
Posted
技术标签:
【中文标题】抛出未处理的异常:读取访问冲突。 x 是 0x20B4112【英文标题】:Unhandled exception thrown: read access violation. x was 0x20B4112 【发布时间】:2020-12-26 18:11:31 【问题描述】: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 != '\0'; 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 循环中)出现错误
【问题讨论】:
k != '\0'
您并不想将数组中的索引与数组中的字符值进行比较。
当x[1]
是小数点时j
会有什么值(例如,如果用户输入1.23
)?
如果字符串根本不包含小数点,你认为第一个循环会做什么?例如"2"
.
就风格而言,您不需要i
和k
。只需使用j
作为两个循环中的循环控制变量。这样您就不需要复制以下值:for (j = 1; x[j] != ‘.’; ++j)
,然后在两个循环之间将j
递增到小数点后使用++j;
,然后运行第二个循环for ( ; x[j] != ‘\0’; ++j)
。
此外,那些重复除以 10 会引入累积的舍入误差。如果您只是将小数点右侧的数字累加为整数值,您将获得更准确的结果,就像第一个循环一样,然后除以std::pow(10, n)
,其中n
是您的位数锯。
【参考方案1】:
有两个错误:
-
对于第二个循环,将条件更改为
x[k] != '\0'
。
变量factor
应初始化为0.1
。
另外,为了避免一些运行时错误(例如,在 0.908 的情况下),从索引 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] != '\0'; 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
值,可能会有精度损失。阅读此article。
【讨论】:
以上是关于抛出未处理的异常:读取访问冲突。 x 是 0x20B4112的主要内容,如果未能解决你的问题,请参考以下文章
抛出未处理的异常:写访问冲突。 bunnies_array 是 0x5CB3CBA