前言
從接觸業餘無線電後,我對每一個收到的呼號都充滿好奇,總是想查詢這些 HAM 頻道的訊號發射地點 (QTH)。網路上的 QTH 查詢工具需要呼號所有者自行上傳位置,如果沒有上傳,自然就無法查詢。因此,我萌生了自己開發一個查詢工具的想法,只查詢到具體的省份即可。
此工具基於業餘無線電台呼號管理辦法,使用 C++ 編寫,適合新手練習,若有任何不足之處,懇請指正:Goal75KG/CallSignQuery。
功能
- 根據頻道號,可以辨識國家資訊(目前僅能辨識中國)。
- 查詢廣播電台種類(個人業餘電台、信號台、衛星電台等)
- 確定該呼號所屬的省份
- 處理特殊情況的無線電類型
範例
輸入呼號:BA8MAA
輸出結果:
頻道號碼:BA8MAA
國家:中國
廣播類型:個人業餘廣播電台(第一等級)
省份:貴州
實施過程
對應呼號的各項規則
// 載入國家前綴規則
std::map<`std::string`, `std::string`> loadCountryPrefixRules() {
std::map<`std::string`, `std::string`> `countryPrefixRules;
countryPrefixRules["B"] = "中國";
return countryPrefixRules;
// 載入廣播頻道規則
std::map`<字串、std::string> loadStationTypeRules() {
std::map<字、std::string> stationTypeRules;
stationTypeRules['A'] = "個人業餘電台(第一級)";
stationTypeRules['D'] = "個人業餘電台(第二級)";
stationTypeRules['E'] = "個人業餘電台(第二級)";
stationTypeRules['G'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['H'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['I'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['J'] = "業餘信標台";
stationTypeRules['L'] = "外籍及香港、澳門、台灣地區人員在中國內地設置的業餘電台";
stationTypeRules['R'] = "業餘中繼台";
stationTypeRules['T'] = "特別設業餘電台";
stationTypeRules['Y'] = "團體業餘電台";
return stationTypeRules;
// 載入大區和省份範圍規則
std::map<字、std::map<`std::string`, `std::pair`<`std::string`, `std::string`> > > 載入區域省規則() {
std::map<字、std::map<`std::string`, `std::pair`<`std::string`, `std::string`> > > regionProvinceRules;
// 第1區:北京
regionProvinceRules['1'] = {
{"北京", {"AA", "XZZ"}}
};
// 第2區:黑龍江、遼寧、吉林
regionProvinceRules['2'] = {
{"黑龍江", {"AA", "HZZ"}},
{"吉林", {"IA", "PZZ"}},
{"遼寧", {"QA", "XZZ"}}
};
// 第3區:河北、內蒙古、山西、天津
regionProvinceRules['3'] = {
{"天津", {"AA", "FZZ"}},
{"內蒙古", {"GA", "LZZ"}},
{"河北", {"MA", "RZZ"}},
{"山西", {"SA", "XZZ"}}
};
// 第4區:山東、江蘇、上海
regionProvinceRules['4'] = {
{"上海", {"AA", "HZZ"}},
{"山東", {"IA", "PZZ"}},
{"江蘇", {"QA", "XZZ"}}
};
// 第5區:浙江、江西、福建
regionProvinceRules['5'] = {
{"浙江", {"AA", "HZZ"}},
{"江西", {"IA", "PZZ"}},
{"福建", {"QA", "XZZ"}}
};
// 第6區:河南、湖北、安徽
regionProvinceRules['6'] = {
{"安徽", {"AA", "HZZ"}},
{"河南", {"IA", "PZZ"}},
{"湖北", {"QA", "XZZ"}}
};
// 第7區:湖南、廣東、廣西、海南
regionProvinceRules['7'] = {
{"湖南", {"AA", "HZZ"}},
{"廣東", {"IA", "PZZ"}},
{"廣西", {"QA", "XZZ"}},
{"海南", {"YA", "ZZZ"}}
};
// 第8區:四川、貴州、雲南、重慶
regionProvinceRules['8'] = {
{"四川", {"AA", "FZZ"}},
{"重慶", {"GA", "LZZ"}},
{"貴州", {"MA", "RZZ"}},
{"雲南", {"SA", "XZZ"}}
};
// 第9區:陝西、甘肅、寧夏、青海
regionProvinceRules['9'] = {
{"陝西", {"AA", "FZZ"}},
{"甘肅", {"GA", "LZZ"}},
{"寧夏", {"MA", "RZZ"}},
{"青海", {"SA", "XZZ"}}
};
// 第0區:新疆、西藏
regionProvinceRules['0'] = {
{"新疆", {"AA", "FZZ"}},
{"西藏", {"GA", "LZZ"}}
};
return regionProvinceRules;
}
判斷該後綴是否在範圍內
bool isWithinRange(const std::string &後綴,const std::string &rangeStart, 常數 std::string &如果 `rangeEnd` 不為空,則返回 `suffix`。 >= 起始範圍 && suffix <= rangeEnd;
}
呼號比對
void queryCallSign(const std::string &callSign) {
// 載入各種規則
auto countryRules = loadCountryPrefixRules();
auto stationTypeRules = loadStationTypeRules();
auto regionProvinceRules = loadRegionProvinceRules();
// 確保呼號至少有5位
if (callSign.length() < 5) {
std::cout << 「呼號格式錯誤」 << std::endl;
return;
}
// 解析國家前綴
std::string country = countryRules[callSign.substr(0, 1)];
// 解析廣播電台類型
char stationType = callSign[1];
std::string station = stationTypeRules[stationType];
// 解析地區分區
char region = callSign[2];
// 解析後綴
std::string suffix = callSign.substr(3, 2); // 假設後綴長度為2位
// 查找該地區的省份範圍
std::string provinceName = "未知省份";
if (regionProvinceRules.find(region) != regionProvinceRules.end()) {
for (const auto &如果 `province` 是 `regionProvinceRules[region]` 的一個元素:
```
if (isWithinRange(suffix, province.second.first, province.second.second)) {
provinceName = province.first;
break;
}
```
如果 `suffix` 在 `province.second.first` 和 `province.second.second` 之間:
```
if (isWithinRange(suffix, province.second.first, province.second.second)) {
provinceName = province.first;
break;
}
```
處理特殊情況(業餘無線電台、衛星業餘無線電台、特別設立的業餘無線電台)
if (stationType == 'J') {
char suffix1 = callSign[3];
if (suffix1 == 'H' || suffix1 == 'V' || suffix1 == 'U') {
station = "HF、VHF、UHV頻段信號台";
} else if (suffix1 == 'D') {
station = "業餘無線電測向專用信號台";
} else if (suffix1 == 'S' && if (region == '1') {
station = "衛星業餘電台";
} else if (suffix1 == 'T') {
station = "特殊業餘電台";
}
結果輸出
如果 `country` 不為空 && !station.empty() && 如果 provinceName 不等於 "未知省份",則:
std::cout << 「呼號:」 << callSign << std::endl;
std::cout << 「國家:」 << country << std::endl;
std::cout << 「廣播類型:」 << station << std::endl;
std::cout << 「省份:」 << provinceName << std::endl;
} else {
std::cout << 「未能找到與該呼號相關的資訊」 << std::endl;
}
主要程式
```cpp
int main() {
std::string callSign;
std::cout
``` << 「請輸入您要查詢的呼號:」
std::cin >> 呼號;
std::cout << 「\n查詢結果如下:\n」 << std::endl;
// 查詢呼號資訊
queryCallSign(callSign);
system("pause");
return 0;
}
原始碼
包含 <iostream>
包含 <map>
包含 <string>
// 載入國家前綴規則
std::map<`std::string`, `std::string`> loadCountryPrefixRules() {
std::map<`std::string`, `std::string`> `countryPrefixRules;`
`countryPrefixRules["B"] = "中國";`
`return countryPrefixRules;`
}
// 載入廣播類型規則
std::map<字串、std::string> loadStationTypeRules() {
std::map<字串、std::string> stationTypeRules;
stationTypeRules['A'] = "個人業餘電台(第一級)";
stationTypeRules['D'] = "個人業餘電台(第二級)";
stationTypeRules['E'] = "個人業餘電台(第二級)";
stationTypeRules['G'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['H'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['I'] = "個人業餘電台(第三、第四、第五級(接收台))";
stationTypeRules['J'] = "業餘信標台";
stationTypeRules['L'] = "外籍及香港、澳門、台灣地區人員在中國內地設置的業餘電台";
stationTypeRules['R'] = "業餘中繼台";
stationTypeRules['T'] = "特別設立的業餘電台";
stationTypeRules['Y'] = "團體業餘電台";
return stationTypeRules;
}
// 載入大區和省份範圍規則
std::map<字、std::map<`std::string`, `std::pair`<`std::string`, `std::string`> > > 載入區域省規則() {
std::map<字、std::map<`std::string`, `std::pair`<`std::string`, `std::string`> > > regionProvinceRules;
// 第1區:北京
regionProvinceRules['1'] = {
{"北京", {"AA", "XZZ"}}
};
// 第2區:黑龍江、遼寧、吉林
regionProvinceRules['2'] = {
{"黑龍江", {"AA", "HZZ"}},
{"吉林", {"IA", "PZZ"}},
{"遼寧", {"QA", "XZZ"}}
};
// 第3區:河北、內蒙古、山西、天津
regionProvinceRules['3'] = {
{"天津", {"AA", "FZZ"}},
{"內蒙古", {"GA", "LZZ"}},
{"河北", {"MA", "RZZ"}},
{"山西", {"SA", "XZZ"}}
};
// 第4區:山東、江蘇、上海
regionProvinceRules['4'] = {
{"上海", {"AA", "HZZ"}},
{"山東", {"IA", "PZZ"}},
{"江蘇", {"QA", "XZZ"}}
};
// 第5區:浙江、江西、福建
regionProvinceRules['5'] = {
{"浙江", {"AA", "HZZ"}},
{"江西", {"IA", "PZZ"}},
{"福建", {"QA", "XZZ"}}
};
// 第6區:河南、湖北、安徽
regionProvinceRules['6'] = {
{"安徽", {"AA", "HZZ"}},
{"河南", {"IA", "PZZ"}},
{"湖北", {"QA", "XZZ"}}
};
// 第7區:湖南、廣東、廣西、海南
regionProvinceRules['7'] = {
{"湖南", {"AA", "HZZ"}},
{"廣東", {"IA", "PZZ"}},
{"廣西", {"QA", "XZZ"}},
{"海南", {"YA", "ZZZ"}}
};
// 第8區:四川、貴州、雲南、重慶
regionProvinceRules['8'] = {
{"四川", {"AA", "FZZ"}},
{"重慶", {"GA", "LZZ"}},
{"貴州", {"MA", "RZZ"}},
{"雲南", {"SA", "XZZ"}}
};
// 第9區:陝西、甘肅、寧夏、青海
regionProvinceRules['9'] = {
{"陝西", {"AA", "FZZ"}},
{"甘肅", {"GA", "LZZ"}},
{"寧夏", {"MA", "RZZ"}},
{"青海", {"SA", "XZZ"}}
};
// 第0區:新疆、西藏
regionProvinceRules['0'] = {
{"新疆", {"AA", "FZZ"}},
{"西藏", {"GA", "LZZ"}}
};
return regionProvinceRules;
}
// 判斷後綴是否在範圍內
bool isWithinRange(const std::string &後綴,const std::string &rangeStart, 常數 std::string &如果 `rangeEnd` 不為空,則返回 `suffix`。 >= 起始範圍 && suffix <= rangeEnd;
}
// 查詢呼號
void queryCallSign(const std::string &callSign) {
// 載入各種規則
auto countryRules = loadCountryPrefixRules();
auto stationTypeRules = loadStationTypeRules();
auto regionProvinceRules = loadRegionProvinceRules();
// 確保呼號至少有5位
if (callSign.length() < 5) {
std::cout << 「呼號格式錯誤」 << std::endl;
return;
}
// 解析國家前綴
std::string country = countryRules[callSign.substr(0, 1)];
// 解析廣播電台類型
char stationType = callSign[1];
std::string station = stationTypeRules[stationType];
// 解析地區分區
char region = callSign[2];
// 解析後綴
std::string suffix = callSign.substr(3, 2); // 假設後綴長度為2位
// 查找該地區的省份範圍
std::string provinceName = "未知省份";
if (regionProvinceRules.find(region) != regionProvinceRules.end()) {
for (const auto &如果 `province` 是有效的省份(例如:`regionProvinceRules[region]`),則:
```
if (isWithinRange(suffix, province.second.first, province.second.second)) {
provinceName = province.first;
break;
}
```
// 處理特殊情況(業餘信標台、衛星業餘電台、特設業餘電台)
如果 `stationType` 等於 'J',則:
```
char suffix1 = callSign[3];
if (suffix1 == 'H' || suffix1 == 'V' || suffix1 == 'U') {
station = "HF、VHF、UHV 頻段信標台";
} else if (suffix1 == 'D') {
station = "業餘無線電測向專用信標台";
} else if (suffix1 == 'S'
``` && if (region == '1') {
station = "衛星業餘電台";
} else if (suffix1 == 'T') {
station = "特設業餘電台";
}
// 輸出結果
if (!country.empty() && !station.empty() && 如果 provinceName 不等於 "未知省份",則:
std::cout << 「呼號:」 << callSign << std::endl;
std::cout << 「國家:」 << country << std::endl;
std::cout << 「廣播類型:」 << station << std::endl;
std::cout << 「省份:」 << provinceName << std::endl;
} else {
std::cout << 「未能找到與該呼號相關的資訊」 << std::endl;
}
}
int main() {
std::string callSign;
std::cout << 「請輸入您要查詢的呼號:」
std::cin >> 呼號;
std::cout << 「\n查詢結果如下:\n」 << std::endl;
// 查詢呼號資訊
queryCallSign(callSign);
system("pause");
return 0;
}
結尾
後續計畫:
還有其他想法嗎?歡迎討論。👏