为什么简单的乘法会出现一些乱码?
Why the simple multiplication would result in some garbled characters?
我尝试设计一个程序来实现两个大整数之间的乘法(使用C++)。但是当我完成之后,我发现如果我通过命令参数输入这两个整数,结果有时会很奇怪,有时会正确。请帮我找出原因并告诉我如何解决。谢谢(主要实现两个大整数相乘的函数是 mul() )。
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
只需将您的字符数组初始化为空数组即可:
char cArr1[500] = {};
char cArr2[500] = {};
然后,为了清楚起见,将参数的长度分配给两个整数,并强制转换它们,因为编译器可能会警告您 size_t
和 int
之间不兼容。
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
然后,打印长度 len1
和 len2
仅用于调试目的:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
事实上,正如@Kevin SUN 提到的,您的参数读取步骤可能缺少空字符,但是,在 运行 一些测试之后,它似乎仅通过初始化 char 数组就可以正常工作。
此外,如评论中所述,您需要增加为 res
数组保留的大小,我做到了 500
使用 g++ -Wall main.cpp -o calc.exe
和 运行 编译:calc 10 100
如果不进行初始化,您会遇到如下问题:
初始化后,输出工作正常:
我尝试设计一个程序来实现两个大整数之间的乘法(使用C++)。但是当我完成之后,我发现如果我通过命令参数输入这两个整数,结果有时会很奇怪,有时会正确。请帮我找出原因并告诉我如何解决。谢谢(主要实现两个大整数相乘的函数是 mul() )。
#include <iostream>
#include <cstring>
#include <stdlib.h>
using namespace std;
void mul(char *c1, char *c2, int len1, int len2);
void printArr(char *c1, char *c2, int len1, int len2);
int main(int argc, char **argv)
{
if (argv[1] != NULL)
{
char cArr1[500], cArr2[500];
for (int i = 0; i < strlen(argv[1]); i++)
{
cArr1[i] = argv[1][i];
}
for (int i = 0; i < strlen(argv[2]); i++)
{
cArr2[i] = argv[2][i];
}
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
exit(100);
}
while (true)
{
cout << "Please input two integers" << endl;
char cArr1[500], cArr2[500];
cin >> cArr1;
if (cArr1[0] == 'q' && cArr1[1] == 'u' && cArr1[2] == 'i' && cArr1[3] == 't')
{
exit(1000);
}
cin >> cArr2;
int parity = 0;
int len1 = strlen(cArr1);
int len2 = strlen(cArr2);
printArr(cArr1, cArr2, len1, len2);
if (cArr1[0] == '-')
{
for (int i = 1; i < len1; i++)
{
cArr1[i - 1] = cArr1[i];
}
parity++;
len1--;
}
if (cArr2[0] == '-')
{
for (int i = 1; i < len2; i++)
{
cArr2[i - 1] = cArr2[i];
}
parity++;
len2--;
}
bool isDigit = true;
for (int i = 0; i < len1; i++)
{
if (!isdigit(cArr1[i]))
{
isDigit = false;
}
}
for (int i = 0; i < len2; i++)
{
if (!isdigit(cArr2[i]))
{
isDigit = false;
}
}
if (!isDigit)
{
cout << "\rInvalid input. Try again" << endl;
continue;
}
if (parity % 2 != 0)
{
cout << "-";
}
(len1 > len2) ? mul(cArr1, cArr2, len1, len2) : mul(cArr2, cArr1, len2, len1);
}
}
void mul(char *bigger, char *smaller, int bigLen, int smallLen)
{
int *bigNum = new int[bigLen];
int *smallNum = new int[smallLen];
for (int i = 0; i < bigLen; i++)
{
bigNum[i] = bigger[bigLen - i - 1] - '0';
}
for (int i = 0; i < smallLen; i++)
{
smallNum[i] = smaller[smallLen - i - 1] - '0';
}
int res[30];
for (int i = 0; i < 30; i++)
{
res[i] = 0;
}
for (int i = 0; i < smallLen; i++)
{
for (int j = 0; j < bigLen; j++)
{
res[i + j] += bigNum[j] * smallNum[i];
}
}
for (int i = 0; i < bigLen + smallLen; i++)
{
int digit = res[i] % 10;
int carry = res[i] / 10;
res[i] = digit;
res[i + 1] += carry;
}
bool null = false;
for (int i = bigLen + smallLen - 1; i >= 0; i--)
{
if (res[i] != 0 && res[i + 1] == 0)
{
null = true;
}
if (null)
{
cout << res[i];
}
}
cout << endl;
}
void printArr(char *c1, char *c2, int len1, int len2)
{
for (int i = 0; i < len1; i++)
{
cout << c1[i];
}
cout << " * ";
for (int i = 0; i < len2; i++)
{
cout << c2[i];
}
cout << " = ";
}
只需将您的字符数组初始化为空数组即可:
char cArr1[500] = {};
char cArr2[500] = {};
然后,为了清楚起见,将参数的长度分配给两个整数,并强制转换它们,因为编译器可能会警告您 size_t
和 int
之间不兼容。
int lenArg1 = 0;
int lenArg2 = 0;
lenArg1 = (int)strlen ( argv[1] );
lenArg2 = (int)strlen ( argv[2] );
然后,打印长度 len1
和 len2
仅用于调试目的:
int len1 = strlen ( cArr1 );
int len2 = strlen ( cArr2 );
cout << "len1 >> " + to_string(len1) <<endl;
cout << "len2 >> " + to_string(len2) <<endl;
事实上,正如@Kevin SUN 提到的,您的参数读取步骤可能缺少空字符,但是,在 运行 一些测试之后,它似乎仅通过初始化 char 数组就可以正常工作。
此外,如评论中所述,您需要增加为 res
数组保留的大小,我做到了 500
使用 g++ -Wall main.cpp -o calc.exe
和 运行 编译:calc 10 100
如果不进行初始化,您会遇到如下问题:
初始化后,输出工作正常: