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.
Related
If the user inputs a value that matches with an int in the array continue the program else quit the program.
My issue is that the function loops the whole array and if it finds one of the values doesnt match it will quit.
//Check if the user input matches with one of the ints in the array
void check(int num, int arr[]) {
for (int i = 0; i < 3; i++) {
if (arr[i] != num) {
printf("Invalid input");
exit(0);
}
}
}
void main() {
int arr[3] = { 1, 2, 3 };
int num = 0;
for (int i = 0; i < 3; i++) {
printf("%d ", arr[i]);
}
printf("\nPLease enter a value which matches with the array %d", num);
scanf("%d", &num);
check(num, arr);
}
void check(int num, int arr[]) {
for (int i = 0; i < 3; i++) {
if (arr[i] == num) {
return;
}
}
printf("Invalid input");
exit(0);
}
Your issue is that checks a single element and judges the input on that specific value. If it has run through each value and the function has still not returned, there is not match and we can exit the program.
You have a logic flaw in the check function: you should output the message and quit if none of the values match the input. You instead do this if one of the values does not match. The check always fails.
Here is a modified version:
#include <stdio.h>
//Check if the user input matches with one of the ints in the array
void check(int num, const int arr[], size_t len) {
for (size_t i = 0; i < len; i++) {
if (arr[i] == num) {
// value found, just return to the caller
return;
}
}
// if we get here, none of the values in the array match num
printf("Invalid input: %d\n", num);
exit(1);
}
int main() {
int arr[3] = { 1, 2, 3 };
size_t len = sizeof(arr) / sizeof(*arr); // length of the array
int num;
for (size_t i = 0; i < len; i++) {
printf("%d ", arr[i]);
}
printf("\n");
printf("Please enter a value which matches with the array: ");
if (scanf("%d", &num) == 1) {
check(num, arr, len);
} else {
// input missing or not a number
printf("Invalid input\n");
}
return 0;
}
You are right, you do exit once arr[i] != num (When the value is not the same as the i:th element in the array).
So, you could change it to: arr[i] == num. If it is the same, perhaps print "You got it!", and a return afterwards.
So i have een solving a problem where i have to find the prime numbers from the input file and save those prime numbers in an output file called output.txt.But If there are no prime numbers in the input file, i'll have to write “No prime numbers found” in the output file.So when i completed the code when there is no prime number it shows No prime numbers found 5-6 times and i only want it to appear 1 time.What is my mistake here?I am totally a noob here
#include <stdio.h>
#include <stdlib.h>
int Primecheck(const int number);
int main()
{
FILE* Number,
* Prime_N;
int num;
char sentence[50] = "No prime numbers found";
int length = strlen(sentence);
int i;
Number = fopen("input.txt", "r");
Prime_N = fopen("output.txt", "w");
if (Number == NULL || Prime_N == NULL)
{
printf("Unable to open file.\n");
exit(EXIT_FAILURE);
}
printf("File opened and Reading Done \n\n");
while (fscanf(Number, "%d", &num) != -1)
{
if (Primecheck(num) == 1)
fprintf(Prime_N, "%d\n", num);
else
for (i = 0; i < length; i++)
{
fputc(sentence[i], Prime_N);
}
}
fclose(Number);
fclose(Prime_N);
printf("Overwrite Success.");
return 0;
}
int Primecheck(const int number)
{
int i;
if (number < 0)
return 0;
for (i = 2; i <= number / 2; i++)
{
if (number % i == 0)
{
return 0;
}
}
return 1;
}
instead of
else
for(i=0;i<length;i++)
{
fputc(sentence[i] ,Prime_N);
}
you can just write
else
printf("No prime numbers found");
Well , as I see from your code , each time you read a number from the file you check if prime write it or write sentence . so of course you get multiple output ,
you should write the number to char* then check if changed after reading from Number and checking if prime write the number in the char* after the loop just check if the length of the char* that you stored the primes in it if changed write it else write your sentence ... Done
something like this
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
typedef struct {
char* data;
size_t size;
size_t capacity;
} string;
void init_string(string* s, size_t size){
s->data = (char*)malloc(sizeof(char) * size);
s->capacity = size;
s->size = 0;
}
void append(string* s,const char* str){
if(s->capacity - s->size < strlen(str)){
s->data = (char*)realloc(s->data, sizeof(char)* 4 * strlen(str));
}strcat(s->data, str);
}
void free_string(string* s){
free(s->data);
}
int is_odd(int n){
return n%2;
}
int main(){
int num[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19};
string str;
init_string(&str,1);
char* snum;
for(int i=0; i<18; i++){
if(!is_odd(i)){
sprintf(snum,"%d",num[i]);
append(&str, snum);
append(&str, "\n");
}
//printf(snum);
//strcat(str, snum);
}
printf("%s",str.data);
free_string(&str);
//printf(str);
return 0;
}
Is this is program to print prime numbers between two numbers
a and b (null safe or not)?
if not , How to add null safe function to make it (NULL SAFE)
I have tried checking if argv[1] or argv[2] are equall to 0
but it is not how it should work
any Ideas for this?
//check if a or b or both are negative numbers
int check_negative(int *x, int *y){
if(*x<0 || *y<0)
{
printf("Error : One or Both arguments are Negative\n");
return 1;
}
}
//check if n is a prime number
int isprime(int n)
{
int i, status = 1;
for(i=2; i <= n/2; ++i)
{
if (n%i == 0)
{
status = 0;
break;
}
}
return status;
}
int main(int argc, char* argv[] )
{
if(argc==1)
{
printf("Error : No arguments were passed\n");
return 0 ;
}
int a=atoi(argv[1]),b=atoi(argv[2]),n,status;
if(check_negative(&a,&b)==1)
{
return 0;
}
printf("Prime numbers between %d and %d are: \n", a, b);
for(n=a+1; n<b; ++n)
{
status = isprime(n);
if(status == 1)
printf("%d ",n);
}
return 0;
}
Is this c program null safe?
No.
The below fails when argc < 3 (e.g. 2,1,0) as it calls atoi() with NULL or unknown. #Ian Abbott
int a=atoi(argv[1]),b=atoi(argv[2]),n,status;
Instead change prior test from only testing against 1 to the below. Note that argc == 0 is possible on select platforms and with certain function calls.
// if(argc==1)
if(argc < 3)
As a stand-alone function, check_negative() does not check if a null pointer argument is passed before de-referencing. Add checks
int check_negative(int *x, int *y){
if (x == NULL || y == NULL) return 0; /// or handle in some way
Aside:
isprime(Any_int_less_than_2) errantly returns 1.
for(i=2; i <= n/2; ++i) is very slow for large n. Suggest speedier for(i=2; i <= n/i; ++i). Sample
What in the world, is the matter here:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int array[20];
int *pArray = array;
int count;
int i = 0;
while(1)
{
scanf("%d", array+i );
if(*(pArray+i) == -1) break;
i++;
}
printf("Contents: ");
while(1){
if (*(pArray + i) != -1)
{
printf("%d ", *(pArray + i) );
i++;
}
}
return 0;
}
Thank you. I am trying to take input from the user and then display the contents of the array. I was going to arrange them in order too using pointers, but I'll wait till someone replies.
Here is my rewrite attempt:
#include <stdio.h>
int main(void)
{
int array[20];
int i = 0;
while(1)
{
scanf("%d", &array[i] );
if(array[i] == -1) break;
i++;
}
printf("Contents: ");
i = 0; // RESET the counter back to ZERO.
while(1)
{
if (array[i] != -1)
{
printf("%d ", array[i] );
i++;
}
}
return 0;
}
You may be facing the error of stack around the variable array is corrupted. The reason is that you are first taking an input and then terminating the loop if the given input was -1.
scanf("%d", array+i );
if(*(pArray+i) == -1) break;
Now assume that i=20 what will happen???
Of course your code will crash on the scanf statement because it will try to access array+20 (the 20th index) which will not be allowed.
You also need to initialize the array first because when you declare an array, it contains junk values perhaps initializing the last index with zero will do the job. You can use the following code:
#include <stdio.h>
int main(void)
{
int array[20];
/*INITIALIZE THE LAST INDEX WITH -1 TO APPLY THE TERMINATING CONDITION*/
array[19] = -1;
int i = 0;
while(1)
{
scanf("%d", array+i );
i++; //INCREMENT HERE TO CHECK THE NEXT INDEX INSTEAD OF CHECKING THIS ONE
if(array+i == -1)
{
scanf("%d", array+i ); //TAKE THE INPUT FOR THE LAST INDEX
break; //TERMINATE THE LOOP
}
}
printf("Contents: ");
i = 0; // RESET the counter back to ZERO.
while(i != 20)
{
printf("%d ", array[i] );
i++;
}
return 0;
}
It seems like you are using pArray without any reason. array can also do exactly what you are trying to do with pArray. For arranging the order, you have to apply any sorting algorithm. Hope this helps.
I had a bunch of problems with this program but looks like this might be inches away from completion and I was hoping someone could tell me what the hell's wrong with the blasted thing!
#include <stdio.h>
#include <string.h>
#define SIZE_OF_STRING 21
void displayMenu(void);
void readArray(char [][SIZE_OF_STRING], int);
void printArray(char [][SIZE_OF_STRING], int);
int shortestArray(char [][SIZE_OF_STRING], int);
int smallestArray(char [][SIZE_OF_STRING], int);
void sortArray(char [][SIZE_OF_STRING], int);
int main(void)
{
int position, n = 0; /* all local to main */
char select[10]; /* select is a string */
char array[1000][SIZE_OF_STRING];
displayMenu();
scanf("%s", select); /* read first selection */
while (strcmp(select, "exit") != 0) /* while not exit */
{
if (strcmp(select, "read") == 0)
{
printf("How many names?");
scanf("%d", &n);
n++;
printf("Enter %d names", n - 1);
readArray(array, n);
}
else if (strcmp(select, "display") == 0)
{
printArray(array, n);
}
else if (strcmp(select, "shortest") == 0)
{
position = shortestArray(array, n);
printf("Shortest name is %s in position %d\n", array[position], position + 1);
}
else if (strcmp(select, "lowest") == 0)
{
position = smallestArray(array, n);
printf("Lowest name is %s in position %d\n",
array[position], position + 1);
}
else if (strcmp(select, "sort") == 0)
{
sortArray(array, n);
}
else
{
printf("INVALID SELECTION");
}
displayMenu();
scanf("%s", select); /* read next selection */
} /* end while */
}/* end main */
void displayMenu(void)
{
puts("Menu selection");
puts("Enter read to read names");
puts("Enter display to display names");
puts("Enter shortest for shortest name");
puts("Enter lowest for lowest names");
puts("Enter sort to sort names");
puts("Enter exit to exit\n");
}
void readArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
gets(a[i]);
}
}
void printArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
puts(a[i]);
}
}
int shortestArray(char a[][SIZE_OF_STRING], int n)
{
int i;
int chag = 0;
int position;
while (a[i] != '\0')
{
if (strlen(a[i]) < strlen(a[i-1]))
{
position = i;
chag = 1;
}
else
{
if (chag = 0)
{
position = 1;
}
else
{
printf("");
}
}
}
return position;
}
int smallestArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
return 0;
}
void sortArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
}
only worried about "shortest" function at the moment all others run okay.
I also know there are better ways of doing the search but I keep getting "declaration creates integer from pointer without cast" errors when I change to a more standard search with a default smallest etc.
chag is to say whether or not number one in a[] is the smallest as it never gets checked, going to change this as soon as I get it working as I can see a more effective way of doing it.
[edit]
My bad, the error that appears is an application error when "smallest" is selected.
the following appears
"the instruction at "0x77c478c0" referenced memory at "0xd2fd82e0". the memory could not be "read".
ok to terminate program, cancel to debug.
changed the shortest function to the following and still get a similar memory message;
int shortestArray(char a[][SIZE_OF_STRING], int n)
{
int i = 1;
int position = 1;
while (a[i] != '\0')
{
if (strlen(a[i + 1]) < strlen(a[i]))
{
position = i + 1;
i++;
}
else
{
i++;
}
}
return position;
}
There's a clbuttic typo in shortestArray():
if (chag = 0) {
position = 1;
}
// ...
This will always evaluate to false, so the else block is run.
Here, zero is assigned to chag which makes the expression evaluate to zero (false). Use the comparision operator == instead. You might want to crank up warning levels as I'm sure, any C compiler has an appropriate message for this.
One big and obvious problem is that in the function you use the variable i without initializing it.
Another problem is this expression: strlen(a[i-1]). If i is 0 then this will access memory before the array.
In addition to the other answers so far:
You don't increment i either.
If I imagine all the trivial fixes applied (correct iteration, comparison instead of assignment in the condition), the function is going to return position of last local minimum of length. I.e. having list of strings like
"a", "bbbb", "ccc", "dd"
it will return 3, but shortest string is at position 0!
You do remember array indices in C start from 0, right (in position = 1)?
you have to know the number of strings entered in the array to avoid unknown behavior.
a way to do this : in main, just after declaration of array, put :
strcpy(array[0], ""); // to indicate that the array is empty.
in the end of readArray() :
strcpy(a[n] , ""); // there is n strings written bythe user (a[0] to a[n-1]).
and finally :
in shortestArray(), the stop condition of the loop must be changed to :
while (strcmp(a[i],"") != 0 ) //a[i] == '\0' is not correct because a[i] is string and '\0' is char.
here is the entire code with the changes i made :
#include <stdio.h>
#include <string.h>
#define SIZE_OF_STRING 21
#define SIZE_OF_ARRAY 1000
void displayMenu(void);
void readArray(char [][SIZE_OF_STRING], int);
void printArray(char [][SIZE_OF_STRING]);
int shortestArray(char [][SIZE_OF_STRING]);
int smallestArray(char [][SIZE_OF_STRING], int);
void sortArray(char [][SIZE_OF_STRING], int);
int main(void)
{
int position, n = 0; /* all local to main */
char select[10]; /* select is a string */
char array[SIZE_OF_ARRAY][SIZE_OF_STRING]; //change here !
strcpy(array[0] , ""); //instruction added : means array is empty
displayMenu();
scanf("%s", select); /* read first selection */
while (strcmp(select, "exit") != 0) /* while not exit */
{
if (strcmp(select, "read") == 0)
{
printf("How many names?");
scanf("%d", &n);
while (n >= SIZE_OF_ARRAY)
{
printf("the number you entered is bigger than the maximum number of strings, please enter a number smaller than %d\n", SIZE_OF_ARRAY);
}
printf("Enter %d names", n);
readArray(array, n);
}
else if (strcmp(select, "display") == 0)
{
printArray(array);
}
else if (strcmp(select, "shortest") == 0)
{
position = shortestArray(array);
if (position == -1)
printf("there is no string entered !\n");
else
printf("Shortest name is %s in position %d\n", array[position-1], position );
}
else if (strcmp(select, "lowest") == 0)
{
position = smallestArray(array, n);
printf("Lowest name is %s in position %d\n",
array[position], position + 1);
}
else if (strcmp(select, "sort") == 0)
{
sortArray(array, n);
}
else
{
printf("INVALID SELECTION");
}
displayMenu();
scanf("%s", select); /* read next selection */
} /* end while */
}/* end main */
void displayMenu(void)
{
puts("Menu selection");
puts("Enter read to read names");
puts("Enter display to display names");
puts("Enter shortest for shortest name");
puts("Enter lowest for lowest names");
puts("Enter sort to sort names");
puts("Enter exit to exit\n");
}
void readArray(char a[][SIZE_OF_STRING], int n)
{
int i;
printf("\ntype one string per line\n");
for (i=0; i<n; i++)
{
scanf("%s",a[i]);
}
strcpy(a[n] , "");
}
void printArray(char a[][SIZE_OF_STRING])
{
int i;
for (i=0; i< SIZE_OF_ARRAY; i++)
{
if (strcmp(a[i] , "") == 0) // a[i-1] is last string entered
break; // this avoid printing non initialized string causing unknown behaviour.
printf("%s\n",a[i]);
}
}
int shortestArray(char a[][SIZE_OF_STRING])
{
int i = 0;
int position = 1;
if(strcmp (a[i] , "\0") == 0)
return position = -1; // there no string entered.
while (strcmp (a[i+1] , "\0") != 0)
{
if (strlen(a[i+1]) < strlen(a[i]))
{
position = i+2 ;
i++;
}
else
{
i++;
}
}
return position;
}
int smallestArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
return 0;
}
void sortArray(char a[][SIZE_OF_STRING], int n)
{
puts("Not yet implemented\n");
}