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
Related
I'm a beginner. I am suppossed to write a simple primal factorization programm and what i came up with has a weird behavior.
Inputs are suppossede to be in the range of 64 bits integer(long long).
It works just fine until i input values of certain length i.e. 13. (picture attached), in which case it just shut's down without an error, which i assume indicated that the programm sees the number as 0, because it should give an error otherwise.
Now, i think problem may be in pointers or in scanf function, so i'd much appreciate if somebody points me in the way of where my mistake is.
I programm in VS on Windows 10, using standard command prompt as terminal.
#include<stdio.h>
#include<math.h>
#include<stdbool.h>
#include<stdint.h>
int ReadInput(int64_t *n, int *ret);
void Primal_Factorization(int64_t n);
enum {INPUT_ERROR = 100, SUCCESS = 0};
int main()
{
int ret = SUCCESS;
int64_t n = 0;
while (ReadInput(&n, &ret) > 0)
{
Primal_Factorization(n);
}
if (n < 0)
{
fprintf(stderr, "Error: Chybny vstup!\n");
ret = INPUT_ERROR;
}
return ret;
}
int ReadInput(int64_t *n, int *ret){
if(scanf("%lld", n) != 1){
*n = 0;
fprintf(stderr, "Error: Chybny vstup!\n");
*ret = INPUT_ERROR;
}
return *n;
}
void Primal_Factorization(int64_t n){
int64_t n_sqrt = sqrt(n);
int count;
int64_t n_origin = n;
bool first_iteration = true;
printf("Prvociselny rozklad cisla %lld je:\n", n);
for (int i = 2; i <= n_sqrt; i++){
count = 0;
if(n % i == 0){
if(first_iteration == false) printf(" x ");
while (n % i == 0){
n = n / i;
count++;
}
if(count != 1) printf("%d^%d", i, count);
else printf("%d", i);
first_iteration = false;
} else continue;
}
if(n_origin == n) printf("%lld\n", n);
else if(n != 1) printf(" x %lld\n", n);
else printf("\n");
}
In this function:
int ReadInput(int64_t *n, int *ret){
if(scanf("%lld", n) != 1){
*n = 0;
fprintf(stderr, "Error: Chybny vstup!\n");
*ret = INPUT_ERROR;
}
return *n;
}
The 64-bit integer is returned as an int which is then used in the main() function to check if the value is positive. The range of int is system-dependent, but if the int is 32 bit (very commonly the case), then for example 10^18 will after truncation to 32-bits result in the value -1486618624, i.e. a negative value. Thus the program terminates because the returned value from ReadInput() is negative, but it does not print the error because n (the untruncated 64-bit integer) is positive.
A minimal modification would be to have ReadInput() return a int64_t instead of int:
int64_t ReadInput(int64_t *n, int *ret)
This program works fine if the user enters only 1 number on the command line. It will factor out the prime factors and output them to the console just fine.
J_10542741#cs3060:~/assn3$ ./assn3 12
12: 2, 2, 3,
My problem is when I test it on these two other cases:
A) Multiple Arguments:
J_10542741#cs3060:~/assn3$ ./assn3 10 8 6
10: 2, 5,
8: 2, 5,
6: 2, 5,
B) Using a Range of Numbers (i.e. {1..5}):
J_10542741#cs3060:~/assn3$ ./assn3 {1..5}
1:
2:
3:
4:
5:
I've looked around this site for anything regarding the return value of pthread_join() as well as searching through Google. I feel that it's a problem with this part of my code:
// FOR loop to join each thread w/ Main Thread 1x1
for(i = 0; i < argc-1; i++){
retCode = pthread_join(t_id[i], &factors);
results = factors;
if (retCode != 0){
// Print Error Message and return -1
fprintf(stderr, "Failure to join threads.");
return -1;
}
else{
printf("%s: ", argv[i+1]);
while(*results != 0){
printf("%d, ", *results);
results++;
}
}
free(factors);
printf("\n");
}
Here is the code in it's entirety:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<string.h>
// Return a pointer to the pFactors array
void *primeFactors(void* number){
int *pFactors = malloc(sizeof(int)); // Dynamic Array for prime factors
int capacity = 0;
int size = 1;
int num = atoi((char*)number);
int prime = 2;
// If num < 4, then that number is already prime
if(num < 4)
pFactors[capacity] = num;
else{
while(num > 1){
while(num % prime == 0){
if(capacity == size){
size++;
pFactors = realloc(pFactors, size*sizeof(int));
}
num /= prime;
pFactors[capacity] = prime;
capacity++;
}
prime++;
}
}
if(capacity == size){
size++;
pFactors = realloc(pFactors, size*sizeof(int));
}
pFactors[capacity] = 0;
pthread_exit((void*)pFactors);
}
// MAIN FUNCTION
int main(int argc, char* argv[]){
int i, retCode; // retCode holds the value of successful/fail operation for pthread_create/join
int j = 1;
int* results;
void* factors;
//Thread Identifier value is equal to the number of actual int(s) in argv
pthread_t t_id[argc-1];
// Check argc for too few arguments
if(argc < 2){
fprintf(stderr, "Usage: ./assn3 <integer value>...");
return -1;
}
// Loop through argv and check argv[j] value to ensure it's >= 0
while(j <= argc-1){
if(atoi(argv[j]) < 0){
fprintf(stderr, "%d must be >= 0", atoi(argv[j]));
return -1;
}
j++;
}
// Create the thread
for(i = 0; i < argc-1; i++){
retCode = pthread_create(&t_id[i], NULL, primeFactors, *(argv+1));
if (retCode != 0){
// Print Error Message and return -1
printf("Failure to start thread. Error: %d\n", retCode);
return -1;
}
}
// FOR loop to join each thread w/ Main Thread 1x1
for(i = 0; i < argc-1; i++){
retCode = pthread_join(t_id[i], &factors);
results = factors;
if (retCode != 0){
// Print Error Message and return -1
fprintf(stderr, "Failure to join threads.");
return -1;
}
else{
printf("%s: ", argv[i+1]);
while(*results != 0){
printf("%d, ", *results);
results++;
}
}
free(factors);
printf("\n");
}
return 0;
}
To reiterate, this program works fine if I only enter in 1 argument. However, when there are multiple arguments, the program outputs the prime factors of the first argument correctly but the following arguments are printed with the prime factors of the first argument. Secondly, when you input a bash script range (i.e.{1..5}) it only prints out the arguments and not their respective prime factors. If there's something that needs clarification, feel free to ask. Also if there appears to be a duplicate/similar question(s) somewhere that I haven't been able to find, please let me know. Thanks.
pthread_create(&t_id[i], NULL, primeFactors, *(argv+1))
You are passing the same argument, *(argv+1), to every thread. Try with *(argv+1+i) instead.
I want to write a power function that prints "Unable to compute o^o" when asked to do so or return the integer result. how can I accomplish this?
My current code prints the error statement as well as the result statement.
My code:
#include <stdio.h>
double power(int base,int n);
int main() {
int no1,no2;
printf("Enter two numbers:\n");
printf("If you want to compute x^y enter x y\n");
scanf("%i%i", &no1, &no2);
printf("The value of %i^%i is %f", no1, no2, power(no1,no2));
return 0;
}
double power(int base, int n) {
double result = 1;
if( n == 0 && base == 0){
printf("Unable to compute 0^0\n");
}
else if( n == 0 && base != 0) {
result = 1;
}
else if( n>0 ){
for(n ; n>0 ; n--) {
result = result*base;
}
}
else if( n<0 ){
int temp = -n;
result = power(base,temp);
result = (float)1.0/result;
}
return result;
}
EDIT: I am actually a novice. I am in the first chapter of K&R where I found a power function. I wanted to improve that thing and found this hurdle. Hence please provide resources if possible so that I understand your answers.
#BartoszMarcinkowski gives you the correct answer, as an alternative (if you can't pass an extra variable) you can return NAN and check the result with isnan().
In computing, NaN, standing for not a number, is a numeric data type
value representing an undefined or unrepresentable value, especially
in floating-point calculations.
#include <stdio.h>
#include <math.h>
double power(int base,int n);
int main(void)
{
double f;
f = power(2, 2);
if (isnan(f)) {
printf("Unable to compute power\n");
} else {
printf("%f\n", f);
}
return 0;
}
double power(int base, int n) {
double result = 1;
if( n == 0 && base == 0){
return NAN;
}
...
return result;
}
It is common for C functions to return 0 on success or error code in case of failure.
#include <stdio.h>
int power(int base,int n, double *result);
int main() {
int no1, no2;
printf("Enter two numbers:\n");
printf("If you want to compute x^y enter x y\n");
scanf("%i%i", &no1, &no2);
double result;
int error = power(no1, no2, &result);
if(error == 0)
printf("The value of %i^%i is %f\n", no1, no2, result);
return 0;
}
int power(int base, int n, double *result) {
*result = 1;
if(n == 0 && base == 0){
printf("Unable to compute 0^0\n");
return 1;
} else if(n == 0 && base != 0) {
*result = 1;
return 0;
} else if(n>0){
for(; n>0 ; n--) {
*result = *result*base;
}
return 0;
} else if(n < 0){
int temp = -n;
power(base,temp, result);
*result = (float) 1.0 / *result;
return 0;
}
return 1;
}
Note : My answer is in reference to the user's post saying that he is
a novice at learning C, so I have assumed that he might not have yet
be comfortable dealing with pointers.
You can have an error flag in your code that tells the main function that an error has occurred.
You can use a global integer, that is common to all functions of your program to inform of errors in code.
After calling the power function, you check whether the error FLAG is set, which means errors have occurred. So you print the error message instead of the result.
What value you should use for showing a error has occurred is arbitrary. In most cases, a non-zero (sometimes negative) value can indicate the specific error. For example:
FLAG = -1 might indicate invalid input
FLAG = -2 might indicate invalid operation
And so on. etc. Here I have chosen FLAG = non-zero value to mean error has occurred.
#include <stdio.h>
double power(int base,int n);
--> char FLAG = 0;
int main() {
int no1,no2;
---- your code ---
double and = power(no1,no2);
--> if (char) {
printf("error : both values cannot be negative);
char = 0;
} else {
printf("The value of %i^%i is %f", no1, no2, ans);
}
return 0;
}
double power(int base, int n) {
---- your code ---
if( n == 0 && base == 0){
printf("Unable to compute 0^0\n");
--> FLAG = -1;
return 0;
}
else if( n == 0 && base != 0) {
result = 1;
}
else ---- your code ---
}
#include <stdio.h>
void ScanArray (int* , int*);
int Pair (int* , int);
int main () {
int a [15] , n;
ScanArray (a , &n);
// printf("\nHello World !!!\n");
if(Pair(a , n) == 0)
printf("The array fulfills the requirements");
else
printf("The array does not fulfills the requirements");
return 0;
}
void ScanArray (int *a , int *n) {
int i , f = 0;
do {
printf("Enter the number of integers : ");
scanf("%d",n);
if (*n > 15)
printf("Enter number bellow 15 \n");
else
f=1;
} while(f == 0);
printf("Enter the %d integers : ",*n);
for (i = 0 ; i < *n ; i++)
scanf("%d",a+i);
}
int Pair (int *a , int n) {
if (n <= 1)
return 0;
else
if (*a-*(a+1) != 1 && *a-*(a+1) != -1)
return 1;
else
return Pair(a++ , n--);
}
don't know why it's not working.
Segmentation fault (core dump).
else
return Pair(a++ , n--);
Using postfix increment and decrement operators will result in the recursive call processing the same values. You should either use prefix operators, or even better, just add and subtract 1.
else
return Pair(a + 1 , n - 1);
I say that's better because it's misleading to think modifying the values matters; the key to recursion is that the recursive calls will have their own copies of a and n, so modifying them in a parent has no effect on the children.
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.