Issues when trying to open an application with system() on mac [C++] - c++

I'm having some issues getting system() to work for my coding class. I'm trying to get my program to ask with cout what program they want to open and then with cin they input the program name and then the program opens the appropriate application.
For example:
system("open /Applications/Google Chrome.app")
When I run this it gives me this output
Kaleb-2:CPP kaleb$ cd "/Users/kaleb/Developement/Code Projects/CPP/" && g++ Hub.cpp -o Hub && "/Users/kaleb/Developement/Code Projects/CPP/"Hub
What Application Would You Like To Use: Google
The files /Applications/Google and /Users/kaleb/Developement/Code Projects/CPP/Chrome do not exist.
I've tried to search the internet about this and I tried encasing it in quotes in every way possible and it didn't work. Normally in terminal you could just do /Applications/Google\ Chrome.app and it would work like normal.
Here is the rest of the code:
#include <iostream>
using namespace std;
int main() {
string App;
cout << "What Application Would You Like To Use: ";
cin >> App;
if (App == "Chrome" || "Google Chrome" || "google") {
system("open /Applications/Google Chrome");
}
}

Related

Cannot write an array in a Ubuntu device using C++ (Debug Assertion Failed. Expression (stream !=NULL))

I am working on Windows and I am trying to write an array into a Ubuntu device using C++ in Visual Studio 2019. Here's a sample of my code:
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs, int *iAnsSize, char *sAns)
...
...
...
char pcFolderName[256];
char pcFileName[256];
sprintf(pcFolderName, "%s\\%s",pcSavePath, pcUUTSerialNumber);
sprintf(pcFileName, "%s\\calib_rfclock.conf",pcFolderName);
// WRITE TABLE ON PC
FILE *pFileW;
pFileW = fopen(pcFileName,"wb");
fwrite(&CalibTable, sizeof(char), CalibTable.hdr.v1.u32Len, pFileW);
fclose(pFileW);
}
return 0;
However, I keep having this pop-up from Microsoft Visual C++ Debug Library that says:
Debug Assertion Failed:
Program:...
File: f:\dd\vctools\crt_bld\sefl_x86\crt\src\fwrite.c
Line: 77
Expression: (stream != NULL)
...
I found this thread and I tried logging in as root on my Ubuntu device. I also tried:
mount -o remount,rw /path/to/parent/directory
chmod 777 /path/to/parent/directory
And I can also create/edit manualy any file in the directory I'm trying to write into with my code, but I get the same error when running it.
Anyone knows what could cause this? I think it could be on the Windows side, but I don't know what I am doing wrong. Thanks a lot in advance.
You never check that opening the file succeeds - and it most likely fails, which is why you get the debug pop-up. Your use of \ as directory delimiters may be the only reason why it fails, but you should check to be sure.
I suggest that you use std::filesystem::path (C++17) to build your paths. That makes it easy to create paths in a portable way. You could also make use of a C++ standard std::ofstream to create the file. That way you don't need to close it afterwards. It closes automatically when it goes out of scope.
Example:
#include <cerrno>
#include <cstring>
#include <filesystem>
#include <fstream>
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs,
int *iAnsSize, char *sAns)
{
...
// Build std::filesystem::paths:
auto pcFolderName = std::filesystem::path(pcSavePath) / pcUUTSerialNumber;
auto pcFileName = pcFolderName / "calib_rfclock.conf";
// only try to write to the file if opening the file succeeds:
if(std::ofstream pFileW(pcFileName, std::ios::binary); pFileW) {
// Successfully opened the file, now write to it:
pFileW.write(reinterpret_cast<const char*>(&CalibTable),
CalibTable.hdr.v1.u32Len);
} else {
// Opening the file failed, print the reason:
std::cerr << pcFileName << ": " << std::strerror(errno) << std::endl;
}
...
}

A method to auto-update the directory of a file using C++?

A method to auto-update the directory of a file using C++ ?
I have a program which aims to first input the password from the user, and once the password matches, the program will open a file using the ShellExecute() function.
This file is a C++ executable file in .exe format.
The program needs to automatically update the directory in the ShellExecute() function instead of having the programmer or other users manually change it in the code each time the executable file's location is changed. What is the best approach to do so ? I have gone through some of these links, but to no avail :
[1] Finding the last created FILE in the directory, C++
[2] How do I make a file self-update (Native C++)
[3] https://www.daniweb.com/programming/software-development/threads/242600/finding-the-most-recently-created-file-in-a-folder
Please feel free to browse my code provided below :
#include<iostream>
#include<conio.h>
#include<string.h>
#include<unistd.h>
#include<windows.h>
using namespace std;
int main(void)
{
string pw="";
char ch;
int attempts=3;
Initiation:
system("cls");
cout<<"Password ?\n--> ";
ch=_getch();
while(ch!=13)
{
pw.push_back(ch);
cout<<'*';
ch=_getch();
}
if(pw=="a32bx#$123")
{
ShellExecute(NULL, "open", "C:\\Users\\agm\\Documents\\easypeasy.exe", NULL, NULL, SW_SHOWDEFAULT);
}
else if(pw!="a32bx#$123")
{
attempts--;
if(attempts>0)
{
cout<<"\n\nIncorrect password. You now have "<<attempts<<" attempts remaining. Loading back the main screen...";
sleep(3); //This gives time for the user to read the line before it moves to the label named Initiation.
goto Initiation;
}
if(attempts==0)
cout<<"\n\nAborting now !";
}
} //END OF CODE
Note : I'm also open to any suggestions on how to improve the overall code.

Bash autocomplete an option without running the application

I have found this code as a bash autocomplete. But, it looks strange to me. What if I do not like to run the code at all. If I would like to type ./a.out then space (without entering) and then by pressing tab, I would like to see only two options apple and cherry and if I type a and press tab, then it autocomplete the option apple and similarly for c. Let's say only one of the two options are acceptable:
./a.out apple
./a.out cherry
where apple and cherry are options and not the name of the files in the directory. In the first case, I would like the program types that your option is apple and in the second case your option is cherry. In any other case, the program should print an error that the option is not valid.
All examples that I find on the internet such as what follows look like that you should run the program first, then it reacts. The while loop inside the main function collides with the normal functionality of the program. Have I misunderstood the readline library? Is the above-described application possible to implement by editing the following code?
// sudo apt-get install libreadline-dev
// g++ -std=c++11 main.cpp -lreadline
#include <iostream>
#include "readline/readline.h"
#include "readline/history.h"
using namespace std;
int main(int argc, char** argv)
{
const char *line;
while ((line = readline("? ")) != nullptr) {
cout << "[" << line << "]" << endl;
if (*line) add_history(line);
free(line);
}
// if(argc!=2)
// {
// cout<<"<exe> one_parameter"<<endl;
// return 1;
// }
// string option=argv[1];
// if(option=="apple" || option=="cherry")
// cout<<"Your option is "<<option<<endl;
// else
// {
// cout<<"Error: invalid option "<<option<<endl;
// return 1;
// }
return 0;
}
// partial answer - why you may want to invoke the app while doing the autocompletion
One way of implementing the autocomplete for an application is to have the application binary configure it (by having a flag that prints the instructions for autocomplete configuration or by just parsing the --help output of the application).
Schemataically:
complete -F $(./a.out --generate-autocomplete-config) ./a.out
This is why you might see the binary actually invoked as a part of autocomplete implementation.
This has nothing to do with your executable. You need to put this in a file and source (source autocomplete_file or . autocomplete_file) it in the bash.
_a_complete_()
{
local word=${COMP_WORDS[COMP_CWORD]}
local files='apple cherry'
COMPREPLY=( $( compgen -W "${files}" -- ${word} ) )
}
complete -F _a_complete_ ./a.out
Here a nice documentation can be found.

libcurl c++ curl_easy_init not working

I just tried setting up curl for the first time using windows + mingw + eclipse juno + curl 7.29. I managed to get it to compile and build fine. I've added the two flags for lcurl and lcurldll.
For some reason though the following does not work:
#include <iostream>
#include <curl.h>
using namespace std;
int main(int argc,char *argv[]) {
cout << "L1" << endl;
CURL *curl;
curl = curl_easy_init();
cout << "L2" << endl;
}
Neither L1 nor L2 will print. If I comment out the easy_init line though it runs fine.
I can't seem to find any similar posts, sorry if this is a dupe. Also, I can't step into anything as it dies as soon as I hit run. I'm sure its something obvious.
Thanks in advance.
Eclipse IDE for C/C++ Developers Version: Juno Service Release 1
Build id: 20120920-0800
curl version: 7.29.0 - SSL enabled
URL: http://curl.haxx.se/gknw.net/7.29.0/dist-w32/curl-7.29.0-devel-mingw32.zip
as for mingw not sure which version I have, I just went to http://sourceforge.net/projects/mingw/files/ and downloaded / installed the latest ver.
In eclipse, under MinGW C++ linker, I have curl and curldll for libraries. In misc I have the static flag - those are the only compiler settings I have changed.
It does work for me, but i just had to add system("PAUSE") at the end since the console close before i can see anything.
here's my code :
#include <curl.h>
#include <iostream>
using namespace std;
int main(void)
{
cout << "L1" << endl;
CURL *curl;
curl = curl_easy_init();
cout << "L2" << endl;
system("PAUSE");
return 0;
}
If you get the message "cannot open include file: 'curl.h': no such file or directory" or something like that, this is because you've missed something in the installation of curl.
It took me a long time to install it.

Unix/C++: Open new terminal and redirect output to it

My program (C++ on Solaris 10) writes output via wcout to its terminal when it is started from a shell. But when I execute it from within Sun Studio or the file manager is does not have a terminal and the ouput appears in the Sun Studio output window or nowhere at all.
I would like it to open its own terminal window in any of the three cases and attach wcout to this terminal window. I want this to be done be the program itself with C++ system calls not by the way how the program is executed from some shell or script. Because then execution in the Studio IDE and double-click in the file manager would still have the same effect.
Being a Windows programmer that seems quite natural to me but I could not find out how this is done in my Unix books nor in the web. Am I requesting the wrong thing, is it really so hard to do or am I missing something?
The following is close to what you want. It still has a few bugs:
The xterm cannot be normally closed (it closes when the program terminates, though). I have no idea why this is so.
Before the intended output, a number is output. Again, I have no idea why.
I don't seem to be able to redirect input.
Maybe someone else know how to fix those bugs (and any others I might not have noticed).
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <iostream>
#include <sstream>
int main()
{
int pt = posix_openpt(O_RDWR);
if (pt == -1)
{
std::cerr << "Could not open pseudo terminal.\n";
return EXIT_FAILURE;
}
char* ptname = ptsname(pt);
if (!ptname)
{
std::cerr << "Could not get pseudo terminal device name.\n";
close(pt);
return EXIT_FAILURE;
}
if (unlockpt(pt) == -1)
{
std::cerr << "Could not get pseudo terminal device name.\n";
close(pt);
return EXIT_FAILURE;
}
std::ostringstream oss;
oss << "xterm -S" << (strrchr(ptname, '/')+1) << "/" << pt << " &";
system(oss.str().c_str());
int xterm_fd = open(ptname,O_RDWR);
char c;
do read(xterm_fd, &c, 1); while (c!='\n');
if (dup2(pt, 1) <0)
{
std::cerr << "Could not redirect standard output.\n";
close(pt);
return EXIT_FAILURE;
}
if (dup2(pt, 2) <0)
{
std::cerr << "Could not redirect standard error output.\n";
close(pt);
return EXIT_FAILURE;
}
std::cout << "This should appear on the xterm." << std::endl;
std::cerr << "So should this.\n";
std::cin.ignore(1);
close(pt);
return EXIT_SUCCESS;
}
You want to output to a file (redirect, using a logging API or close stdout/reopen it as a file). And then tail it with tail -f in a terminal of your choice.
This has added benefit of saving your log output for review even if the terminal crashes/is killed.
When you invoke your program, instead of running: myprog 1 2 3 a b c, run xterm -e myprog 1 2 3 a b c.
I would recommnend to create a shell script that runs the terminal to which you pass your program to execute, then you should call that script instead of your program from the file manager.
Your script.sh:
#!/bin/sh
xterm -e /path_to_your_program/your_program
Using mknod to create pipe in /tmp every linux have /tmp and everyone always allowed to use it
system("mknod /tmp/printing_pipe pipe");
system("qterminal -e tail -f /tmp/printing_pipe");
write to the /tmp/printing_pipe to use it