concatenate numbers with multiple periods

I'm trying to generate a few random ip addresses to put into an array but I can't remember how to concatenate multiple numbers with multiple periods.

eg: 100.252.1.62

Please only post hints on how to approach this problem so I can solve it myself.

Thanks.
Turn them into strings.
Last edited on
Is it possible to do this without using sstream?

So far I have made an int function that returns a random number from 0 to 255. How can I turn that into a string?

int randgen(int minimun, int maximum) where minimum is 0 and maximum is 255.
Without using stringstream you would need to write your own function that transcribes each integer into its corresponding char value. sstream is faster than writing a function to transform large numbers but of course it has its own problems.

You could try boost::lexical_cast, but I recommend sstream.

1
2
3
4
5
6
template <typename T> std::string to_string (T variable)
{
  std::ostringstream ss();
  ss << variable;
  return ss.str();
}

another solution
1
2
3
4
5
6
int const NUM = 1000;
//the length is 12 because of the the maximum number of int + sign + '\0'
//this could be different at different platforms or compiler
char intToStr[12]; 
sprintf(intToStr, "%i", NUM);
cout<<"intToStr = "<<intToStr<<"\n";


this way is faster but less flexible and unsafe
choose the solutions you need according to your application
Last edited on
Many thanks for the replies!

I don't know if I should make a new thread or not but I made my program with stringstream and now I have a string array of 30 IPv4 addresses.

My question is: How can I sort my string array of numeric IP addresses in ascending order? I only know bubble sort to sort integer arrays and I haven't learned how to use <algorithm> yet.
1
2
3
4
5
6
7
8
9
10
11
12
13
std::vector<std::string> sortString;
  sortString.push_back("201");
  sortString.push_back("222");
  sortString.push_back("333");
  sortString.push_back("532");
  
//descending
  std::sort(sortString.begin(), sortString.end(), std::greater<std::string>());
  std::copy(sortString.begin(), sortString.end(), std::ostream_iterator<std::string>(cout, "\n"));

//ascending
 std::sort(sortString.begin(), sortString.end());
  std::copy(sortString.begin(), sortString.end(), std::ostream_iterator<std::string>(cout, "\n"));


you could implement the algorithm by yourself, this could be a good practice
besides bubble sort, there are selection sort, quick sort, heap sort, merge sort and other's
Last edited on
Note that the sorting above will be lexicographical not numerical.
you are right
it should be convert to size_t first if it have to base on numerical
Thanks for your correction
1
2
3
4
5
6
7
8
9
10
  std::vector<size_t> sortNum;
  sortNum.push_back(2);
  sortNum.push_back(9);
  sortNum.push_back(333);
  sortNum.push_back(532);

  std::sort(sortNum.begin(), sortNum.end());    
  std::copy(sortNum.begin(), sortNum.end() - 1, std::ostream_iterator<size_t>(cout, "."));  
  cout<<sortNum.back()<<"\n";
  


According to the idea of Duous, this should be better
Last edited on
Since you only need the strings when you want a human to look at them, why not store them as numbers internally, then convert them on output?
If you want to sort the IP, you will need to provide a function that compares two IP.
1
2
3
4
5
6
7
8
9
10
11
12
struct ip{
  unsigned char code[4];
};

bool comp(const ip &a, const ip &b){
//compare element by element
  int K;
  for(K=0; K<4 && a.code[K]==b.code[K]; K++)
    ;
  if( K==4 ) return false; //equal
  return a.code[K] < b.code[K];
}
You could change the representation to a single number and compare that.

Edit: simpler
typedef std::vector<unsigned char> ip_code;
Last edited on
I can't figure it out.

I print out the first and last 3 items of my array after sorting and it only sorts up to 99. I know there are strings that begin with 255... but it doesn't seem know those are larger than 99.

0.100.79.127
0.102.68.143
0.103.77.203
99.93.122.155
99.93.2.173
99.95.119.108
please show us your code
if you just apply std::sort on std::string
it would sorted by lexicographical not numerical
...which is why I recommend only converting to string on output...
Why are you not storing them as shorts and then just outputting a string?

If you want to accept std::string input I recommend this quick fix. It does use stringstreams.
1
2
3
4
5
6
7
8
9
IP:: IP (std::string str)
{
  this->_size = 4;
  std::replace(str.begin(), str.end(), '.', ' ');

  std::istringstream ss(str);
  for (size_t i = 0; i < _size; ++i)
    ss >> this->_ip[i];
}


Then _ip[] is array of 4 shorts (or 4 unsigned chars). Then on output put it back into a string.
Okay, I am really struggling with this, here is my source code, but when I sort it thinks 0 is the lowest and 9 is highest, but 255 should be higher than 99. I have been trying really hard to use everyone's suggestions, but I am stumped: my C++ knowledge is very limited.

I want to try it your way, Duoas, but I can't figure out how to concatenate 4 random shorts without turning them into strings first.


EDIT: I just realized that I can make 4 arrays then concatenate them after I've sorted them and add periods!! I feel like an idiot. I was thinking too much into this. I truly appreciate all your help.
Last edited on
...er, that still won't sort properly...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
struct IPv6_Address
  {
  char octets[ 8 ];
  ...
  };

template <typename Char, typename Traits>
std::basic_ostream <Char, Traits> &
operator << (
  std::basic_ostream <Char, Traits> & outs,
  const IPv6_Address& ipaddress
  ) {
  outs << ipaddress.octets[ 0 ];
  size_t N = (std::count( ipaddress.octets + 4, ipaddress.octets + 8, 0 ) == 4) ? 4 : 8;
  for (unsigned n = 1; n < N; n++)
    outs << "." << ipaddress.octets[ n ];
  return outs;
  }
what is a struct? is that a data type like void or main?

I wish I could understand that but I'm not at that level yet. This is what I have so far and you're correct.. my output is not what I want because there are a lot of repeats due to the way I am sorting I think?
Last edited on
Structs are a form of "composite" data type. A struct... is basically a set of variables of differing names bundled into one type.

With structs, you can create your own types. A little template you may want to use is:
1
2
3
4
struct name
{
    //Variables.
};


Since you're creating your own type, you will need to create an instance of it, just like you would an int.

That was not the best explanation, but I hope it's enough. If it's not, then try this:
http://cplusplus.com/doc/tutorial/structures/

Happy coding! :)

-Albatross
Thanks
Last edited on
Topic archived. No new replies allowed.