抛出未处理的异常:读取访问冲突。 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". 就风格而言,您不需要ik。只需使用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:对于较大的floatdouble 值,可能会有精度损失。阅读此article。

【讨论】:

以上是关于抛出未处理的异常:读取访问冲突。 x 是 0x20B4112的主要内容,如果未能解决你的问题,请参考以下文章

PeekMessage() 抛出未处理的异常(访问冲突)

抛出未处理的异常:写访问冲突。 bunnies_array 是 0x5CB3CBA

在 TPL 中快速抛出未处理的异常

Xcode升级后iOS项目抛出未处理的异常

抛出异常:读取访问冲突。 **bp** 为 0xFFFFFFFFFFFFFFFF

Visual C ++ - 从设置表单图标中抛出未处理的异常?