Segmentation fault - Core Dumped error while using getopt - c++

I know this queston has been asked multiple times, but still I am unable to figure this out
#include<stdio.h>
#include<getopt.h>
int ch;
int queue_time=60;
int thread_num=4;
char *scheduling_algo="FCFS";
extern char *optarg;
int port=8080;
int debug_flag,h_flag,l_flag;
int main(int argc,char *argv[])
{
while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
switch(ch)
{
case 'd':
debug_flag=atoi(optarg); /* print address in output */
break;
case 'h':
h_flag=atoi(optarg);
break;
case 'l':
l_flag=atoi(optarg);;
break;
case 'p':
port = atoi(optarg);
break;
case 'r':
printf("%s",optarg);
break;
case 't':
queue_time = atoi(optarg);
break;
case 'n':
thread_num = atoi(optarg);
break;
case 's':
scheduling_algo = optarg;
break;
default:
printf("nothing was passed");
}
printf("%d",queue_time);
printf("%d",debug_flag);
printf("%d",h_flag);
printf("%d",l_flag);
}
I am executing my program using the following command
./a.out -d -h -l -t 55
I am getting the core dumped error . I read a few examples on google, but still I am facing this problem. Can anyone please help?

You need to read the man page for getopt()
while ((ch = getopt(argc, argv, "dhlprtns")) != -1)
^^^^^^^^
This does not correspond to the way you are using the arguments. You
want colons ":" after the flags which expect arguments. In your code
"d" is not followed by a colon and yet you seem to want an value for it:
case 'd':
debug_flag=atoi(optarg); /* print address in output */
break;
So what is happening is you are calling atoi(0) and this is seg faulting.
Here's the example from the man page, note how "b" is not followed by a
colon while "f" is.
#include <unistd.h>
int bflag, ch, fd;
bflag = 0;
while ((ch = getopt(argc, argv, "bf:")) != -1) {
switch (ch) {
case 'b':
bflag = 1;
break;
case 'f':
if ((fd = open(optarg, O_RDONLY, 0)) < 0) {
(void)fprintf(stderr,
"myname: %s: %s\n", optarg, strerror(errno));
exit(1);
}
break;
case '?':
default:
usage();
}
}
argc -= optind;
argv += optind;

This may be of use to others: You will also get a segfault if you specify an option letter as both without colon, and with colon eg "dabcd:e" - in this case "d" occurs with and without colon.... and then use that option letter.
It appears getopt and its variants do not check for this conflict and return an error!

Related

How to get value of optarg without using command line?

I used getopt() function to get value of optarg parameters in Visual Studio. However, following to document of GNU, getopt() is a function that used to parse command-line options of the Unix/POSIX style and I can not use commandline in Visual Studio. So, how can I get the optarg in VS without using command line or getopt().
Here is my code:
int ch;
extern char* optarg;/*
extern int optind, opterr;*/
char* testfn;
bool testflag = false;
double prd = 60 * 24; // minutes of a day
int maxstep = 100; // # em steps
int Z = 2; // # mixtures
double initscale = 0.25 * prd; // 6 hours
while (optind < argc) {
if ((ch = getopt(argc, argv, "t:m:z:s:")) != -1) {
switch (ch) {
case 't':
testflag = true;
testfn = optarg;
break;
case 'm':
maxstep = atoi(optarg);
break;
case 'z':
Z = atoi(optarg);
break;
case 's':
initscale = atof(optarg);
break;
default:
usage();
}
}
else {
// Regular argument
//code to handle the argument
optind++; // Skip to the next argument
}
}

Incomplete image is written using fwrite()

I was writing a code to read and write an image file, but my code works fine except for only one fourth of the image is written when using fwrite()...Please help me find out where i've mistaken.Thanks in advance.
PS I'm a newbie in this field.
This is my code for the read and write functions.
Please ignore any silly things I might have coded to get the work done.
#include<iostream>
#include <cstdlib>
#include <cstdio>
#define FALSE 0
#define TRUE 1
int c,numberOfCols,numberOfRows,HighVal,totalPx,header;
int** a;
int doneReading = FALSE;
char * string;
unsigned char * image;
//Read Image
int readImage(char **argv){
FILE * pFile;
pFile = fopen (argv[1],"rt");
if (pFile==NULL) perror ("Error opening file");
else {
string = (char *)calloc(256,1);
while (!(doneReading) && !feof (pFile)) {
c=(char)getc (pFile);
switch(c){
case 'P':
c=(char)getc (pFile);
switch(c){
case '1':
header=1;
std::cout<<".pbm white n black";
break;
case '2':
header=2;
std::cout<<".pgm greyscale";
break;
case '3':
header=3;
std::cout<<".ppm rgb";
break;
}
c=(char)getc (pFile);
if(c==0x0A) ungetc(c,pFile) ;
break;
case '#':
fgets(string,256,pFile);
std::cout<<"File you entered is "<<string<<"\n";
break;
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
ungetc(c,pFile);
fscanf(pFile,"%d %d %d",&(numberOfCols),&(numberOfRows),&(HighVal));
doneReading=TRUE;
std::cout<<"Done";
std::cout<<"\nNo. of columns: "<<numberOfCols<<"\nNo. of Columns: "<<numberOfRows<<"\nMaximum Intensity: "<<HighVal<<"\n";
break;
}
totalPx=numberOfCols*numberOfRows*1;
image=(unsigned char *)malloc(totalPx);
fread(image,1,totalPx,pFile);
}
std::cout<<"Image read from "<<argv[1]<<"...\n";
}
return totalPx;
}
//Write Image
void writeImage(char **argv,int pixels){
FILE *fOut;
fOut=fopen(argv[2],"wt");
if (fOut==NULL) perror ("Error opening file");
else {
fprintf(fOut,"P%d \n%d %d \n%d",header,numberOfCols,numberOfRows,HighVal);
fwrite(image,1,pixels,fOut);
std::cout<<"Image Written on "<<argv[2]<<"...";
}
}
int main (int argc,char **argv)
{
int pixels;
pixels = readImage(argv);
writeImage(argv,pixels);
return 0;
}
Your problem appears to be with the value returned from readImage(). It's returning the number of pixels without taking into account the size of a pixel. This line:
totalPx=numberOfCols*numberOfRows*1;
returns the number of pixels, but a pixel can be 1, 2, 4 or more bytes. Assuming your image data is RGBA, then you need to multiply that by 4 in the call to either writeImage() or fwrite().

GetFileAttributes Function

#include "stdafx.h"
#include <Windows.h>
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD d = GetFileAttributes(argv[0]);
_TCHAR* temp;
printf("%d\n", d);
switch(d)
{
case 2048: temp = L"Compressed"; break;
case 32: temp = L"Archive"; break;
case 16: temp = L"Directory"; break;
case 16384: temp = L"Encrypted"; break;
case 2: temp = L"Hidden"; break;
case 128: temp = L"Normal"; break;
case 1: temp = L"Readonly"; break;
case 4: temp = L"System"; break;
case 256: temp = L"Temporary"; break;
default: temp = L"Error or unsupported attribute"; break;
}
_tprintf(temp);
getch();
return 0;
}
what's wrong with this code? I always get 32 in d, even when I launch it with no attributes?
I'm using visual studio 2010.
Thank you!
argv[0] is the name of your executable program. Simply set the index to 1 (ensure it exists). You may also want to use a bitwise AND operation to determine if a flag is set.

move cursor in c++ using gotoXY and kbhit

I want to move the position of symbol "A" in the terminal via the following code in c++, but the terminal closes and seems it does not enter the for loop. I don't know where I am wrong. I will be grateful if you help me:
'w' should move it up
's' should move it down
'a' and 'd' to right and left
#include <iostream>
#include <conio.h>
#include <string>
#include <Windows.h>
using namespace std;
void goToXY(int x=0,int y=0)
{
HANDLE h=GetStdHandle(STD_OUTPUT_HANDLE);
COORD c;
c.X=x;
c.Y=y;
SetConsoleCursorPosition(h,c);
}
int main()
{
char symbol='A';
int X=0, Y=0;
goToXY(X,Y);
cout<<symbol;
for(;;)
{
if(kbhit())
{
char ch = getch();
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
case 's':
goToXY(X,Y+1);
cout<<symbol;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
}
}
getch();
return 0;
}
}
1) You forgot to add break; after each case-body.
2) And you've put return 0; in the body of for-loop, so your program stops after first iteration.
Try this:
for(;;)
{
if(kbhit())
{
char ch = getch();
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
break;
case 's':
goToXY(X,Y+1);
cout<<symbol;
break;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
break;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
break;
}
}
}
getch();
return 0;
You have not used the break; statement after each case in your switch statement. Hope this helps.
switch(ch)
{
case 'w':
goToXY(X,Y-1);
cout<<symbol;
break;
case 's':
goToXY(X,Y+1);
cout<<symbol;
break;
case 'a':
goToXY(X-1,Y);
cout<<symbol;
break;
case 'd':
goToXY(X+1,Y);
cout<<symbol;
break;
}

Getopt joining parameters

Is there way using getopt function to parse:
./prog -L -U
as same as:
./prog -LU
This is my try (not working):
while ((c = getopt(argc, argv, "LU")) != -1) {
switch (c) {
case 'L':
// L catch
break;
case 'U':
// U catch
break;
default:
return;
}
}
In this simple example are only 2 parameters but in my project are required all combinations of 6 parameters. For example: -L or -LURGHX or -LU -RG -H etc.
Can getopt() handle this? Or I must write complex parser to do that?
Save for a missing brace, your code works fine for me:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv) {
int c;
while ((c = getopt(argc, argv, "LU")) != -1) {
switch (c) {
case 'L':
// L catch
printf("L\n");
break;
case 'U':
// U catch
printf("U\n");
break;
default:
break;
}
}
return 0;
}
$ ./a.out -LU
L
U
$ ./a.out -L
L
$
It behaves exactly as you would like:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char** argv)
{
int c;
while ((c = getopt(argc, argv, "LU")) != -1) {
switch (c) {
case 'L':
puts("'L' option");
break;
case 'U':
// U catch
puts("'U' option");
break;
default:
puts("shouldn't get here");
break;
}
}
return 0;
}
And test it:
precor#burrbar:~$ gcc -o test test.c
precor#burrbar:~$ ./test -LU
'L' option
'U' option
precor#burrbar:~$ ./test -L -U
'L' option
'U' option
getopt() is a POSIX standard function that follows the POSIX "Utiltiy Syntax Guidelines", which includes the following:
Guideline 5:
Options without option-arguments should be accepted when grouped behind one '-' delimiter.
getopt does seem capable of handling it, and it does
Here are some examples showing what this program prints with different combinations of arguments:
% testopt
aflag = 0, bflag = 0, cvalue = (null)
% testopt -a -b
aflag = 1, bflag = 1, cvalue = (null)
% testopt -ab
aflag = 1, bflag = 1, cvalue = (null)