How to convert a command line argument to an int? - c++

Im trying to convert the command line argument(*argv[]) to an integer using the atoi function
int main(int argc, char *argv[]) {
This is my attempt
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <conio.h>
using namespace std;
int main(int argc, char *argv[]) {
int x = 0;
for ( x=0; x < argc; x++ )
{
int x = atoi(argv[1]);
cout << x;
}
return 0;
}
However this returns 0 and im unsure why. Thankyou

It's hard to say having the arguments you pass to your program, but there are few problems here.
Your loop goes from 0 to argc, but your inside your loop you always use argv[1], if you didn't pass any arguments you're going out of bounds, because argv[0] is always the path to your executable.
atoi is a function from C, and when it fails to parse it's argument as an int, it returns 0, replace it with std::stoi, and you will get and execption if the conversion failed. You can catch this exception with try/catch, and then check the string that you tried to convert to int.

Well, this
#include <iostream>
#include <sstream>
#include <string>
#include <cstdlib>
#include <conio.h>
using namespace std;
int main(int argc, char* argv[]) {
int x = 0;
for (x = 0; x < argc; x++)
{
cout << argv[x];
}
return 0;
}
just prints the path to the .exe, the path is a string, it has no numbers. And as I understood from my "research" about command line arguments, you need to use your program through a command line, a terminal, to initialise the argv argument.
Link : https://www.tutorialspoint.com/cprogramming/c_command_line_arguments.htm
Also, as I understood at least, the argv[0] is always the path of the .exe
I hope I will be of some help, if I am mistaken at something, pls tell me where and I will correct my self by editing the answer

Related

Why I get "mpir_ui" was not declared in this scope?

after installing mpir-3.0 on fedora 31. Now I try to build project:
#include <stdio.h>
#include <gmp.h>
#include <mpir.h>
#include <mpfr.h>
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
mpf_t a; //mpir float variable
mpf_init(a); //initialise a
mpir_ui two = 2; //mpir unsigned integer variable
FILE* stream; //file type pointer to output on standard output (console)
mpf_init_set_ui (a, 2); //set value of a to 2
mpf_out_str (stream, 10, 2, a); //output value of a
cout << "\nMPIR working" << "\n" ;
}
But when I compile it I get this error:
‘mpir_ui’ was not declared in this scope; did you mean ‘mpfr_ai’?|
I've used the flags:
-lmpir -lmpfr -lgmp

Is there any way to get rid of error "deprecated conversion from string" in this graphic program?

#include <graphics.h>
#include <conio.h>
#include <iostream>
using namespace std;
int main(){
int gd = DETECT,gm;
/* warning deprecated convesion from string to char* [wWrite-strings] */
initgraph(&gd,&gm, "C:\\TURBOC3\\BGI");
circle(300,300,50);
closegraph();
getch();
return 0;
}
Store the string in a modifiable array:
char bgi[] = "C:\\TURBOC3\\BGI";
initgraph(&gd,&gm,bgi);

I want to store in an array messages from a ROS topic for further elaboration

I'm sorry if this question is too simple for you, but i don't have good programming skills and ROS knowledge. I have a ROS topic in which are published some numbers that are heart beat intervals in seconds. I need to subscribe to that topic and do this kind of elaboration: The idea is to have a little array of ten numbers in which i can store continuously ten heart beat. Then i have a bigger array of 60 numbers that must go up by ten position in order to have at the bottom the newest ten values of the small array and it has to "throw away" the ten oldest values ( i did a bit of research and maybe i have to use a vector instead of an array because in C++ array are fixed as far as i read ). Then i have to print every time these 60 values in a text file (i mean in a loop, so the the text file will be continuously overwritten). Moreover, i see that ROS outputs the data from a topic in this manner: data: 0.987 with every data divided from the others by --- in a column. What i really want, because i need it for a script that reads text file in this manner, is a text file in which the values are in one column without spaces and other signs or words, like this:
0.404
0.952
0.956
0.940
0.960
I provide below the code for my node, in which, for now, i did only the subscribing part, since i have no idea on how to do the things that i have to do later. Thank you in advance for your help!!!
Code:
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <vector>
int main(int argc, char **argv)
{
ros::init(argc, argv, "writer");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/HeartRateInterval", 1000);
ros::spin();
return 0;
}
NOTE: I didn't include the Float32/64 header because i publish the heart beats as a string. I don't know if this is of interest.
EDIT: I will include below the code of the publisher node which publish on the ROS topic the data.
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
int main(int argc, char **argv)
{
ros::init(argc, argv, "heart_rate_monitor");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<std_msgs::String>("/HeartRateInterval", 1000);
ros::Rate loop_rate(1);
while (ros::ok())
{
ifstream inputFile("/home/marco/Scrivania/marks.txt");
string line;
while (getline(inputFile, line)) {
istringstream ss(line);
string heart;
ss >> heart;
std_msgs::String msg;
msg.data = ss.str();
pub.publish(msg);
ros::spinOnce();
loop_rate.sleep();
}
}
return 0;
}
Since what is published is the "variable" msg, i tried to replace in the code given as an answer the variable string_msg with msg, but nothing has changed. Thank you!
I'm not sure I understood exactly what you want but here is a brief example which might do what you need.
I'm using here an std::deque to have a circular buffer of 60 values. What you are missing in your code is a callback function process_message which is called for the subscriber every time a new message arrives.
I did not compile this code, so it may not compile right away but the basics are there.
#include <ros/ros.h>
#include <std_msgs/String.h>
#include "../include/heart_rate_monitor/wfdb.h"
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <deque>
static std::deque<std::string> queue_buffer;
static int entries_added_since_last_write = 0;
void write_data_to_file()
{
// open file
std::ofstream data_file("my_data_file.txt");
if (data_file.is_open())
{
for (int i = 0; i < queue_buffer.size(); ++i)
{
data_file << queue_buffer[i] << std::end;
}
}
else
{
std::cout << "Error - Cannot open file." << std::endl;
exit(1);
}
data_file.close();
}
void process_message(const std_msgs::String::ConstPtr& string_msg)
{
// if buffer has already 60 entries, throw away the oldest one
if (queue_buffer.size() == 60)
{
queue_buffer.pop_front();
}
// add the new data at the end
queue_buffer.push_back(string_msg.data);
// check if 10 elements have been added and write to file if so
entries_added_since_last_write++;
if (entries_added_since_last_write == 10
&& queue_buffer.size() == 60)
{
// write data to file and reset counter
write_data_to_file();
entries_added_since_last_write = 0;
}
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "writer");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("/HeartRateInterval", 1000, process_message);
ros::spin();
return 0;
}

Lost prints from pthread c++

I start to use pthread of C++ and have made a simple exampe for multi threads(3). But what i see is that I always got prints from two threads. why?
#include <iostream>
#include <string>
#include <pthread.h>
using namespace std;
int N=10;
void* run(void* arg) {
char* msg = (char*)arg;
for(int i; i<=N; ++i) std::cout<<msg<<std::endl;
}
int main(int argc, char* argv[]) {
if (argc > 1) N = stoi(argv[1]);
pthread_t t1,t2,t3;
pthread_create(&t1,NULL,run,(void*)"xxx");
pthread_create(&t2,NULL,run,(void*)" howdy");
pthread_create(&t3,NULL,run,(void*)" wrold");
pthread_join(t1,NULL);
pthread_join(t2,NULL);
pthread_join(t3,NULL);
return 0;
}
Prints like:
howdy
wrold
howdy
wrold
It's undefined behaviour, anything can happen.
For example on my machine it doesn't print anything at all.
i is not initialized.
void* run has to return something (e.g.: return NULL;)

C++ CMD input along with exe

Sorry for such a noobie question, but how can I get a program to read the data i input with my program, like how cmd does it with the options
shutdown.exe -f
how do i read the example -f into my program?
This should print out each of the whitespace delimited parameters which were passed to your program.
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
for(int i = 0; i < argc; i++)
{
printf("%s\n", argv[i]);
}
return 0;
}
If you're using plain old C++, your main function will need to look something like this:
int main(int argc, char *argv[])
where argc is the number of whitespace separated items, and argv is an array of pointers to each one
int main(int argc, char *argv[])
{
}
arguments are passed by argv.