如何将数字转为德语单词wstring?C++代码错误排查求助
德语数字转单词代码问题排查
需要将0到10亿之间的数字转换为德语单词形式的wstring,但当前代码存在逻辑错误:输入1001时,预期返回eintausendeins,实际返回nulleins。以下是待排查的代码:
wstring NumberToWords(wstring u) { map<int, wstring> numberWords = { {0, L"null"}, {1, L"eins"}, {2, L"zwei"}, {3, L"drei"}, {4, L"vier"}, {5, L"fünf"}, {6, L"sechs"}, {7, L"sieben"}, {8, L"acht"}, {9, L"neun"}, {10, L"zehn"}, {11, L"elf"}, {12, L"zwölf"}, {13, L"dreizehn"}, {14, L"vierzehn"}, {15, L"fünfzehn"}, {16, L"sechzehn"}, {17, L"siebzehn"}, {18, L"achtzehn"}, {19, L"neunzehn"}, {20, L"zwanzig"}, {30, L"dreißig"}, {40, L"vierzig"}, {50, L"fünfzig"}, {60, L"sechzig"}, {70, L"siebzig"}, {80, L"achtzig"}, {90, L"neunzig"}, {100, L"hundert"}, {1000, L"tausend"}, {1000000, L"million"}, {1000000000, L"milliarde"} }; std::wstring result = L""; std::wstring number = u; if (number.empty() || number == L"0") { return numberWords[0]; } std::vector<int> numberParts; int size = number.size(); int start = size - 3; int end = size; while (start >= 0) { if (start == 0 && size % 3 != 0) { numberParts.push_back(stoi(number.substr(0, end - start))); break; } numberParts.push_back(stoi(number.substr(start, end - start))); end = start; start -= 3; } for (int i = numberParts.size() - 1; i >= 0; i--) { int part = numberParts[i]; if (part >= 100) { result += numberWords[part / 100]; result += L" "; result += numberWords[100]; part = part % 100; if (part > 0) { result += L" "; } } if (part >= 20) { result += numberWords[(part / 10) * 10]; part = part % 10; if (part > 0) { result += L" "; result += numberWords[part]; } } else if (part > 0) { result += numberWords[part]; } if (i > 0) { result += L" "; if (part > 0) { result += numberWords[1000 * (int)pow(10, i)]; result += L"en"; } } } return result;
核心错误点
- 语法错误导致逻辑混乱:代码中
else if (part > 0)的代码块未闭合,后续的if (i > 0)被错误嵌套到该分支中,导致执行流程完全偏离预期,这是输入1001返回错误结果的直接原因之一。 - 数字拆分逻辑错误:当前拆分逻辑无法正确处理长度非3倍数的数字(如4位的1001)。以1001为例,代码仅拆分出最后3位的
001(转成1),遗漏了高位的1,导致千位部分未被处理。 - 单位计算错误:使用
1000 * (int)pow(10, i)计算单位完全错误,正确的单位应为10^(3*i)(如i=1对应1000,i=2对应1000000),且pow函数存在精度问题,建议直接用预定义的单位数组。 - 德语数字规则未遵循:
- 千位前的数字1需用
ein而非eins(如eintausend而非einstausend); - 单位
tausend无需复数后缀en,仅当数量大于1时,million和milliarde才需加en(如zwei millionen)。
- 千位前的数字1需用
修正后的代码
#include <string> #include <vector> #include <map> #include <algorithm> using namespace std; wstring NumberToWords(wstring u) { map<int, wstring> numberWords = { {0, L"null"}, {1, L"eins"}, {2, L"zwei"}, {3, L"drei"}, {4, L"vier"}, {5, L"fünf"}, {6, L"sechs"}, {7, L"sieben"}, {8, L"acht"}, {9, L"neun"}, {10, L"zehn"}, {11, L"elf"}, {12, L"zwölf"}, {13, L"dreizehn"}, {14, L"vierzehn"}, {15, L"fünfzehn"}, {16, L"sechzehn"}, {17, L"siebzehn"}, {18, L"achtzehn"}, {19, L"neunzehn"}, {20, L"zwanzig"}, {30, L"dreißig"}, {40, L"vierzig"}, {50, L"fünfzig"}, {60, L"sechzig"}, {70, L"siebzig"}, {80, L"achtzig"}, {90, L"neunzig"}, {100, L"hundert"}, {1000, L"tausend"}, {1000000, L"million"}, {1000000000, L"milliarde"} }; vector<pair<long long, wstring>> units = { {1000000000, L"milliarde"}, {1000000, L"million"}, {1000, L"tausend"}, {1, L""} }; wstring result = L""; wstring number = u; if (number.empty() || number == L"0") { return numberWords[0]; } // 转换为数字避免字符串拆分错误 long long num = stoll(number); for (auto& unit : units) { long long divisor = unit.first; wstring unitName = unit.second; if (num >= divisor) { int part = num / divisor; num %= divisor; // 处理百位及以下 wstring partStr; if (part >= 100) { partStr += numberWords[part / 100]; partStr += L" "; partStr += numberWords[100]; part %= 100; if (part > 0) { partStr += L" "; } } if (part >= 20) { partStr += numberWords[(part / 10) * 10]; part %= 10; if (part > 0) { partStr += L" "; partStr += numberWords[part]; } } else if (part > 0) { // 千位前的1用ein if (divisor == 1000 && part == 1) { partStr += L"ein"; } else { partStr += numberWords[part]; } } if (!partStr.empty()) { if (!result.empty()) { result += L""; // 德语数字无空格连接 } result += partStr; if (!unitName.empty()) { result += unitName; // 复数处理:仅million和milliarde在数量>1时加en if ((divisor == 1000000 || divisor == 1000000000) && part > 1) { result += L"en"; } } } } } return result; }
修正说明
- 改用数字直接拆分,避免字符串拆分的逻辑错误;
- 遵循德语数字规则,处理
ein替代eins的场景; - 正确处理单位复数后缀,仅
million和milliarde在数量大于1时添加en; - 修复语法错误,确保代码结构正确;
- 用预定义单位数组替代
pow函数,避免精度问题。
内容的提问来源于stack exchange,提问作者tmighty
相关产品推荐
相关产品推荐

