atof coredump with getopt - c++

I'm writing a C++ application which converts fahrenheit to celsius and kelvin, and kelvin to celsius and fahrenheit, etc. Since it's stupid to write an interative application here, I decided to familiarize myself with the getopt function in unistd.h.
Format:
F2C -k 273.15
Output:
FAHR CELSIUS KELVIN
32 0 273.15
Here is my code:
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#define VERSION 0.1
#define HELP help(argv[0])
#define OPTS "vk:f:c:h"
float ver = (float)VERSION;
void help(char *s);
namespace Fahrenheit
{
float FK(float F) {
return ((5.0/9.0) * (F - 32.0) + 273.15);
}
float FC(float F) {
return ((5.0/9.0) * (F - 32.0));
}
void printfahr(float F) {
std::cout << "FAHR\t\tCELSIUS\t\tKELVIN" << std::endl;
std::cout << F << "\t\t" << FC(F) << "\t\t" << FK(F) << std::endl;
}
}
namespace Celsius
{
float CF(float C) {
return ((C*(9/5)) + 32);
}
float CK(float C) {
return (C+273.15);
}
void printc(float C) {
std::cout << "FAHR\t\tCELSIUS\t\tKELVIN" << std::endl;
std::cout << CF(C) << "\t\t" << C << "\t\t" << CK(C) << std::endl;
}
}
namespace Kelvin
{
float KF(float K) {
return (((9.0/5.0) * (K-273.15)) + 32);
}
float KC(float K) {
return (K-273.15);
}
void printk(float K) {
std::cout << "FAHR\t\tCELSIUS\t\tKELVIN" << std::endl;
std::cout << KF(K) << "\t\t" << KC(K) << "\t\t" << K << std::endl;
}
}
int main(int argc, char *argv[])
{
char arg = '\0';
if(argc < 2 && argc == 1 && argc > 0) {
help(argv[0]);
exit(1);
}
/*** Use function getopt() defined in unistd.h to accept 5 arguments: -v, -h, -k, -f, and -c ***/
while((arg=getopt(argc, argv, OPTS))!=-1)
{
float floatarg = atof(optarg);
switch(arg)
{
case 'v':
std::cout << "The current version is:" << ver << std::endl;
break;
case 'h':
HELP;
break;
case 'k':
Kelvin::printk(floatarg);
break;
case 'f':
Fahrenheit::printfahr(floatarg);
break;
case 'c':
Celsius::printc(floatarg);
break;
default:
HELP;
break;
}
}
return 0;
}
void help(char *s) {
std::cout << "Usage:\t"<< s << " [-option] [argument]" << std::endl;
std::cout << "option:\t" << "-c [temperature]: convert a Celsius temperature to Fahrenheit and Kelvin" << std::endl;
std::cout << "\t" << "-f [temperature]: convert a Fahrenheit temperature to Celsius and Kelvin" << std::endl;
std::cout << "\t" << "-h: show help information" << std::endl;
std::cout << "\t" << "-k [temperature]: convert a Kelvin temperature to Fahrenheit and Celsius" << std::endl;
std::cout << "\t" << "-v: show version information" << std::endl;
}
My problem is that whenever I use an option that accepts no arguments (like -v) I get a core dump.
dbx has shown me that the SIGSEV occurs at line 70 (float floatarg = atof(optarg);).
When I run the program like this:
./F2C -k 273.15
The math is done correctly and I get a clear printout. It's only when I use -v or -h that my program SIGSEV's.
Extra information:
This program was compiled with the Sun studio compiler suite, version 5.12.
I'm completely baffled as to why my program SIGSEV's. It is inconsistent and makes no sense.
I would appreciate any help available.

Should have done some optarg checking. After all, you can't convert null to a float.
new main():
#define FLOATARG atof(optarg)
int main(int argc, char *argv[])
{
char arg = '\0';
if(argc < 2 && argc == 1 && argc > 0) {
help(argv[0]);
exit(1);
}
/*** Use function getopt() defined in unistd.h to accept 5 arguments: -v, -h, -k, -f, and -c ***/
while((arg=getopt(argc, argv, OPTS))!=-1)
{
switch(arg)
{
case 'v':
std::cout << "The current version is: << ver << std::endl;
break;
case 'h':
HELP;
break;
case 'k':
Kelvin::printk(FLOATARG);
break;
case 'f':
Fahrenheit::printfahr(FLOATARG);
break;
case 'c':
Celsius::printc(FLOATARG);
break;
default:
HELP;
break;
}
}
return 0;
}

The shortest fix is:
float floatarg = optarg ? atof(optarg) : 0.0;
You can also rewrite your code like
float floatarg = 0.0;
switch(arg)
{
case 'v':
std::cout << "The current version is:" << ver << std::endl;
break;
case 'h':
HELP;
break;
case 'k':
floatarg = atof(optarg);
Kelvin::printk(floatarg);
break;
case 'f':
floatarg = atof(optarg);
Fahrenheit::printfahr(floatarg);
break;
...
or
float floatarg = 0.0;
if(optarg) {
floatarg = atof(optarg);
}
switch(arg)
{
case 'v':
std::cout << "The current version is:" << ver << std::endl;
break;
case 'h':
HELP;
break;
case 'k':
Kelvin::printk(floatarg);
break;
case 'f':
Fahrenheit::printfahr(floatarg);
break;
...

Related

writing a program which helps the tudio to convert midi note number to name and octave

I want to write a C++ program that converts MIDI note number to name and octave using the switch statements ?
I am having a few errors in my code the code should print out a Note name and octave number (eg. input -> 24 ; output -> C1).
https://www.inspiredacoustics.com/en/MIDI_note_numbers_and_center_frequencies
int main() {
int mi;
cout <<"MIDI value: " << std::endl;
cin >> mi;
int oct_v;
oct_v = (mi/12) - 1;
string notes;
notes = "C C# D D# E F F# G G# A A# B";
string nt;
nt = notes.substr((mi % 12) * 2 , (mi % 12) * 2 +2);
cout <<"Note name " << nt << oct_v;
return 0;
}
The code is not perfect and I am having doubts about what should I put into switch statements.
First some hints:
"I want to write a C++ script"
The term script is typically used for interpreted languages like shell scripts. As c++ is a compiled language we don't name them script. It is a c++ program or c++ source code.
" what should I put into switch statements."
You don't use any switch statement! You pick some substring from a string. That has nothing to do with a switch statement!
What is wrong with your code:
Your calculation for picking the sub string is quite fine, but you assume that your notes inside your string are always have a length of 2 but you use 2 chars for e.g. "C " or 3 chars for "A# ". You simply should write your string with 2 letters per note as:
std::string notes = "C C#D D#E F F#G G#A A#B";
The second parameter of substr is the length and not the end position.
In addition: You should not use using namespace std;
Here are some alternative solutions also with switch statement.
int main() {
int mi;
std::cout <<"MIDI value: " << std::endl;
std::cin >> mi;
unsigned int oct_v = mi/12 -1;
// variant with array
std::string notes[]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
std::string nt = notes[mi%12];
// variant with substring ( from your code, but fixed )
std::string notes2= "C C#D D#E F F#G G#A A#B";
std::string nt2 = notes2.substr((mi % 12) * 2 , 2);
std::string nt3;
// with switch
switch ( mi%12 )
{
case 0: nt3 = "C"; break;
case 1: nt3 = "C#"; break;
case 2: nt3 = "D"; break;
case 3: nt3 = "D#"; break;
case 4: nt3 = "E"; break;
case 5: nt3 = "F"; break;
case 6: nt3 = "F#"; break;
case 7: nt3 = "G"; break;
case 8: nt3 = "G#"; break;
case 9: nt3 = "A"; break;
case 10: nt3 = "A#"; break;
case 11: nt3 = "B"; break;
}
std::cout <<"Note name " << nt << ":" << oct_v << std::endl;
std::cout <<"Note name2 " << nt2 << ":" << oct_v << std::endl;
std::cout <<"Note name3 " << nt3 << ":" << oct_v << std::endl;
return 0;
}
I think you'd better use a table of char arrays to store the notes. I propose the following code :
#include <iostream>
#include <string>
const char notes[12][4]={"C","C#","D","D#","E","F","F#","G","G#","A","A#","B"};
void midiToNote(int midi, int& octave,std::string& note)
{
octave = ( (midi-12)/12 );
note = std::string(notes[midi%12]);
}
int main()
{
int midi;
int oct;
std::string name;
midi = 29;
midiToNote(midi,oct,name);
std::cout << midi <<" is " <<name << oct<< std::endl;
midi = 51;
midiToNote(midi,oct,name);
std::cout << midi <<" is "<< name << oct << std::endl;
return 0;
}
Hope this helps.

GetOpt not working on Mac, none of the arguments show up

int c = 0;
while (c = getopt(argc, argv, "p:t:e:") != -1) {
std::cout<<"c: "<<c<<std::endl;
switch (c) {
case 'p':
if (optarg) {
std::cout << "lol" << std::endl;
person = atoi(optarg);
}
break;
case 't':
if (optarg) {
time = stod(optarg);
std::cout << "ll" << std::endl;
}
break;
case 'e':
if (optarg) {
ecg = atoi(optarg);
std::cout << "2dasf" << std::endl;
}
break;
}
}
Been trying to make getopt work on my Mac. C is printed as 1, but None of the print statements within the switch are printed. This works perfectly in Linux. What is wrong with my Mac?

How to interface C++ and Excel (Output from C++ program to an Excel spreadsheet)

I am making a small program for my job (it has nothing to do with programming) to help them with the many measurements and efficiency of their job.
I have made most of the program in a Console App in C++ with Code::Blocks.
Would it be possible to yank the output of variables from my C++ and put them in certain cells in an Excel spreadsheet? I have looked around the internet for some forums but some do not work or have me use Visual Basics. Any clues or hints would help dramatically. Thanks.
Source Code:
#include <iostream>
#include <cstdlib>
#include <cmath>
//Function Prototypes -- *
void DisplayMenu();
void Bahama();
int Colonial();
int StormPanel();
void DisplayMenu()
{
int a;
std::cout << "*---Display Menu---*\n";
std::cout << "1) Bahama/Colonial\n";
std::cout << "2) Strom Panel\n\n";
std::cout << "Type the corresponding number for\n";
std::cout << "the type of shutter you need calculated: ";
std::cin >> a;
switch(a)
{
case 1:
Bahama();
break;
case 2:
StormPanel();
break;
}
}
void Bahama()
{
int Token = 200;
do{
int SN; //Shutter Number
int QSL; // Quantity of Shutter Louvers
double W; //Width
double H; //Hight
double Sl; // Shutter Louvers (trail)
double SL; // Size of Shutter Louvers
float Sd = 3.7812; // Single Deduction
float Dd = 5.6562; // Double Deduction
float Td = 7.5312; // Triple Deduction
float Qd = 9.4062; // Quadruple Deduction
float QTd = 11.2812; // Quintuple Deduction
float STd = 13.1562; // Sextuple Deduction
float HL; // Hight multiplied by Length
system("cls");
std::cout << "*----------------------------------------*\n\n";
std::cout << "What is the Width of the Bahama/Colonial shutter?\n";
std::cout << "(Whole Number or Decimal[Inches]): ";
std::cin >> W;
std::cout << "*----------------------------------------*\n\n";
std::cout << "What is the Hight of the Bahama/Colonial shutter?\n";
std::cout << "(Whole Number or Decimal[Inches]): ";
std::cin >> H;
HL = W*H;
system("cls");
std::cout << "*---------------------------------------------------------
----
---------------------------------------*\n\n";
std::cout << "Is this Shutter a . . ." << "\n" << "Single (1), Double
(2),"
<< "\n" << "Triple (3), Quadruple (4)," << "\n" << "Quintuple (5), or
Sextuple
(6): ";
std::cin >> SN;
switch (SN)
{
case 1: Sl = W - Sd;
break;
case 2: Sl = W - Dd;
break;
case 3: Sl = W - Td;
break;
case 4: Sl = W - Qd;
break;
case 5: Sl = W - QTd;
break;
case 6: Sl = W - STd;
break;
default: Sl = W - Sd;
}
SL = Sl / SN;
std::cout << "\n\nWith a Width of [" << W <<"] and a Hight of [" << H <<
"]";
std::cout << " the Bahama/Colonial Shutters'. . .";
std::cout << "\n\nSide Slide: ";
std::cout << W - 3.3125;
std::cout << "\n\nSide Rails: ";
std::cout << H - 3.7187;
std::cout << "\n\nLouver Size: ";
std::cout << SL;
// std::cout << "\n\nNumber of Louvers: ";
// std::cout << NP;
std::cout << "\n\n*-----------------------------------------------------
----
-------------------------------------------*\n\n\n";
std::cout << "Would you like to measure out another Bahama/Colonial
shutter?";
std::cout << "(1 = Yes)(2 = Main Menu)(0 = Quit): ";
std::cin >> Token;
switch (Token)
{
case 2: DisplayMenu();
case 0: Token = 200;
}
} while (Token == 1);
}
int StormPanel()
{
std::cout << "Storm Panel!";
return 0;
}
int main()
{
DisplayMenu();
return 0;
}
You can control Excel via OLE Automation.
https://support.microsoft.com/en-us/help/216686/how-to-automate-excel-from-c-without-using-mfc-or-import

How to perform same action as changing Windows 7 display from Landscape to Portrait

I need to write a program which programmatically changes the Landscape mode to Portrait of a touchscreen in Windows 7. The resolution is 1920 x 1080 and I thought I could switch the 1920 with the 1080 and use ChangeDisplaySettings or ChangeDisplaySettingsEx to make the change. but it doesn't work.
Windows CE has some sort of rotate feature, so I tried that. as in:
devmode.dmFields = DM_DISPLAYORIENTATION;
devmode.dmDisplayOrientation = DMDO_90;
ChangeDisplaySettingsEx(NULL,&devmode,NULL,CDS_RESET,NULL);
But that didn't work on a normal test desktop PC.
I can do this through Control Panel, Display, Screen Resolution, choose Portrait, so should I not be able to do via Windows API?
How can I make this change in code?
EDIT
I tried this code, but I get DISP_CHANGE_BADMODE returned by ChangeDisplaySettings.
#include <Windows.h>
#include <iostream>
int main() {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(dm.dmPelsHeight > dm.dmPelsWidth) {
std::cout << "Screen should be rotated 90 degrees\n";
std::cout << "Do you want to rotate display 90 degrees? (y or n)\n";
char ch;
std::cin >> ch;
if(ch == 'y') {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT;
// determine new orientation
switch (dm.dmDisplayOrientation)
{
case DMDO_DEFAULT:
dm.dmDisplayOrientation = DMDO_270;
break;
case DMDO_270:
dm.dmDisplayOrientation = DMDO_180;
break;
case DMDO_180:
dm.dmDisplayOrientation = DMDO_90;
break;
case DMDO_90:
dm.dmDisplayOrientation = DMDO_DEFAULT;
break;
default:
// unknown orientation value
// add exception handling here
break;
}
LONG ret = ChangeDisplaySettings(&dm, CDS_TEST); //0);
std::cout << "ChangeDisplaySettings returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW: std::cout << "The settings change was unsuccessful because the system is DualView capable\n"; break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
}
else
std::cout << "Screen orientation is just fine\n";
}
}
I saw an article on the web indicating that possibly it couldn't be done. But this code works.
#include <Windows.h>
#include <iostream>
int main(int argc, char* argv[]) {
DEVMODE dm;
// initialize the DEVMODE structure
ZeroMemory(&dm, sizeof(dm));
dm.dmSize = sizeof(dm);
// only change first/default display (index=0)
if (0 != EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dm))
{
std::cout << "Current orientation\n";
switch(dm.dmDisplayOrientation) {
case DMDO_DEFAULT: std::cout << "DMDO_DEFAULT\n"; break;
case DMDO_90: std::cout << "DMDO_90\n"; break;
case DMDO_180: std::cout << "DMDO_180\n"; break;
case DMDO_270: std::cout << "DMDO_270\n"; break;
}
std::cout << "Panning height: " << dm.dmPanningHeight << '\n'
<< "Panning width: " << dm.dmPanningWidth << '\n';
std::cout << "Colour resolution: " << dm.dmBitsPerPel << " bits per pixel\n";
std::cout << "Height in pixels: " << dm.dmPelsHeight << '\n';
std::cout << "Width in pixels: " << dm.dmPelsWidth << '\n';
if(argc != 2) {
std::cout << "Usage: rotate_screen <angle>. Angle values: 0, 90, 180, 270. Angles are rotation clockwise. Use 0 to revert back\n";
exit(0);
}
// parse parameter
int rotate = atoi(argv[1]); // should do something better and safer here
if(rotate != 0 && rotate != 90 && rotate != 180 && rotate != 270) {
std::cout << "incorrect rotation selected\n";
}
else {
// swap height and width
DWORD tmp = dm.dmPelsHeight;
dm.dmPelsHeight = dm.dmPelsWidth;
dm.dmPelsWidth = tmp;
// select fields which have changed
dm.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_DISPLAYORIENTATION;
// set angle
switch(rotate) {
case 0: dm.dmDisplayOrientation = DMDO_DEFAULT; break;
case 90: dm.dmDisplayOrientation = DMDO_90; break;
case 180: dm.dmDisplayOrientation = DMDO_180; break;
case 270: dm.dmDisplayOrientation = DMDO_270; break;
default:
std::cout << "Something went wrong, aborting\n";
exit(0);
}
LONG ret = ChangeDisplaySettingsEx(NULL, &dm, NULL, 0, NULL); //CDS_RESET, NULL); //0);
std::cout << "ChangeDisplaySettingsEx returned " << ret << '\n';
switch(ret) {
case DISP_CHANGE_SUCCESSFUL: std::cout << "display successfully changed\n"; break;
case DISP_CHANGE_BADDUALVIEW:
std::cout << "The settings change was unsuccessful because the system is DualView capable\n";
break;
case DISP_CHANGE_BADFLAGS: std::cout << "An invalid set of flags was passed in.\n"; break;
case DISP_CHANGE_BADMODE: std::cout << "The graphics mode is not supported.\n"; break;
case DISP_CHANGE_BADPARAM: std::cout << "An invalid parameter was passed in. This can include an invalid flag or combination of flags.\n"; break;
case DISP_CHANGE_FAILED: std::cout << "The display driver failed the specified graphics mode.\n"; break;
case DISP_CHANGE_NOTUPDATED: std::cout << "Unable to write settings to the registry.\n"; break;
case DISP_CHANGE_RESTART: std::cout << "The computer must be restarted for the graphics mode to work.\n"; break;
}
}
} // enum worked
}

getopt command line get values c++

How do you get the values of the flags in getopt, I have tried googling it but all I got is on how to switch cases and set flags. I got the below code and what I am trying to do is to have three flags, -a, -b, -c but only two flags are passed like ./filename -a somevalue -c anothervalue or ./filename -b somevalue -c anothervalue any help?
int main(int argc, char *argv[])
{
int flagA = 0;
int flagB = 0;
while (1) {
char c;
c = getopt (argc, argv, "abc:");
if (c == -1) {
break;
}
switch (c) {
case 'a':
flagA = 1;
//cout<<optarg<<endl; //I tried printing the value but it only prints the second flag value
break;
case 'b':
flagB = 1;
cout<<optarg<<endl;
break;
case 'c':
cout<<optarg<<endl;
break;
case '?':
default:
cout<<"Usage: %s [-a] [-b <something>].\n", argv[0]<<endl;
}
if(flagA > 0){
//do something using the values of flagA and flagC
}
else if(flagB > 0){
//do something using the values of flagB and flagC
}
}
return 0;
}
If you intend to use optarg with a flag, the flag must have : after it in the option string.
c = getopt(argc, argv, "a:b:c:");
Your usage output statement should not have compiled for you. Also, you are attempting to mix C style format specifiers into a C++ output stream, which is incorrect.
cout << "Usage: " << argv[0] << " [-a] [-b <something>].\n";
There are multiple problems with the code, but the key one is in your invocation of getopt(). You have the option control string "abc:", which means that neither -a nor -b takes an option.
Assuming you're using a POSIX standard version of getopt() and not GNU getopt(), then when you run either:
./filename -a somevalue -c anothervalue
./filename -b somevalue -c anothervalue
the somevalue after the first flag means that options are finished and the remaining arguments are non-option arguments. GNU getopt(), in the absence of the environment variable POSIXLY_CORRECT, will permute the argument list so that -c anothervalue is also recognized (and the arguments are permuted such that somevalue ends up at the end).
Your code would be better written:
#define _XOPEN_SOURCE 600
#include <iostream>
#include <unistd.h>
using namespace std;
int main(int argc, char *argv[])
{
int flagA = 0;
int flagB = 0;
int opt;
char *c_opt = 0;
while ((opt = getopt(argc, argv, "abc:")) != -1)
{
switch (opt)
{
case 'a':
flagA = 1;
cout << "A: " << flagA << "\n";
break;
case 'b':
flagB = 1;
cout << "B: " << flagB << "\n";
break;
case 'c':
c_opt = optarg;
cout << "C: " << c_opt << "\n";
break;
default:
cerr << "Usage: " << argv[0] << " [-a] [-b] [-c <something>]\n";
return -1;
}
}
if (flagA)
{
// do something using the values of flagA and c_opt (if set)
}
else if (flagB)
{
// do something using the values of flagB and c_opt (if set)
}
else if (c_opt)
{
// do something using just c_opt (neither flagA nor flagB is set)
}
else
{
// do something if no options are specified (report error?)
}
for (int i = optind; i < argc; i++)
cout << "File: " << i << ": " << argv[i] << "\n";
return 0;
}
The code above (as amended) compiles cleanly with GCC 4.9.1 on Mac OS X 10.10 (Yosemite):
g++ -O3 -g -std=c++11 -Wall -Wextra -Werror opt.cpp -o opt
The BSD-ish getopt() hews close to the POSIX standard, so the result I get is:
$ ./opt -a 5 -c something
A: 1
File: 2: 5
File: 3: -c
File: 4: something
$
florw.wat commented:
I want the -a and -b options to take an argument. What I am trying to do is I have two functions which take two arguments, so if -a is set then I would like to call function a else if -b then call function b. I need the two values to call the functions.
Given that clarification, the code might look like:
#define _XOPEN_SOURCE 600
#include <cstdlib>
#include <iostream>
#include <unistd.h>
using namespace std;
static void usage(const char *arg0)
{
cerr << "Usage: " << arg0 << " [-a filename | -b filename] -c <something>\n";
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
char *a_opt = 0;
char *b_opt = 0;
char *c_opt = 0;
int opt;
while ((opt = getopt(argc, argv, "a:b:c:")) != -1)
{
switch (opt)
{
case 'a':
a_opt = optarg;
cout << "A: " << a_opt << "\n";
break;
case 'b':
b_opt = optarg;
cout << "B: " << b_opt << "\n";
break;
case 'c':
c_opt = optarg;
cout << "C: " << c_opt << "\n";
break;
default:
cerr << "Unknown option: " << optopt << "\n";
usage(argv[0]);
break;
}
}
if (optind != argc || c_opt == 0 || (a_opt && b_opt) || (a_opt == 0 && b_opt == 0))
usage(argv[0]);
else if (a_opt)
cout << "A&C: " << a_opt << " " << c_opt << "\n";
else
cout << "B&C: " << b_opt << " " << c_opt << "\n";
return 0;
}
Sample run:
$ ./opt -a option -c something
A: option
C: something
A&C: option something
$