判斷字符串是否符合ip:port模式

Linux下使用inet庫

#include <arpa/inet.h>
#include <iostream>
#include <string>

using namespace std;

bool validate_ip_address(const char* ip, const bool& ipv6) {
  unsigned char buf[sizeof(struct in6_addr)];
  if (ipv6) { //ipv6
    if (inet_pton(AF_INET6, ip, buf))
      return true;
  }
  else { //ipv4
    if (inet_pton(AF_INET, ip, buf))
      return true;
  }
  return false;
}
bool validate_ip_address(const std::string& ip, bool ipv6) {
  return validate_ip_address(ip.data(), ipv6);
}

int main() {
    std::string s1("10.10.10.10:20");
    std::string s2("10.10.10.10");
    std::string s3("10.10.10:20");
    std::string s4("10.10.10.10:20.20");
    std::string s5("10.a10.10:20");
    std::string s6("10.10.10.a10:20");
    std::string s7("10");
    std::string s8("10.10.10.1001:30");
    std::string s9("10.10.10.1001:");
    std::string s10("10:1");
    std::string s11("10.10.10.10.10:10");
    std::string s12("10.10.10.10:a");
    std::string s13("10.10.10.10.10.10:101");
    std::string s14("300.10.10.10:20");
    std::string s15("0:0:0:0:0:FFFF:204.152.189.116");

    std::cout << s1 << " " << std::boolalpha << validate_ip_address(s1, false) << std::endl;
    std::cout << s2 << " " << std::boolalpha << validate_ip_address(s2, false) << std::endl;
    std::cout << s3 << " " << std::boolalpha << validate_ip_address(s3, false) << std::endl;
    std::cout << s4 << " " << std::boolalpha << validate_ip_address(s4, false) << std::endl;
    std::cout << s5 << " " << std::boolalpha << validate_ip_address(s5, false) << std::endl;
    std::cout << s6 << " " << std::boolalpha << validate_ip_address(s6, false) << std::endl;
    std::cout << s7 << " " << std::boolalpha << validate_ip_address(s7, false) << std::endl;
    std::cout << s8 << " " << std::boolalpha << validate_ip_address(s8, false) << std::endl;
    std::cout << s9 << " " << std::boolalpha << validate_ip_address(s9, false) << std::endl;
    std::cout << s10 << " " << std::boolalpha << validate_ip_address(s10, false) << std::endl;
    std::cout << s11 << " " << std::boolalpha << validate_ip_address(s11, false) << std::endl;
    std::cout << s12 << " " << std::boolalpha << validate_ip_address(s12, false) << std::endl;
    std::cout << s13 << " " << std::boolalpha << validate_ip_address(s13, true) << std::endl;
    std::cout << s14 << " " << std::boolalpha << validate_ip_address(s14, false) << std::endl;
    std::cout << s15 << " " << std::boolalpha << validate_ip_address(s15, true) << std::endl;
}
  1. 高版本GCC支持regex
  2. GCC 4.8不支持regex梯轻,手動實現(xiàn)
#include <iostream>
#include <string>
#include <cctype>
#include <cstdlib>

using namespace std;

bool validate_connection(std::string conn, bool ipv6)
{
    const char dot = '.';
    const char colon = ':';
    const size_t max_dots = ipv6 ? 5 : 3; //three dots in ipv4 and five dots in ipv6
    const size_t max_colons = 1; //one colon seperating ip and port
    const size_t max_digits = 3; //as most three digits in part of ip
    const int max_piece_val = 255; //255 is the max val of a piece of ip

    size_t dots = 0;
    size_t colons = 0;
    size_t port_len = 0;

    std::string::iterator iter = conn.begin();
    size_t piece_len = 0;
    int piece_val = 0;
    for (; iter != conn.end(); ++iter) {
        if (dots < max_dots) { //former three parts of ip
            if (*iter != dot) {
                if (!std::isdigit(*iter)) //only digit allowed
                    return false;
                if (piece_len == max_digits) //a part of ip contains no more than three digits
                    return false;
                if ((piece_val = piece_val * 10 + *iter - '0') > max_piece_val)
                    return false;
                ++piece_len;
            }
            else {
                ++dots;
                piece_val = 0;
                piece_len = 0;
            }
        }
        else { //the left is {4th part of ip}:port
            if (colons < max_colons) { //the forth part of ip
                if (*iter != colon) {
                    if (!std::isdigit(*iter))
                        return false;
                    if (piece_len == max_digits)
                        return false;
                    if ((piece_val = piece_val * 10 + *iter - '0') > max_piece_val)
                        return false;
                    ++piece_len;
                }
                else
                {
                    ++colons;
                    piece_len = 0;
                }
            }
            else { //port
                if (!std::isdigit(*iter))
                    return false;
                ++port_len;
            }
        }
    }

    if (dots < max_dots || colons < max_colons || port_len == 0)
        return false;

    return true;
}

int main()
{
    std::string s1("10.10.10.10:20");
    std::string s2("10.10.10.10");
    std::string s3("10.10.10:20");
    std::string s4("10.10.10.10:20.20");
    std::string s5("10.a10.10:20");
    std::string s6("10.10.10.a10:20");
    std::string s7("10");
    std::string s8("10.10.10.1001:30");
    std::string s9("10.10.10.1001:");
    std::string s10("10:1");
    std::string s11("10.10.10.10.10:10");
    std::string s12("10.10.10.10:a");
    std::string s13("10.10.10.10.10.10:101");
    std::string s14("300.10.10.10:20");

    std::cout << s1 << " " << std::boolalpha << validate_connection(s1, false) << std::endl;
    std::cout << s2 << " " << std::boolalpha << validate_connection(s2, false) << std::endl;
    std::cout << s3 << " " << std::boolalpha << validate_connection(s3, false) << std::endl;
    std::cout << s4 << " " << std::boolalpha << validate_connection(s4, false) << std::endl;
    std::cout << s5 << " " << std::boolalpha << validate_connection(s5, false) << std::endl;
    std::cout << s6 << " " << std::boolalpha << validate_connection(s6, false) << std::endl;
    std::cout << s7 << " " << std::boolalpha << validate_connection(s7, false) << std::endl;
    std::cout << s8 << " " << std::boolalpha << validate_connection(s8, false) << std::endl;
    std::cout << s9 << " " << std::boolalpha << validate_connection(s9, false) << std::endl;
    std::cout << s10 << " " << std::boolalpha << validate_connection(s10, false) << std::endl;
    std::cout << s11 << " " << std::boolalpha << validate_connection(s11, false) << std::endl;
    std::cout << s12 << " " << std::boolalpha << validate_connection(s12, false) << std::endl;
    std::cout << s13 << " " << std::boolalpha << validate_connection(s13, true) << std::endl;
    std::cout << s14 << " " << std::boolalpha << validate_connection(s14, false) << std::endl;
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖坠七,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異旗笔,居然都是意外死亡彪置,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門蝇恶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拳魁,“玉大人,你說我怎么就攤上這事撮弧∨税茫” “怎么了姚糊?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長授舟。 經(jīng)常有香客問我救恨,道長,這世上最難降的妖魔是什么岂却? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任忿薇,我火速辦了婚禮裙椭,結果婚禮上躏哩,老公的妹妹穿的比我還像新娘。我一直安慰自己揉燃,他們只是感情好扫尺,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著炊汤,像睡著了一般正驻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抢腐,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天姑曙,我揣著相機與錄音,去河邊找鬼迈倍。 笑死伤靠,一個胖子當著我的面吹牛,可吹牛的內容都是我干的啼染。 我是一名探鬼主播宴合,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼迹鹅!你這毒婦竟也來了卦洽?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤斜棚,失蹤者是張志新(化名)和其女友劉穎阀蒂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體弟蚀,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡蚤霞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了粗梭。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片争便。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖断医,靈堂內的尸體忽然破棺而出滞乙,到底是詐尸還是另有隱情奏纪,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布斩启,位于F島的核電站序调,受9級特大地震影響,放射性物質發(fā)生泄漏兔簇。R本人自食惡果不足惜柴钻,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望灿巧。 院中可真熱鬧赂摆,春花似錦、人聲如沸狸窘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翻擒。三九已至氓涣,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間陋气,已是汗流浹背劳吠。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留巩趁,地道東北人痒玩。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓,卻偏偏與公主長得像晶渠,于是被迫代替她去往敵國和親凰荚。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351

推薦閱讀更多精彩內容