Check command line input in C - c

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int allDigits(char *S) {
while ( *S ) {
if ( ! isdigit(*S)) return 0;
S++;
}
return 1;
}
int main (int argc, char *argv[]) {
int i, /*for loop index*/
sum=0; /*the sum of the arguments*/
for (i=1; i<argc; i++) {
if ( allDigits(argv[i]))
sum = sum + atoi(argv[i]);
else {
fprintf(stderr,"Usage: %s [<int> <int> ... <int>]\n",argv[0]);
exit(1);
}
}
printf("Sum of the %d integers is %d\n", argc-1, sum);
exit(0);
}
I got this example from my notes, which check the command line input to see whether is a number or not. However, there is one part I don't really understand how that works, in the function allDigits we used isdigit() to check the input. But why we put ! in front of isdigit?
Can anyone explain this part to me?

Related

Segmentation Fault when using command-line arguments

I'm new to programming. Following is a program I wrote to calculate the probability distribution of random 6-sided dice throws. It works perfectly, however if I use command-line argument for number of throws, it starts throwing up segmentation fault error. Can somebody help me understand what I am doing wrong ?
// distribution of rand numbers
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
const unsigned short NUM_FACES = 6;
int main(int argc, char * argv[])
{
if(argc != 2 || isdigit(argv[1]))
{
printf("Invalid arguments!!\n");
printf("Usage: %s numThrows\n", argv[0]); //correct usage of arguments
exit(EXIT_FAILURE);
}
system("clear");
srand(time(0)); //updating seed
long upperLim = atol(argv[1]);
long dist[7] = {0};
double probab = 0.0;
unsigned int i;
for(i = 0; i < upperLim; i++)
++dist[rand()%6 + 1]; //generating random numbers (1-6)
for(i = 0; i < NUM_FACES; i++)
{
probab = 100.0*dist[i]/upperLim; //calculating probability of each throws
printf("DICE THROW %d -> Number of throws: %ld Distribution: %.2lf%c\n", i+1, dist[i], probab, '%');
}
getchar();
return 0;
}
isdigit(argv[1])
isdigit wants an int, not a char *
If you want to ckeck if all characters are digits you can use something like:
bool strIsDigit(const char *str)
{
while (*str)
{
if (!isdigit((unsigned char)*str++))
{
return false;
}
}
return true;
}

For Loop Not Iterating the Right Amount of times

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int rnd = list[modo];
}
return 1;
}
This code compiles fine, I just have a question as to why the for loop isn't iterating till size < i Where i is the same size as the integer argument that gets passed int.
It's supposed to keep printing %d until it reaches size i but it only prints one random number.
I'm trying to get it to print the amount of random numbers that are passed as an argument.
So if you enter ./main 3 to run the program for example it prints: 0 4 5 or ./main 4 it prints: 2 1 5 6
There is a return 0 inside the for statement block, this exits the main function and ends the program, remove this line. (And change the last line return 1 to return 0.)
isrnick answer is spot on. Anyway, the program has many other problems.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main( int argc, int *argv[] ) { // <--- Must be int main(int argc, char *argv[])
srand(time(NULL)); // <--- Warning, you need a cast here.
int list[10] = {0,1,2,3,4,5,6,7,8,9}; // <--- Why?
int modo = rand() %11; // <--- Must be %10 if desired max is 9
int rnd = list[modo]; // <--- This will be a single value for the program
int arr[argc]; // <--- VLAs? Why?
int i = argv[1]; // <--- Warning, C string to int... you need a conversion function
int size = 0;
for (size = 0; size < i; size++){ // <--- Do yourself a favor, use i as the looping variable
srand(time(NULL)); // <--- One srand per program
printf("%d \n", rnd); // <--- always print the same number
return 0; // <--- Terminate program here? No, no.
}
return 1; // <--- If no error, return 0.
}
Minimal fixed version (no checks):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
srand((unsigned int)time(NULL));
int n = atoi(argv[1]);
for (int i = 0; i < n; i++) {
int rnd = rand() % 10;
printf("%d ", rnd);
}
return EXIT_SUCCESS;
}
More controls:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
return EXIT_FAILURE;
}
srand((unsigned int)time(NULL));
int n;
if (sscanf(argv[1], "%i", &n) != 1) {
return EXIT_FAILURE;
}
if (n < 0) {
return EXIT_FAILURE;
}
for (int i = 0; i < n; i++) {
int rnd = rand() % 10;
printf("%d ", rnd);
}
return EXIT_SUCCESS;
}

read indefinite amount of integers and print on file

*this program read integers until one is negative then prints on a file a characteristic of each of them: how many integers it can be divided by. the problem is that it keeps asking for integers even when i inseert negative ones. please let me know if you can a way to fix this without changing too much of the code
#include <stdio.h>
#include <stdlib.h>
int checkdiv(int *n);
int main(int argc, char * argv[]){
int *p;
int i, j;
FILE *fp;
int amount;
i=0;
p=NULL;
if(fp = fopen("ris.txt", "w")){
do{i++;
p=realloc(p,sizeof(int)*i);
scanf("%d", (p+i-1));
amount=checkdiv(p+i-1);
if(amount!= -1);
fprintf(fp,"%d %d\n", *(p+i-1),amount);
}while(p+i-1>0);
}else{
printf("errore");
}
fclose(fp);
free(p);
return 0;
}
int checkdiv(int *n){
int i;
int amount=0;
for(i = 2;i < *n; i++){
if(*n % i == 0){
amount++;
}
}
if(*n <= 0){
amount= -1;
}
return amount;
}
Your problem is in:
}while(p+i-1>0);
must be;
}while(*(p+i-1)>0);
HTH
You should remove semi colon in line
if(amount!=-1);
so that the statement below it can be included in if block.

How to work with functions and outputs C

I want to enter 4 numbers and display the largest possible number. Can anybody help me with this please? I have tried multiply different approaches, so do not wonder why there are so many libraries.
Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h> //pow
#include <limits.h> //char max
#include <ctype.h> //
int sort_alg(const void *a, const void *b)
{
char ab[32], ba[32];
sprintf(ab, "%d%d", *(int*)a, *(int*)b);
sprintf(ba, "%d%d", *(int*)b, *(int*)a);
return strcmp(ba, ab);
}
void max_numb(int *a, int len)
{
int i;
qsort(a, len, sizeof(int), sort_alg);
for (i = 0; i < len; i++)
printf("%d", a[i]);
putchar('\n');
}
int main(void)
{
int numbers[4];
for(int count = 0; count < 4; count++)
{
scanf("%d", &numbers[count]);
printf("%d", numbers);
}
max_numb(numbers, sizeof(numbers)/sizeof(numbers[0]));
return 0;
}
Why don't you try some algorithm. It's pretty easy to select just the maximum. You don't have to sort it
Try this:
int max(int a[],int len)
{
int max=a[0];
for(int i=0;i<len;i++)
{
if(max<a[i])
max=a[i];
}
return max;
}
Sorry if I misunderstood your query. I answered by the title.
If printing the largest of the numbers entered is your sole purpose, you can do it without any sorting algorithm. While getting inputs, just use a variable that stores the highest number entered till now, and update the variable if any new value greater than maxim is entered
Code
int main() {
int numbers[4];
int maxim = -99999; //any small that you can assue to be minimimum
for(int count = 0; count < 4; count++) {
scanf("%d", &numbers[count]);
printf("%d ", numbers[count]);
if(numbers[count] > maxim) {
maxim = numbers[count];
}
}
printf("\n") ;
printf("Maximum Value : %d\n", maxim) ;
return 0;
}
Sorry if I misunderstood your question.
the following proposed code:
performs the desired functionality.
cleanly compiles
documents why each header file is included
properly checks for errors from system functions
caveat: does not check that all entered numbers are positive ( >= 0 )
Notice that proposed code is failing to prompt the user for each value to input, so the user will be looking at a blank terminal, with a blinking cursor (and wondering what to do) So the code should be prompting the user for each number.
and now, the proposed code
#include <stdio.h> // scanf(), fprintf(), printf(), putchar(), sprintf()
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <string.h> // strcmp()
#define MAX_NUMBERS 4
// prototypes
int sort_alg(const void *a, const void *b);
void max_numb( int Numbers[] );
int main( void )
{
int numbers[ MAX_NUMBERS ];
for( int count = 0; count < MAX_NUMBERS; count++ )
{
if( 1 != scanf("%d", &numbers[count]) )
{
fprintf( stderr, "scanf for number: %d failed\n", count+1 );
exit( EXIT_FAILURE );
}
// implied else, scanf successful
printf( " %d", numbers[ count ] ); // leading space for formatting
}
max_numb( numbers );
return 0;
}
int sort_alg(const void *a, const void *b)
{
char ab[32], ba[32];
sprintf(ab, "%d%d", *(int*)a, *(int*)b);
sprintf(ba, "%d%d", *(int*)b, *(int*)a);
return strcmp(ba, ab);
}
void max_numb( int Numbers[] )
{
qsort( Numbers, MAX_NUMBERS, sizeof(int), sort_alg);
putchar( '\n' ); // so output from 'max_numb()' will be on a new line
for (int i = 0; i < MAX_NUMBERS; i++)
printf( "%d", Numbers[i] );
putchar( '\n' );
}
a typical run of the proposed code outputs:
1 2 3 4
1 2 3 4
4321

palindrome program (not working) i dont know why

I tried making a small program that would detect if you typed in a palindrome but for some reason, it just loops
ps I'm a beginner
#include <stdio.h>
#include <string.h>
int main(void)
{
char arr[100], arr1[100];
int i;
printf("type in a string\n\n");
gets(arr);
strrev(arr) == arr1;
for (i=0; arr==arr1; i++)
{
printf("%c is a palindrome\n", arr);
}
for (i=0; arr!=arr1; i++)
{
printf("%c is not a palindrome\n", arr);
}
return 0;
}
arr and arr1 are base address of the two arrays respectively which would be different.One simple Code is here
#include <stdio.h>
#include <string.h>
int main(void)
{
char arr[100], arr1[100];
int i;
printf("type in a string\n\n");
gets(arr);
int len=strlen(arr);
strcpy(arr1,arr);
strrev(arr);
for(i=0;i<len;i++){
if(arr1[i]!=arr[i]){
printf("Not palindrome");
return 1;
}
}
printf("Palindrome");
return 0;
}
Use fgets instead of gets.
The first character could be compared to the last character. Then move the indexes toward the center for subsequent comparisons.
#include <stdio.h>
#include <string.h>
int main(void) {
char arr[100] = "";
int first = 0;
int last = 0;
printf ( "type in a string\n\n");
if ( !fgets ( arr, sizeof arr, stdin)) {
printf ( "fgets problem\n");
return 0;
}
arr[strcspn ( arr, "\n")] = '\0';//remove newline
for ( first = 0, last = strlen ( arr) - 1; first <= last; first++, last--) {
if ( arr[first] != arr[last]) {
printf("%s is not a palindrome\n", arr);
return 0;
}
}
printf ( "%s is a palindrome\n", arr);
return 0;
}

Resources