Increment IP address - c++

In that program I want to increment IP address. And I see output like that:
125.23.45.67
126.23.45.67
127.23.45.67
128.23.45.67
129.23.45.67
130.23.45.67
131.23.45.67
132.23.45.67
133.23.45.67
134.23.45.67
But I want to see output like this:
124.23.45.67
124.23.45.68
124.23.45.68
124.23.45.70
124.23.45.71
124.23.45.72
124.23.45.73
124.23.45.74
124.23.45.75
124.23.45.76
Here is program code:
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
using namespace std;
#include "winsock2.h"
#pragma comment(lib,"wsock32.lib")
void main()
{
in_addr adr1;
in_addr adr2;
int i;
adr1.s_addr=inet_addr("124.23.45.67");
adr2.s_addr=inet_addr("as.34.34.56");
if (adr1.s_addr!=INADDR_NONE)
cout << " adr1 correct" << endl;
else
cout << " adr1 incorect " << endl;
if (adr2.s_addr!=INADDR_NONE)
cout << " adr2 correct" << endl;
else
cout << " adr2 incorect" << endl;
cout << inet_ntoa(adr1) << endl;
cout << inet_ntoa(adr2) << endl;
for (i=0;i<10;i++)
{
adr1.s_addr ++;
cout << inet_ntoa(adr1) << endl;
}
}

Big endian and little endian gets another one! Use htonl and ntohl to convert back and forth.
for (i=0;i<10;i++)
{
adr1.s_addr = htonl(ntohl(adr1.s_addr) + 1);
cout << inet_ntoa(adr1) << endl;
}

To increment an IP address you will need to break up the in_addr object into 4 int objects (a short int will also do) and increment the 4th one until it hits 256, and then reset it to 1 and increment the 3rd one, etc. You shouldn't be using ++ on the in_addr object directly.
EDIT: Okay, so you can properly increment it if you reverse the byte order. I personally wouldn't do it that way. Especially if all you're doing is outputting IP strings and not using them as an in_addr elsewhere in code.

Instead of using adr1.s_addr:
adr1.s_addr=inet_addr("124.23.45.67");
adr2.s_addr=inet_addr("as.34.34.56");
Use this:
u_long addr1=inet_addr("124.23.45.67");
And increment addr1, i.e. addr1++
the last octet gets incremented.
Or follow this formula:
if IP is A.B.C.D then u_long addr = A + 256*B + 256*256*C + 256*256*256*D

Related

uint8_t element assignment to uint8_t array in C++

I am trying to create a uint8_t array and try to change the first element of the array, then print it to the terminal as a string.
But, after I assign currBlock (changed block) to arr[0], cout gives an error. I tried to find the answer in StackOverflow but couldn't find a similar question. Can you help me with it?
Error: bitset::_M_copy_from_ptr
#include <iostream>
#include <sstream>
#include <bitset>
int main()
{
uint8_t arr[3]{0};
uint8_t currBlock{arr[0]};
int flag{1};
currBlock ^= (-flag ^ arr[0]) & (1UL << 3);
cout << "Buffer is : " << bitset<24>(arr).to_string() << endl;
arr[0] = currBlock;
cout << "Buffer is : " << bitset<24>(arr).to_string() << endl;
return 0;
}
I was expecting a print out of the uint8_t, but instead I get an error.

When multithreading in C++, it randomly repeats the input line stored in my sctruct

I'm writing a program, that reads a file, and for each line, it creates a thread. In log, I can see that before calling the pthread_create command, it is taking the lines correctly (one at a time). The problem is that when creating the thread, it is randomly repeating the lines. I originally thought that a usleep(250) could solve it (in fact it mitigates the problem a bit), but it still keeps repeating some lines and ignoring others.
Please excuse the terrible mix of C with C++! The code:
#include <iostream>
#include <cstdlib>
#include <pthread.h>
#include <fstream>
#include <stdlib.h>
using namespace std;
#define NUM_THREADS 201
struct thread_data{
int thread_id;
char *serial;
char *location;
};
void *RunCommand(void *threadarg)
{
struct thread_data *my_data;
my_data = (struct thread_data *) threadarg;
char *writecmd1="nohup date --date='10 hour' '+%Y-%m-%d_%H:%M:%S' >> /results_path/";
char *writecmda="cd /work_place/bin; ./process1 -d";
char *serial_num=my_data->serial;
char *d_location=my_data->location;
char *writecmd2=" >> /results_path/";
char *writecmd3=".out ";
char *writecmd3a="; ";
char *writecmd4="& ";
char * final_cmd = (char *) malloc(1 + strlen(writecmd1) + strlen(serial_num) + strlen(writecmd3) + strlen(writecmd3a) + strlen(writecmda) + strlen(d_location) + strlen(writecmd2) + strlen(serial_num) + strlen(writecmd3) + strlen(writecmd4));
strcpy(final_cmd,writecmd1);
strcat(final_cmd,serial_num);
strcat(final_cmd,writecmd3);
strcat(final_cmd,writecmd3a);
strcat(final_cmd,writecmda);
strcat(final_cmd,d_location);
strcat(final_cmd,writecmd2);
strcat(final_cmd,serial_num);
strcat(final_cmd,writecmd3);
strcat(final_cmd,writecmd4);
cout << final_cmd << endl;
cout << my_data->serial << "-" << my_data->location << endl;
system(final_cmd);
free(final_cmd);
pthread_exit(NULL);
}
int main ()
{
pthread_t threads[NUM_THREADS];
struct thread_data td[NUM_THREADS];
int rc;
int i = 0;
const char s[2] = ",";
string input_line;
std::ifstream infile("elements_list.in");
while (infile >> input_line)
{
char *main_line = &input_line[0u];
char *token;
// Get the first token. In the file it is the serial number
token = strtok(main_line, s);
td[i].serial = token;
// Get the second token. In the file it is the location
token = strtok(NULL, s);
td[i].location = token;
td[i].thread_id = i;
cout << td[i].serial << "#" << td[i].location << endl;
usleep(250); //Sleep for miliseconds
rc = pthread_create(&threads[i], NULL, RunCommand, (void *)&td[i]);
if (rc)
{
cout << "Error:unable to create thread," << rc << endl;
exit(-1);
}
i++;
}
pthread_exit(NULL);
}
An example of my output (the line with # is before creating the thread, the line with hyphen is when creating the thread):
10000230#location1
10000294#location2
10000294-location2
10000294-location2
10000301#location3
10000301-location3
10000257#location4
10000257-location4
10000344#location5
10000071#location6
10000354#location7
10000354-location7
10000041#location8
10000041-location8
10000058#location9
10000058-location9
1000036310000363-location10
10000363#location10
-location10
10000363-location10
10000201#location11
10000201-location11
10000095#location12
20000037-location13
20000037#location13
On top of that in some cases my structure is apparently loosing shape (see the line for "location10"). Location 1, 5 and 6 are ignored, Location 2 repeated, etc.
The only post I found close to my issue is Multithreading in C but honestly I'm not entirely clear about the solution.
Hope you can help. Thanks in advance
First of all: Your program does not compile using g++. Your code example misses
#include <string.h> // or rather <cstring>
#include <unistd.h>
I have to admit that it was kind of painful to read your code. I did not find the exact reason why lines are repeated but your malformed output is due to a race condition.
std::cout::operator<< is thread safe. 2 concurrent calls are never interleaved in your output. So
Thread 1:
std::cout << "foo\n"
Thread 2:
std::cout << "bar\n"
Always yields either foo\nbar\n or bar\nfoo\n and never fboo\nar\n or something similar. However you are using multiple calls to std::cout::operator<<
Thread 1:
std::cout << "f" << "o" << "o" << std::endl;
Thread 2:
std::cout << "b" << "a" << "r" << std::endl;
Which is the same as
Thread 1:
std::cout << "f";
std::cout << "o";
/* ... */
may yield fboaor\n\n.
When you are multithreading you have to create your full output lines before feeding them to std::cout:
std::stringstream ss;
ss << "My" << "safe" << "output" << "scheme" << std::endl;
std::cout << ss.str();
I also strongly urge you to read a decent book on C++. Your program has a lot of other problems.

Update: program shows adress of fstream instead of the text file

I am about to write a program which asks the user if they want to "search or convert" a file, if they choose convert, they need to provide the location of the file.
I do not know why the program shows the address of the file instead of opening it.
Here is my first approach:
#include <fstream>
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
char dateiname[64], kommando[64];
ifstream iStream;
cout << "Choose an action: " << endl <<
" s - search " << endl <<
" c - convert" << endl <<
" * - end program" << endl;
cin.getline(kommando,64,'\n');
switch(kommando[0])
{
case 'c':
cout << "Enter a text file: " << endl;
cin.getline(dateiname,64,'\n');
iStream.open("C://users//silita//desktop//schwarz.txt");
case 's': break;
case '*': return 0;
default:
cout << "Invalid command: " << kommando << endl;
}
if (!iStream)
{
cout << "The file " << dateiname << " does not exist." << endl;
}
string s;
while (getline(iStream, s)) {
while(s.find("TIT", 0) < s.length())
s.replace(s.find("TIT", 0), s.length() - s.find("TIT", 3),"*245$a");
cout << iStream << endl;
}
iStream.close();
}
At first you can't compare c-strings using ==. You must use strcmp(const char*, const char*). More info about it you can find there: http://www.cplusplus.com/reference/cstring/strcmp/
For example: if (i == "Konvertieren") must become if(!strcmp(i,"Konvertieren"))
As mentioned in Lassie's answer, you can't compare strings in this way using c or c++; just to flesh it out, however, I'll explain why.
char MyCharArr[] = "My Character Array"
// MyCharArr is now a pointer to MyCharArr[0],
// meaning it's a memory address, which will vary per run
// but we'll assume to be 0x00325dafa
if( MyCharArr == "My Character Array" ) {
cout << "This will never be run" << endl;
}
Here the if compares a pointer (MyCharArr) which will be a memory address, ie an integer, to a character array literal. Obviously 0x00325dafa != "My Character Array".
Using cstrings (character arrays), you need to use the strcmp() function which you will find in the cstring library, which will give you a number telling you "how different" the strings are, essentially giving the difference a numerical value. In this instance we are only interested in no difference, which is 0, so what we need is this:
#include <cstring>
using namespace std;
char MyCharArr[] = "My Character Array"
if( strcmp(MyCharArr,"My Character Array")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}
While you are not doing so in your question, If we were using c++ strings rather than character arrays, we would use the compare() method to similar affect:
#include <string>
using namespace std;
string MyString = "My C++ String"
if( MyString.compare("My C++ String")==0 ) {
// If there is 0 difference between the two strings...
cout << "This will now be run!" << endl;
}

Size of data types using pointers?

I want to see the size of data types on my computer. So I started with int datatype with this code :
#include <iostream>
using namespace std;
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
cout << "The first address: \t" << tpntr1;
tpntr2 = ++tpntr1;
cout << "\n The second address : \t" << tpntr2;
unsigned int size= (tpntr2 - tpntr1);
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}
After compiling in visual studio the size is returned to be 0. In a particular run the first address was 0028FBA4 and second was 0028FBA8 but the difference is coming out as zero. Can some one please point out what am I doing wrong here ? I guess its something related to hexadecimal to decimal conversion.
Here's a hint: Move the couts to the end to see what's going on:
#include <iostream>
using namespace std;
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
tpntr2 = ++tpntr1;
unsigned int size= (tpntr2 - tpntr1);
cout << "The first address: \t" << tpntr1;
cout << "\n The second address : \t" << tpntr2;
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}
The addresses are the same. You're literally assigning tpntr2 to tpntr1.
If you change tpntr2 = ++tpntr1 to
tpntr2 = tpntr1;
tpntr2++;
It will partially do what you want. Note that this will print 1 as the size. I may be mistaken, but pointer arithmetic takes into consideration the size of the type (someone please correct me if this isn't the case. I can't explain it otherwise).
As Carcigenicate pointed out, your main issue is that ++ modifies the value. However, you might also not get the result you want due to how pointer arithmetic works.
A corrected form of this would read:
tpntr1 = &t;
tpntr2 = tpntr1;
tpntr2++;
However, your result will be 1, because tpntr2 - tpntr1 will return the difference in terms of the number of ints. Since an int is 4 bytes (at least, in my implementation), this will print that the difference is 1, even though the memory addresses are 4 apart.
If you want the actual bytes (which would be 4), you need to cast to a type which will bypass this behavior. You have two options: cast the pointers to an int, which would make it a simple math operation on numbers, or reinterpret_cast<char*>, which will tell it to treat the pointers as being to one byte of memory. For example, this will show the size as 4:
int main()
{
int t, *tpntr1, *tpntr2;
tpntr1 = &t;
tpntr2 = tpntr1;
tpntr2++;
unsigned int size= (reinterpret_cast<char*>(tpntr2) - reinterpret_cast<char*>(tpntr1));
cout << "The first address: \t" << tpntr1;
cout << "\n The second address : \t" << tpntr2;
cout << "\n the size of int : \t" << size<<"\n";
return 0;
}

Right Shift in C++ giving unusual results (unsigned 64-bit)

I am in the horrible world of bit shifting. I have the following code:
I am shifting this number: 140638023551944 >> 5.
The binary representation for 140638023551944 according to http://www.binaryhexconverter.com/decimal-to-binary-converter is
1000011000011111011101000111
Right shifted 5, I expect: 0000010000110000111110111010
But instead, I get 4394938235998, which is 111111111101000110101110110111110001011110.
That number, to me, looks to have almost nothing at all to do with the original number. I don't see a pattern in one that exists in the other. It is very bizarre.
The code is along the lines of:
uint64_t n, index, tag;
uint64_t one = 1;
uint64_t address = 140638023551944;
/*left shift to get index into the last index.length() number of slots*/
cout << "original address is " << address << " " << "\n";
n = (address >> 5);
cout << "after right shifting away offset bits " << n << "\n";
"address" is populated with the correct integer, 140638023551944. I have verified that.
What is this bizarre behavior? It is consistent with this simulator: http://www.miniwebtool.com/bitwise-calculator/bit-shift/?data_type=10&number=140638023551944&place=5&operator=Shift+Right! But I am pretty sure right shift is not supposed to work that way!
// EVERYTHING WORKS CORRECTLY!
#include <cassert> // assert()
#include <iostream> // cout
#include <cstdint> // UINT64_MAX
using namespace std;
int main() {
uint64_t n, index, tag;
uint64_t one = 1;
uint64_t address = 140638023551944;
/*left shift to get index into the last index.length() number of slots*/
cout << "original address is " << address << " " << "\n";
n = (address >> 5);
cout << "after right shifting away offset bits " << n << "\n";
{ // Everything works correctly!
assert( 140638023551944>>5 == 140638023551944/32 );
assert( 140638023551944>>5 == 4394938235998 );
assert( 140638023551944/32 == 4394938235998 );
assert( 140638023551944 < UINT64_MAX );
}
}