How to convert hours, minutes and seconds to seconds - time

I should convert hours, minutes and seconds to seconds,but the problem is that the program can take as an input 3 format types. The first is in the format 54 (which means there are only 54 sec) , sometimes in the format 45:56 (which means 45 minutes and 56 seconds) and sometimes in the format (12:35:12) which means 12 hour 35 minutes and 12 seconds. For example if i want to input those numbers and convert them to seconds i don't know when should i use cin for character ':'
I tried this one but i couldn't input the space character:
char a;
int nr,arr[1000],cnt=0,sum=0;
while (a==':')
{
cin>>nr>>a;
cnt++;
arr[cnt]=nr;
}
if (cnt==1) sum=arr[1];
if (cnt==2) sum=60*arr[1]+arr[2];
if (cnt==3) sum=3600*arr[1]+60*arr[2]+arr[3];

Use strtok and atoi:
#include <iostream>
#include <cstring>
#include <cstdlib>
using namespace std;
int main() {
char time[9];
int sum;
cin>>time;
char *t1=strtok(time,":");
char *t2=strtok(NULL,":");
if (t2==NULL)
sum=atoi(t1);
else {
char *t3=strtok(NULL,":");
if (t3==NULL)
sum=atoi(t1)*60+atoi(t2);
else
sum=atoi(t1)*3600+atoi(t2)*60+atoi(t3);
}
cout<<sum<<endl;
return 0;
}

Related

What is happening when I declare an int, double, and char; I input a double for an int and an int for a double? It seems as it breaks things apart

input: 5.7 4 b
output: 5 0.7 4
What is happening for this output to occur?
Also I notice that I am unable to input the last varble "char" when I use inputs that don't match their declared data type.
#include <iostream>
#include <string>
#include <math.h>
using namespace std;
int main()
{
int whole;
double fractional;
char letter;
cin >> whole >> fractional >> letter;
cout << whole << " " << fractional << " " << letter << endl;
return 0;
}
at first cin expects an integer, so it only reads the integer part of the first value and leaves the rest. Your input is equivalent to this 5 0.7 4 b, so b is never read.

Program that uses exec() on itself - value problem

I am trying to write a program where it execs itself N times, and each time it execs itself a value x starting from 1 is incremented. N should be the only argument of the program.
For example:
./exec_test.o 4
will print:
Exec: 1
Exec: 2
Exec: 3
Exec: 4
Execs done
I only succeeded in making my values decrease from 4 instead of increase to 4:
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int x = atoi(args[1]); //x = the argument used when executing
*args[1]-=1; //decrement the argument value
if (x>0){
printf("Exec : %d \n",x); //printing current argument
execv(args[0],args); //exec itself with argument decremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}
and executing it results in this:
Exec: 4
Exec: 3
Exec: 2
Exec: 1
Execs done
Is it possible to make x increment from 1 instead of decrease from N while using only one argument for the program?
Yes. You can hold two information (current and maximum count) in one argument.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char** args){
if (argc<2){ //Argument error handling
fprintf(stderr,"Usage %s number_of_iter",args[0]);
exit(EXIT_FAILURE);
}
int max, x = 1; // set x to 1 for the first iteration (it will fail to read x)
char next_argument[128];
char* next_args[3];
sscanf(args[1], "%d_%d", &max, &x);
if (x <= max){
printf("Exec : %d \n",x); //printing current argument
// create next argument
snprintf(next_argument, sizeof(next_argument), "%d_%d", max, x + 1);
next_args[0] = args[0];
next_args[1] = next_argument;
next_args[2] = NULL;
execv(args[0],next_args); //exec itself with argument incremented
perror(args[0]);
exit(1);
}
printf("Execs done \n");
}

Qsort comparison

I'm converting C++ code to Go, but I have difficulties in understanding this comparison function:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
using namespace std;
typedef struct SensorIndex
{ double value;
int index;
} SensorIndex;
int comp(const void *a, const void* b)
{ SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
return abs(y->value) - abs(x->value);
}
int main(int argc , char *argv[])
{
SensorIndex *s_tmp;
s_tmp = (SensorIndex *)malloc(sizeof(SensorIndex)*200);
double q[200] = {8.48359,8.41851,-2.53585,1.69949,0.00358129,-3.19341,3.29215,2.68201,-0.443549,-0.140532,1.64661,-1.84908,0.643066,1.53472,2.63785,-0.754417,0.431077,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256,-0.123256};
for( int i=0; i < 200; ++i ) {
s_tmp[i].value = q[i];
s_tmp[i].index = i;
}
qsort(s_tmp, 200, sizeof(SensorIndex), comp);
for( int i=0; i<200; i++)
{
cout << s_tmp[i].index << " " << s_tmp[i].value << endl;
}
}
I expected that the "comp" function would allow the sorting from the highest (absolute) value to the minor, but in my environment (gcc 32 bit) the result is:
1 8.41851
0 8.48359
2 -2.53585
3 1.69949
11 -1.84908
5 -3.19341
6 3.29215
7 2.68201
10 1.64661
14 2.63785
12 0.643066
13 1.53472
4 0.00358129
9 -0.140532
8 -0.443549
15 -0.754417
16 0.431077
17 -0.123256
18 -0.123256
19 -0.123256
20 -0.123256
...
Moreover one thing that seems strange to me is that by executing the same code with online services I get different values (cpp.sh, C++98):
0 8.48359
1 8.41851
5 -3.19341
6 3.29215
2 -2.53585
7 2.68201
14 2.63785
3 1.69949
10 1.64661
11 -1.84908
13 1.53472
4 0.00358129
8 -0.443549
9 -0.140532
12 0.643066
15 -0.754417
16 0.431077
17 -0.123256
18 -0.123256
19 -0.123256
20 -0.123256
...
Any help?
This behavior is caused by using abs, a function that works with int, and passing it double arguments. The doubles are being implicitly cast to int, truncating the decimal component before comparing them. Essentially, this means you take the original number, strip off the sign, and then strip off everything to the right of the decimal and compare those values. So 8.123 and -8.9 are both converted to 8, and compare equal. Since the inputs are reversed for the subtraction, the ordering is in descending order by magnitude.
Your cpp.sh output reflects this; all the values with a magnitude between 8 and 9 appear first, then 3-4s, then 2-3s, 1-2s and less than 1 values.
If you wanted to fix this to actually sort in descending order in general, you'd need a comparison function that properly used the double-friendly fabs function, e.g.
int comp(const void *a, const void* b)
{ SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
double diff = fabs(y->value) - fabs(x->value);
if (diff < 0.0) return -1;
return diff > 0;
}
Update: On further reading, it looks like std::abs from <cmath> has worked with doubles for a long time, but std::abs for doubles was only added to <cstdlib> (where the integer abs functions dwell) in C++17. And the implementers got this stuff wrong all the time, so different compilers would behave differently at random. In any event, both the answers given here are right; if you haven't included <cmath> and you're on pre-C++17 compilers, you should only have access to integer based versions of std::abs (or ::abs from math.h), which would truncate each value before the comparison. And even if you were using the correct std::abs, returning the result of double subtraction as an int would drop fractional components of the difference, making any values with a magnitude difference of less than 1.0 appear equal. Worse, depending on specific comparisons performed and their ordering (since not all values are compared to each other), the consequences of this effect could chain, as comparison ordering changes could make 1.0 appear equal to 1.6 which would in turn appear equal to 2.5, even though 1.0 would be correctly identified as less than 2.5 if they were compared to each other; in theory, as long as each number is within 1.0 of every other number, the comparisons might evaluate as if they're all equal to each other (pathological case yes, but smaller runs of such errors would definitely happen).
Point is, the only way to figure out the real intent of this code is to figure out the exact compiler version and C++ standard it was originally compiled under and test it there.
There is a bug in your comparison function. You return an int which means you lose the distinction between element values whose absolute difference is less then 1!
int comp(const void* a, const void* b)
{
SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
// what about differences between 0.0 and 1.0?
return abs(y->value) - abs(x->value);
}
You can fix it like this:
int comp(const void* a, const void* b)
{ SensorIndex* x = (SensorIndex*)a;
SensorIndex* y = (SensorIndex*)b;
if(std::abs(y->value) < std::abs(x->value))
return -1;
return 1;
}
A more modern (and safer) way to do this would be to use std::vector and std::sort:
// use a vector for dynamic arrays
std::vector<SensorIndex> s_tmp;
for(int i = 0; i < 200; ++i) {
s_tmp.push_back({q[i], i});
}
// use std::sort
std::sort(std::begin(s_tmp), std::end(s_tmp), [](SensorIndex const& a, SensorIndex const& b){
return std::abs(b.value) < std::abs(a.value);
});

Repeating values for in a random bytes generator in c++

I have made a random bytes generator for intialization vector of CBC mode AES implementation,
#include <iostream>
#include <random>
#include <climits>
#include <algorithm>
#include <functional>
#include <stdio.h>
using bytes_randomizer = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, uint8_t>;
int main()
{
bytes_randomizer br;
char x[3];
uint8_t data[100];
std::generate(std::begin(data), std::end(data), std::ref(br));
for(int i = 0; i < 100; i++)
{
sprintf(x, "%x", data[i]);
std::cout << x << "\n";
}
}
But the problem is it gives the same sequence over and over, I found a solution to on Stack which is to use srand() but this seems to work only for rand().
Any solutions to this, also is there a better way to generate nonce for generating an unpredictable Initialization Vector.
Error C2338: invalid template argument for independent_bits_engine: N4659 29.6.1.1 [rand.req.genl]/1f requires one of unsigned short, unsigned int, unsigned long, or unsigned long long
Error C2338 note: char, signed char, unsigned char, int8_t, and uint8_t are not allowed
You can't use uint8_t in independent_bits_engine, at least on Visual Studio 2017. I don't know where and how you managed to compile it.
As the answer DeiDei suggests, seeding the engine is an important part to get random values. It's also same with rand().
srand(time(nullptr)); is required to get random values by using rand().
You can use:
using bytes_randomizer = std::independent_bits_engine<std::default_random_engine, CHAR_BIT, unsigned long>;
std::random_device rd;
bytes_randomizer br(rd());
Some example output:
25
94
bd
6d
6c
a4
You need to seed the engine, otherwise a default seed will be used which will give you the same sequence every time. This is the same as the usage of srand and rand.
Try:
std::random_device rd;
bytes_randomizer br(rd());

Implement a random-number generator using only getpid() and gettimeofday()?

I am using gcc compiler to Implement a random-number generator using only getpid() and gettimeofday(). Here is my code
#include <stdio.h>
#include <sys/time.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
struct timeval tv;
int count;
int i;
int INPUT_MAX =10;
int NO_OF_SAMPLES =10;
gettimeofday(&tv, NULL);
printf("Enter Max: \n");
scanf("%d", &INPUT_MAX);
printf("Enter No. of samples needed: \n");
scanf("%d", &NO_OF_SAMPLES);
/*printf("%ld\n",tv.tv_usec);
printf("PID :%d\n", getpid());*/
for (count = 0; count< NO_OF_SAMPLES; count++) {
printf("%ld\n", (getpid() * tv.tv_usec) % INPUT_MAX + 1);
for (i = 0; i < 1000000; ++i)
{
/* code */
}
}
return 0;
}
I gave a inner for loop for delay purpose but the result what i am getting is always same no. like this
./a.out
Enter Max:
10
Enter No. of samples needed:
10
1
1
1
1
1
1
1
1
1
1
Plz correct me what am i doing wrong?
getpid() is constant during the programs execution, so you get constant values, too.
But even if you use gettimeofday() inside the loop, this likely won't help:
gcc will likely optimize away your delay loop.
even it it's not optimized away, the delays will be very similar and your values won't be very random.
I'd suggest you look up "linear congruential generator", for a simple way to generate more random numbers.
Put gettimeofday in the loop. Look if getpid() is divisible by INPUT_MAX + 1 you will get the same answer always. Instead you can add getpid() (not make any sense though()) to tv.tv_usec.

Resources