问题描述
我有问题。 我希望从给定的数字中获取每个数字作为同一数组中的元素。
但是,当我进行编译时,如果将范围从给定数字的大小之上的一次迭代扩展,则我将从Visual Studio的Debug模式中获取损坏的数据异常作为异常。
我首先想到的是因为int类型作为4字节实体的最大长度只有4位,因为我过去只为9999以上的大数获得一位。但是我注意到我的数字也从一个迭代值开始迟了...这使得不可能显示最后一位数字。
如果在给定的数字后加零,则可以手动向相反方向偏移,但这不适用于我的原始数字。
但是,我无法找到解决方法……这是我的代码。 在寻求帮助之前,以下是屏幕截图,解释了用于将数字转换为数组的原理:AvroCoder 我只想用数字类型来解决它,因为char类型涉及另一种使用缓冲区管理内存的方式...我真的不知道该如何处理正确的知识。
有人可以帮我完成调试吗?
#include <iostream>
#include <math.h>
//method to convert user number entry to array of digits
long long numToArray(double num,double arrDigits[],const long long n) {
//instanciate variables
//array of with m elements
arrDigits[n];
double* loopValue = new double(0);
//extract the digits and store them into arrDigits array
for (long long i = 0; i < n; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula
temp += arrDigits[i - k] * pow(10,k);
loopValue = new double(0);
*loopValue = floor(num / pow(10,n - i)) - temp;
arrDigits[i] = *loopValue;
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
return 0;
}
//main program interacting with the user
int main()
{
std::cout << "please type an integer: ";
double num;
const long long n = sizeof(num);
double array[n]{};
std::cin >> num;
//call the method to test if all values are in the array
numToArray(num,array,n);
return 0;
}
注意:如果我从n扩展到n + 1,Visual Studio将显示错误。如果我将类型设为int或long,则sizeof(num)一直都是4 ... 然后,我必须将其设置为double并从主作用域中将其提取出来,从而使其... double ... 人们要求删除指针,否则我将无法运行该程序。
解决方法
我希望从给定的数字中获取每个数字作为同一数组中的元素。
如果要将每个数字简单地放入数组中,只需几行代码即可将小数转换为字符串,删除小数点(如果存在),然后将字符串复制到缓冲区:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <iomanip>
int main()
{
double d = 1.45624234;
std::ostringstream strm;
strm << std::setprecision(12);
// copy this to a string using the output stream
strm << d;
std::string s = strm.str();
// remove the decimal point
s.erase(std::remove(s.begin(),s.end(),'.'),s.end());
// Now copy each digit to a buffer (in this case,vector)
std::vector<int> v;
std::transform(s.begin(),std::back_inserter(v),[&](char ch) { return ch - '0';});
// output the results
for (auto c : v )
std::cout << c;
}
输出:
145624234
标准库已经为您完成了所有工作。在这种情况下,operator <<
的重载double
在流式传输到缓冲区时会创建字符串。怎么做的?这基本上就是您的代码要尝试的操作,但是显然是安全正确的。
然后,只需将每个数字字符转换为代表该数字的实际整数,std::transform
便会这样做。通过从每个字符数减去字符0
,将每个数字字符复制到向量。
#include <iostream>
#include <math.h>
#include <list>
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
//counting the number of digits
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum/10;
++count;
}
std::cout << "number of digits compositing your natural integer: " << count<<std::endl;
//process the value for conversion to list of digits,so you can
//access each digits by power and enhance your calculus operations
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - count;//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10,k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10,containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
std::cout << "digits array value at " << i << " is " << arrDigits[i] << " \n";
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits),std::end(arrDigits));
//print the converted list
std::cout << "array converted to list: ";
for (double j : listDigits) {
std::cout << j << " ";
}
std::cout << std::endl;
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
std::cout << "removed zero element to the list\n";
for (double i : listDigits) {
std::cout << i << " ";
}
std::cout << "natural integer successfully converted into list digits data\n";
return 0;
}
an example on debug mode in Visual Studio 2019
,我最终将整个代码封装为两个函数。但是我在第一次和最后一次迭代中都有额外的价值...
答案几乎是完整的,只需要解决从main移到其拥有的函数内部的偏移量。最后,我从两个新函数中添加了一个具有所需大小的新数组变量,因此我们获得了可以在很远的范围内进行操作的数组。
#include <iostream>
#include <math.h>
#include <list>
int CountNumberDigits(int num) {
int count = 0;
long long CountingNum = static_cast<long long>(num);
while (CountingNum != 0) {
CountingNum = CountingNum / 10;
++count;
}
return count;
}
double* NumToArray(double num) {
double converternum = num * 10;//removing the right offset to keep the last digit
const int containerSize = sizeof(double); //defining array constant size
int sizeRescale = containerSize - CountNumberDigits(num);//set general offset to handle according to the user entry
double arrDigits[containerSize] = {};//initialize array with a sufficient size.
double* loopValue = new double(0); //define pointer variable to make to operation possible
//extract the digits and store them into arrDigits array
for (long long i = 0; i < containerSize; i++) {
long temp = 0;
for (long k = 0; k < i + 1; k++) {
//mathematical general formula adapted to the computation
temp += arrDigits[i - k] * pow(10,k);
loopValue = new double(0); //reinitialize the pointer
*loopValue = floor(converternum / pow(10,containerSize - i)) - temp; //assign the math formula to the pointer
arrDigits[i] = *loopValue;//assigne the formula for any i to the array relatively to k
}
}
//convert array to a list
std::list<double> listDigits(std::begin(arrDigits),std::end(arrDigits));
for (double j : listDigits) {
std::cout << j << " ";
}
//remove the zeros offset and resize the new converted list
for (int j = 0; j < sizeRescale; j++) {
listDigits.pop_front();
}
//convert list to array
double* arrOutput = new double[listDigits.size()]{};
std::copy(listDigits.begin(),listDigits.end(),arrOutput);
double* ptrResult = arrOutput;
return ptrResult;
}
int main()
{
//Entry request of any natural integer within the range of double type
std::cout << "Please type a natural integer from 1 to 99999999\n";
double num;
std::cin >> num;
int count = CountNumberDigits(num);
std::cout << "number of digits compositing your natural integer: " << count << std::endl;
double* ptrOutput = NumToArray(num);
//reduce the array to the num size
double* shrinkArray = new double[CountNumberDigits(num)];
for (int i = 0; i < CountNumberDigits(num); i++) {
*(shrinkArray+i) = ptrOutput[i];
std::cout << *(shrinkArray+i) << " ";
}