简体   繁体   中英

How do I increment an IP address represented as a string?

I have an IP address in char type Like char ip = "192.123.34.134" I want increment the last value (134). Does anyone how should i do it? I think, i should convert it to an integer, and then back, but unfortunately i don't know how? :( I'm using C++.

Please help me!

Thanks, kampi

You can convert the IP address from a string to an integer using inet_addr , then, after manipulating it, convert it back to a string with inet_ntoa .

See the documentation for these functions for more info on how to use them.

Here's a small function that will do what you want:

// NOTE: only works for IPv4.  Check out inet_pton/inet_ntop for IPv6 support.
char* increment_address(const char* address_string)
{
    // convert the input IP address to an integer
    in_addr_t address = inet_addr(address_string);

    // add one to the value (making sure to get the correct byte orders)
    address = ntohl(address);
    address += 1;
    address = htonl(address);

    // pack the address into the struct inet_ntoa expects
    struct in_addr address_struct;
    address_struct.s_addr = address;

    // convert back to a string
    return inet_ntoa(address_struct);
}

Include <arpa/inet.h> on *nix systems, or <winsock2.h> on Windows.

Quick/Dirty!

void increment(std::string& ip)
{
    std::string::size_type dot = ip.find_last_of('.');
    std::stringstream stream(ip.substr(dot+1));
    int part = 0;

    stream >> part;

    part++;

    stream.str(""); stream.clear();

    stream << part;

    ip.replace(dot+1, std::string::npos, stream.str());
}
int a,b,c,d;
sscanf(str, "%d.%d.%d.%d", &a,&b,&c,&d);
sprintf(str, "%d.%d.%d.%d\0", a,b,c,d+1);

I would write a method that accepts a string in that format.
Convert it to 4 integers. increment. (Important Check range)
Then convert back to a string.

If you want somthing more long term and robust a class representing the IP address. Then you maintain the class an manipulate as appropraite and convert to string when needed.

#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include <stdexcept>



class MyIp
{
    struct Dot
    {};
    struct Byte
    {
        Byte(unsigned char& val)
            :m_val(val)
        {}
        unsigned char&  m_val;
    };
    friend std::istream& operator>>(std::istream& str,MyIp::Dot const& d);
    friend std::istream& operator>>(std::istream& str,MyIp::Byte const& b);
    friend std::ostream& operator<<(std::ostream& str,MyIp const& ip);
    public:
        MyIp(std::string const& ip)
        {
            std::stringstream str(ip);
            str >> Byte(ad[0]) >> Dot() >> Byte(ad[1]) >> Dot() >> Byte(ad[2]) >> Dot() >> Byte(ad[3]);
            std::string leftover;
            if (str >> leftover)
            {   throw std::runtime_error("InvalidIP: Long");
            }
        }
        void inc(int index)
        {
            if ((index >= 0) && (index <=3))
            {
                ++ad[index];
                if (ad[index] == 0)
                {
                    inc(index-1);
                }
            }
        }
    private:
        unsigned char   ad[4];
};
std::istream& operator>>(std::istream& str,MyIp::Dot const& d)
{
    char x  = str.get();
    if (x != '.')
    {   throw std::runtime_error("Invalid IP: Dot");
    }
    return str;
}
std::istream& operator>>(std::istream& str,MyIp::Byte const& b)
{
    unsigned int val;
    str >> val;
    if (!str || val > 255)
    {   throw std::runtime_error("Invalid IP: Val");
    }
    b.m_val = static_cast<unsigned char>(val);
    return str;
}
std::ostream& operator<<(std::ostream& str,MyIp const& ip)
{
    return str  << static_cast<unsigned int>(ip.ad[0])
                << "." << static_cast<unsigned int>(ip.ad[1])
                << "." << static_cast<unsigned int>(ip.ad[2])
                << "." << static_cast<unsigned int>(ip.ad[3]);
}

int main()
{
    try
    {
        std::string ip("127.0.0.1");

        MyIp    addr(ip);

        std::cout << addr << "\n";
        addr.inc(3);
        std::cout << addr << "\n";
    }
    catch(std::exception const& e)
    {
        std::cout << "What: " << e.what() << "\n";
    }
}

You can also use the location of the last "." and take from there to the end to convert to an int, bump it up 1, check boundaries and then convert it to a string and append to the base part.

This probably isn't very sane but it was fun to think about.

Since the IP address space is 32-bits you could write a function to convert IP addresses into unsigned 32-bit integers. Then you can add or subtract 1 or as much as you want, and convert back into an IP address. You wouldn't have to worry about range checking.

In pseduo-code for 192.123.34.134 you'd do:

int i = (192 << 24) + (123 << 16) + (34 << 8) + 134

More generally, for abcd:

int i = (a << 24) + (b << 16) + (c << 8) + d

Now change i as much as you want ( i++ , i+=10000 ) and convert back:

String ip = (i >> 24) + "." + 
            ((i >> 16) mod 256) + "." + 
            ((i >> 8) mod 256) + "." + 
            (i mod 256);

Excuse the syntax - I couldn't write C++ to save myself.

MK

This site ate my tabs, so I'll try again. I'm sure there is a library to do something like this, but this should work (assuming my syntax isn't messed up) enough to get the idea across.

Pseudo Code:

char[] ipAddress= "192.123.34.134";

if (ipAddress[ipAddress.Length-1] == '9')
{
    if(ipAddress[ipAddress.Length-2]=='9')
    {
        ipAddress[ipAddress.Length-1]='0';
        ipAddress[ipAddress.Length-2]='0';
        ipAddress[ipAddress.Length-3]=(char)ipAddress[ipAddress.Length-3]+1;
    }
    else
    {
        ipAddress[ipAddress.Length-2]=(char)ipAddress[ipAddress.Length-2]+1;
        ipAddress[ipAddress.Length-1]='0';
    }
}
else
{
     ipAddress[ipAddress.Length-1]=(char)ipAddress[ipAddress.Length-1]+1;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM