creating process with fork in loop - loops

I'm trying to make a program that will print all the prime number between 2 values (lvan (lower value) and uval (upper value)), print some of them by the user choice (nval) and will find them by using number of child processes (pval is the number of children's).
so the problem is that I don't know how to make my program make only the asked amount of child processes and preventing my child process from creating it's own childs.
I will mark the line that I thought that I need to enter the code that will make everything work well (may be a wrong line).
I've tried to kill the child process but that's terminated all the program, I've tried to make the child return a value (with return and exit commands) but that terminated the program as well.
What should I do ?
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/mman.h>
#include <sys/wait.h>
void parseargs(char *argv[], int argc, int *lval, int *uval, int *nval, int *pval);
int isprime(int n);
int countFlags(char* arr, int size);
int main (int argc, char **argv)
{
int lval = 1; //def val
int uval = 100; //def val
int nval = 10; //def val
int pval = 4; //def val
int count = 0;
int rc,num;
// Parse arguments
parseargs(argv, argc, &lval, &uval, &nval, &pval);
if (uval < lval)
{
fprintf(stderr, "Upper bound should not be smaller then lower bound\n");
exit(1);
}
if (lval < 2)
{
lval = 2;
uval = (uval > 1) ? uval : 1;
}
if (pval < 0)
pval=4;
char *flagarr = mmap ( NULL, (uval-lval+1)*sizeof(char),
PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0 );
if (flagarr == MAP_FAILED)
exit(2);
//start forks
for(int i =0; (i<pval); i++){
if(rc=fork()<0)
{
printf("fork failed");
exit(1);
}
if(rc==0)
{
for (num = lval+i; num <= uval; num+=pval)
{
if (isprime(num))
{
flagarr[num - lval] = 1;
count ++;
} else {
flagarr[num - lval] = 0;
}
}
printf("%d\n",i);
//problematic line imo ??
}
}
for(int i =0; (i<pval) ; i++)
wait(NULL);
// Print results
printf("Found %d primes%c\n", count, count ? ':' : '.');
for (num = lval; (num <= uval) && (nval) ; num++)
if (flagarr[num - lval])
{
nval--;
count--;
printf("%d%c", num, (count && nval) ? ',' : '\n');
}
munmap(flagarr,(uval-lval+1));
return 0;
}
// NOTE : use 'man 3 getopt' to learn about getopt(), opterr, optarg and optopt
void parseargs(char *argv[], int argc, int *lval, int *uval, int *nval, int *pval)
{
int ch;
opterr = 0;
while ((ch = getopt (argc, argv, "l:u:n:p:")) != -1)
switch (ch)
{
case 'l': // Lower bound flag
*lval = atoi(optarg);
break;
case 'u': // Upper bound flag
*uval = atoi(optarg);
break;
case 'n':
*nval = atoi(optarg);
break;
case 'p':
*pval = atoi(optarg);
break;
case '?':
if ((optopt == 'l') || (optopt == 'u')|| (optopt == 'n')|| (optopt == 'p'))
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
else
fprintf (stderr, "Unknown option character `\\x%x'.\n", optopt);
exit(1);
default:
exit(1);
}
}
int countFlags(char* arr, int size)
{
int ret =0;
for(int i=0;i<size;i++)
ret+=arr[i];
return ret;
}
int isprime(int n)
{
static int *primes = NULL; // NOTE: static !
static int size = 0; // NOTE: static !
static int maxprime; // NOTE: static !
int root;
int i;
// Init primes array (executed on first call)
if (primes == NULL)
{
primes = (int *)malloc(2*sizeof(int));
if (primes == NULL)
exit(1);
size = 2;
primes[0] = 2;
primes[1] = 3;
maxprime = 3;
}
root = (int)(sqrt(n));
// Update primes array, if needed
while (root > maxprime)
for (i = maxprime + 2 ; ; i+=2)
if (isprime(i))
{
size++;
primes = (int *)realloc(primes, size * sizeof(int));
if (primes == NULL)
exit(1);
primes[size-1] = i;
maxprime = i;
break;
}
// Check 'special' cases
if (n <= 0)
return -1;
if (n == 1)
return 0;
// Check prime
for (i = 0 ; ((i < size) && (root >= primes[i])) ; i++)
if ((n % primes[i]) == 0)
return 0;
return 1;
}

Related

Why do I get different results depending on how many child processes I use?

I am working on a simple C program that recursively creates children and uses them to sum all the numbers in a file, depending on user input. There are three predetermined file sizes that the user can chose from, as well as three set amounts of children that can be generated. In theory, there could be any number of children or any size file, but for the sake of simplicity there are only 3 here.
The problem I'm running into is, no matter which file I use, the only time the sum is correct is when the program uses only 1 child. With other amounts of children, such as 4, the number is close, but not quite right. Can someone offer me any insight as to what is causing this issue?
Here is the section of code I think is problematic:
// C program to demonstrate use of fork() with pipe()
// By: Maxwell Wendlandt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <sys/wait.h>
#include <unistd.h>
int main()
{
FILE *file;
int numForks;
// initialize pipes for up to 4 children
int fd[4][2];
// initialize up to 4 processes
pid_t pid[4];
int total = 0;
int finalResult = 0;
char fileName[10] = "";
int fileNum;
int numLines;
// ask which file to scan
printf("Enter file number 1 (1000 nums), 2 (10000 nums) or 3 (100000 nums):\n");
scanf("%i", &fileNum);
// chose the file
switch(fileNum)
{
case 1 :
printf("File 1 selected.\n");
strcpy(fileName, "file1.dat");
numLines = 1000;
break;
case 2 :
printf("File 2 selected.\n");
strcpy(fileName, "file2.dat");
numLines = 10000;
break;
case 3 :
printf("File 3 selected.\n");
strcpy(fileName, "file3.dat");
numLines = 100000;
break;
default :
printf("Enter a valid file number next time.\n");
return 0;
}
// ask how many children (forks)
printf("Do you want 1, 2 or 4 child processes?\n");
scanf("%i", &numForks);
for (int i = 0; i < numForks + 1; i++)
{
if (pipe(fd[i]) == -1)
{
printf("Error with creating pipe.\n");
return 1;
}
}
for(int i = 0; i < numForks; i++)
{
pid[i] = fork();
if(pid[i] == -1)
{
printf("Error creating child.\n");
return 1;
}
if(pid[i] == 0)
{
// children
int sum = 0, num = 0;
int start, end;
file = fopen(fileName, "r");
start = i * (numLines / numForks);
printf("start: %i\n", start);
end = ((i + 1) * (numLines / numForks));
printf("end: %i\n", end);
fseek(file, (start * 4), SEEK_SET);
for(int i = start; i < end; i++)
{
fscanf(file, "%d", &num);
printf("num on line %d is: %d\n", i + 1, num);
sum += num;
}
printf("sum in child: %d\n", sum);
write(fd[i][1], &sum, sizeof(sum));
close(fd[i][1]);
return 0;
}
}
// parent
for(int i = 0; i < numForks; i++)
{
read(fd[i][0], &total, sizeof(total));
close(fd[i][0]);
finalResult += total;
}
printf("The grand total: %i\n", finalResult);
for(int i = 0; i < numForks; i++)
{
wait(NULL);
}
return 0;
}
Thanks in advance!
each line of the file has one 3 digit number on it. So a 1000 number file has 1000 lines.
This means each line consists of four five bytes - the three digits, the carriage return, and the newline character. e.g., 123\r\n. The off-by-two error here
fseek(file, (start * 3), SEEK_SET);
will cause each seek to drift, and each child will read from an earlier position than they should. If each line is five bytes, this should be start * 5.
Aside: I would hazard a guess the numbers in your files are padded with zeroes (see the generation example below).
If so, the fscanf specifier %i may not be desirable, as it acts as strtol with a base of 0, meaning the numbers base is determined by its first characters.
This may lead to confusing results when zero padded numbers are parsed as octal. For example:
004 - octal, value 4.
040 - octal, value 32.
400 - decimal, value 400.
009 - octal, invalid value (0).
011 - octal, value 9.
%d will parse the inputs as base-10 numbers.
This has a few problems.
printf("Do you want 1, 2 or 4 child processes?\n");
scanf("%i", &numForks);
for (int i = 0; i < numForks + 1; i++) {
if (pipe(fd[i]) == -1)
/* ... */
i < numForks + 1 is an off-by-one error. The user can also enter an arbitrary number.This will invoke Undefined Behaviour if fd is accessed via an out-of-bounds index.
In general, you should be checking the return values of more functions, such as scanf, fscanf, fseek, write, and read, to ensure you are working with valid data.
Prefer perror and fprintf(stderr, ...) to print useful error messages to the correct stream.
A very cursory refactoring:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <wait.h>
int main(void)
{
int numForks;
// initialize pipes for up to 4 children
int fd[4][2];
// initialize up to 4 processes
pid_t pid[4];
int total = 0;
int finalResult = 0;
char fileName[10] = "";
int fileNum;
int numLines;
printf("Enter file number 1 (1000 nums), 2 (10000 nums) or 3 (100000 nums):\n");
if (1 != scanf("%d", &fileNum)) {
fprintf(stderr, "Invalid number of files.\n");
return 1;
}
switch (fileNum) {
case 1:
printf("File 1 selected.\n");
strcpy(fileName, "file1.dat");
numLines = 1000;
break;
case 2:
printf("File 2 selected.\n");
strcpy(fileName, "file2.dat");
numLines = 10000;
break;
case 3:
printf("File 3 selected.\n");
strcpy(fileName, "file3.dat");
numLines = 100000;
break;
default:
printf("Enter a valid file number next time.\n");
return 0;
}
printf("Do you want 1, 2 or 4 child processes?\n");
if (1 != scanf("%d", &numForks) || 1 > numForks || numForks > 4 || numForks == 3) {
fprintf(stderr, "Invalid number of child processes.\n");
return 1;
}
for (int i = 0; i < numForks; i++) {
if (pipe(fd[i]) == -1) {
perror("pipe");
return 1;
}
}
for (int i = 0; i < numForks; i++) {
pid[i] = fork();
if (pid[i] == -1) {
perror("fork");
return 1;
}
// children
if (pid[i] == 0) {
int sum = 0, num = 0;
int start, end;
FILE *file = fopen(fileName, "r");
if (!file) {
fprintf(stderr, "Child %d failed to open ", i + 1);
perror(fileName);
return 1;
}
start = i * (numLines / numForks);
end = ((i + 1) * (numLines / numForks));
printf("start: %d\nend: %d\n", start, end);
if (-1 == fseek(file, (start * 4), SEEK_SET)) {
perror("fseek");
return 1;
}
for (int i = start; i < end; i++)
if (1 == fscanf(file, "%d", &num))
sum += num;
printf("sum in child: %d\n", sum);
write(fd[i][1], &sum, sizeof sum);
close(fd[i][1]);
return 0;
}
}
// parent
for (int i = 0; i < numForks; i++) {
if (sizeof total == read(fd[i][0], &total, sizeof total))
finalResult += total;
close(fd[i][0]);
}
for (int i = 0; i < numForks; i++)
wait(NULL);
printf("The grand total: %d\n", finalResult);
}
The code used to generate files to test with (./gen 1000 > file1.dat):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char **argv)
{
int i = 0;
if (argc > 1)
i = atoi(argv[1]);
srand((unsigned) time(NULL));
while (i-- > 0)
printf("%03d\n", rand() % 1000);
}
And a sanity checker (./sanity-check < file1.dat):
#include <stdio.h>
int main(void)
{
int sum = 0, num;
while (1 == scanf("%d", &num))
sum += num;
printf("%d\n", sum);
}

When trying to print from string getting error: Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)

I'm writing a function that receives a format normally seen in a printf call and a string of integers separated by an inconsistent amount of spaces. It prints the format how it would've been printed from printf with the correct representation of the integers.
I first tried to create the extractNums function that returns an array of all the integers from the second string sent to the printFormattedIntegers function.
But later in printFormattedIntegers I get a Exception: EXC_BAD_ACCESS (code=EXC_I386_GPFLT error when I simply try to print the first element of the format string. I found that if I comment out the extractNums function call, I get no error and it works.
I'm not sure why the extractNums call interrupts the rest of the program, any ideas?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define I 1
#define V 5
#define X 10
#define L 50
#define C 100
#define D 500
#define M 1000
void printFormattedIntegers(char* format, char numbers[]);
char converter(char c, int num);
int charToInt(char* str);
int* extendArr(int* arr, int currSize);
int* extractNums(char* nums);
void printDecAsBin(int num);
void printDEC(int num);
void printHEX(int num);
void printOCT(int num);
void printBIN(int num);
void printROM(int num);
void main()
{
char format[100];
char numbers[100];
printFormattedIntegers("Dec: %d Hex: %x Roman: %r", " 123 10 9");
}
void printFormattedIntegers(char* format, char* numbers)
{
int formatInd = 0, numsInd = 0;
int* numsArr = extractNums(numbers);
while (format[formatInd] != '\0')
{
if (format[formatInd] != '%')
printf("%c",format[formatInd]);
else
{
converter(format[formatInd+1], numsArr[numsInd]);
numsInd++;
}
formatInd++;
}
}
char converter(char c, int num)
{
switch(c)
{
case 'd':
printDEC(num);
break;
case 'x':
printHEX(num);
break;
case 'o':
printOCT(num);
break;
case 'b':
printBIN(num);
break;
case 'r':
printROM(num);
break;
case '\0':
printf("%%");
break;
default:
printf("%%%c",c);
break;
}
}
int charToInt(char* str)
{
int mult = 1;
int re = 0;
int len = strlen(str);
for(int i = len -1 ; i >= 0 ; i--)
{
re = re + ((int)str[i] -48)*mult;
mult = mult*10;
}
return re;
}
int* extendArr(int* arr, int currSize)
{
int* newArr;
int i;
newArr = (int*)malloc((currSize+1) * sizeof(int));
if (newArr == NULL)
{
printf("Memory allocation failed.\n");
exit(1);
}
for (i=0;i<currSize;i++)
newArr[i] = arr[i];
free(arr);
return newArr;
}
int* extractNums(char* nums)
{
char *copiedStr, *token;
int *newArr=NULL,counter = 0, intChar;
char sep[] = " ";
strcpy(copiedStr,nums);
token = strtok(copiedStr,sep);
while (token != NULL)
{
intChar = charToInt(token);
newArr = extendArr(newArr,counter);
newArr[counter] = intChar;
counter++;
token = strtok(NULL,sep);
}
}
void printDecAsBin(int num)
{
if (num == 0)
printf("0");
else if (num == 1)
printf("1");
else
{
printDecAsBin(num / 2);
printf("%d", num % 2);
}
}
void printDEC(int num)
{
printf("%d", num);
}
void printHEX(int num)
{
printf("%x", num);
}
void printOCT(int num)
{
printf("%o", num);
}
void printBIN(int num)
{
printDecAsBin(num);
}
void printROM(int num)
{
while (num >= M)
{
num -= M;
printf("M");
}
if (num >= M - C)
{
printf("CM");
num -= (M - C);
}
else if (num >= D)
{
printf("D");
num -= D;
}
while (num >= C)
{
num -= C;
printf("C");
}
if (num >= C - X)
{
printf("XC");
num -= (C - X);
}
else if (num >= L)
{
printf("L");
num -= L;
}
while (num >= X)
{
num -= X;
printf("X");
}
if (num >= X - I)
{
printf("IX");
num -= (X - I);
}
else if (num >= V)
{
printf("V");
num -= V;
}
while (num > 0)
{
num -= I;
printf("I");
}
}
You are writing to unallocated memory. That invokes Undefined Behaviour and from that point anything can happen at any moment:
int* extractNums(char* nums)
{
char *copiedStr, *token; // copiedStr is an initialized pointer here
int *newArr=NULL,counter = 0, intChar;
char sep[] = " ";
strcpy(copiedStr,nums); // use of the initialized pointer: UB!

Using * in main() parameters for command-line calculator

I'm doing a homework problem which is to create a calculator using the argc and argv[] parameters in the main function.
What we were supposed to do, and I did, was to create a char pointer array containing the operators I want to use.
this is what I have:
const int OTabMax = 10;
const char *OTab[] = {
"+",
"-",
"*",
"/",
"quad",
"wurz",
"sinR",
"sinG",
"cosR",
"cosG"
};
int OTabCheck(char S[]) // char *S
{
int n;
for (n = 0; n < OTabMax; n++){
if (strcmp(S, OTab[n]) == 0) {break;}
}
return n;
}
It returns a number depending on which operator was used, which goes into a switch case where the calculation is done.
looks like this:
switch(key){
case 0:
break;
case 1:
break;
case 2:
x = atof(argv[1]);
y = atof(argv[3]);
z = 0;
z = x*y;
printf("%f * %f = %f\n",x,y,z);
break;
case 3-8;
break;
case 9:
break;
default: printf("Wrong input!\n"); exit(0); break;
}
The case in question is case 2: which whenever I do a calculation like calling the program through the terminal with ./"program_name" 2 * 2
it printf's 2.000000 * 0.000000 = 2.000000
here is the MRE:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
const int OTabMax = 10;
const char *OTab[] = {
"+",
"-",
"*",
"/",
"quad",
"wurz",
"sinR",
"sinG",
"cosR",
"cosG" };
int OTabCheck(char S[]) // char *S
{
int n;
for (n = 0; n < OTabMax; n++){
if (strcmp(S, OTab[n]) == 0) {break;}
}
return n;
}
int main(int argc,char *argv[]){
float x = 0;
float y = 0;
float z = 0;
int key = 0;
if(argc < 3){
exit(0);
}
if(argc == 4){
key = OTabCheck(argv[2]);
}else if(argc == 3){
key = OTabCheck(argv[1]);
}
switch(key){
case 2:
x = atof(argv[1]);
y = atof(argv[3]);
z = 0;
z = x*y;
printf("%f * %f = %f\n",x,y,z);
exit(0);
break;
default: printf("Wrong input!\n"); exit(0); break;
}
}

c program will not read user input

I am writing a client/server and after I am done getting information from the clients they close. Now I am trying to ask the user (server side) if they would like to continue but my program jumps straight to the end of the program.
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
main (void)
{
int to_server; // to read from client
int from_server; // to write to client
int finish; // lets me know that client is done
int i,j,k,m,l,p; // because C needs this defined as int
int numClient;// number of clients
char temp[14];
int page_size = 128;
int pages_left;
int max_frames=10;
int used_frames = 0;
int frameUpdate=0;
int freeframe[10] = {3,0,9,8,7,5,1,4,2,6};
int numpage=0;
int frames;
int client1[5];
int client2[5];
int client3[5];
int check;
int option;
int byte;
int search;
int getPage;
int getOffset;
int physical_Addr;
int offset;
int req[3];
int dummy = 0;
int again;
struct values{
char privFifo[14];
int memoryreq;
}cinput;
/* Create the fifos and open them */
if ((mkfifo("FIFO1",0666)<0 && errno != EEXIST))
{
perror("cant create FIFO1");
exit(-1);
}
if((to_server=open("FIFO1", O_RDONLY))<0){
printf("cant open fifo to write");
}
//get number of clients
printf("\nHow many clients?\n");
scanf("%d", &numClient);
for(j =1; j <= numClient; j++){
read(to_server, &cinput, sizeof(cinput));
printf("\n\nFifo_%d \nMemory request %d", cinput.privFifo, cinput.memoryreq);
req[j-1] = cinput.memoryreq;
if(cinput.memoryreq > 1280){
printf("\nERROR! Insufficient memory for request!");
exit(-1);
}
if((mkfifo(cinput.privFifo,0666)<0 && errno != EEXIST))
{
perror("cant create privFifo");
exit(-1);
}
if((from_server=open(cinput.privFifo, O_WRONLY)<0)){
printf("cant open fifo to write");
}
// find number of pages need for request
numpage = cinput.memoryreq/page_size;
if((numpage * page_size) < cinput.memoryreq){
numpage++;
}
sleep(1);
printf("\nPages needed %d", numpage);
write(from_server, &numpage, sizeof(numpage));
printf("\n******Main Memory******");
for(m = 0; m < numpage; m++){
if(j==1){
printf("\n* client: %d\tframe: %d", j, freeframe[m]);
frames = freeframe[m];
client1[m] = frames;
// write(from_server, &frames, sizeof(frames));
used_frames++;
}
else if (j == 2){
printf("\n* client: %d\tframe: %d", j, freeframe[dummy]);
frames = freeframe[dummy];
write(from_server, &frames, sizeof(frames));
used_frames++;
dummy++;
}
else if (j == 3){
printf("\n* client: %d\tframe: %d", j, freeframe[dummy]);
frames = freeframe[dummy];
write(from_server, &frames, sizeof(frames));
used_frames++;
dummy++;
}
}
dummy = used_frames;
used_frames = max_frames - used_frames;
if(j==1){
pages_left = max_frames - numpage;
}
else {
pages_left = dummy;
}
printf("\n Frames available:");
for(l = pages_left; l!= 0; l--){
check = max_frames - l;
printf(" %d", freeframe[check]);
}
pages_left = check;
close(from_server);
unlink(cinput.privFifo);
}
printf("\nDONE!!!");
close(to_server);
unlink("FIFO1");
}
Here is my problem area (sorry for my messy code ):
printf("press 1 to find Physical address of a byte?");
scanf("%d\n", &again);
while(again == 1){
printf("\nWhich client are we accessing? ");
scanf("%d", &option);
printf("\nWhat byte would you like to find? ");
scanf("%d", &byte);
if(option == 1){
for(p = 0; p < sizeof(client1); p++){
search = p*page_size;
if(search <= byte)
getPage= client1[p];
}
getOffset=byte%page_size;
physical_Addr = (getPage * page_size) + offset;
printf("Physical Address is %d", physical_Addr);
}
else if(option == 2){
for(p = 0; p < sizeof(client1); p++){
search = p*page_size;
if(search <= byte)
getPage= client1[p];
}
getOffset=byte%page_size;
physical_Addr = (getPage * page_size) + offset;
printf("Physical Address is %d", physical_Addr);
}
else if(option == 3){
for(p = 0; p < sizeof(client1); p++){
search = p*page_size;
if(search <= byte)
getPage= client1[p];
}
getOffset=byte%page_size;
physical_Addr = (getPage * page_size) + offset;
printf("Physical Address is %d", physical_Addr);
}
else{
printf("ERROR!");
}
printf("Press 1 to choose another client.");
scanf("%d", &again);
}

Where is the logical error in this C program?

This is a simple program: pass user input via the main function in order to compute the range of a series of integers. However, the program is defaulting to the usage function. In other words, it does not seem to accept input from the command line.
The program executes, but somewhere along the way it reaches a condition where the usage message is printed to the terminal.
Here's the program:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
int range(int a[], int *n, int *rng){
//Declarations
int i; //Dummy variable
int min;
int max;
//Validate input
if(!a || !n || !rng || *n <= 0) return -1;
//Main execution
min = a[0];
max = a[0];
for(i=0; i<*n; i++){
if(a[i]<min)
min = a[i];
if(a[i]>max)
max = a[i];
}
*rng = max-min;
return 0;
}
void printUsage() {
printf("\nUsage:[-s <series of at least two integers>] [-h help].");
}
int main(int argc, char **argv){
//Declarations
int setInt[100];
int i; //Dummy index
int n; //Temp variable
int err;
int rng;
//Run some tests to determine validity of input
for(i=0; i<argc; i++){
//Is there at least some user input?
if(argc == 1){
printUsage();
return -1;
}
//Determine if the user requested usage
if(strcmp("-h", argv[i]) == 0){
printUsage();
return -1; //TRY REMOVING LATER TO SEE IF PROGRAM CAN KEPP RUNNING
}
//Determine if the user entered some data
else if(strcmp("-s", argv[i]) == 0){
//There must be at least TWO arguments after this call
if((i+1) == argc || (i+2) == argc){
printUsage();
return -1;
}
//Start another loop to fill an array of values the user entered
//Reuse i, but start at three to grap the first supposed integer
for(i=3; i < argc; i++){
err = sscanf(argv[i], "%d", &n);
if(err == 0) {//The input wasn't an integer
printUsage();
return -1;
}
else {
assert(err == 1);
setInt[i-3] = n; //Store the variable in an array
}
}
}
else{//unknown input
printUsage();
return -1;
}
//For bracket
}
//Call the function
printf("The range of values entered is %d.", rng);
range(setInt, &argc, &rng);
getchar();
getchar();
return 0;
//Main bracket
}
the problem is that you don't increment i before looking for -s
change the line
else if(strcmp("-s", argv[i]) == 0){ //i is still zero, so argv[i] is the command entered
to
else if(strcmp("-s", argv[++i]) == 0){
(add ++ before the i) and it won't print usage.

Resources