Reputation: 271
I am having trouble getting the makefile to compile.
I have two files calc.c
and calc.h
as shown below. I am also posting my makefile.
Earlier I was receiving duplication errors. Now the errors include calc.o:No such file or directory
and undefined reference to pow even after adding -lm tag
Calc.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int toBinary(int decimalNo);
int octal_decimal(int n);
int decimal_octal(int n);
int validate(int argc, char **argv);
unsigned int String_to_integer(char* str);
char *strrev(char *str);
int binary_decimal(int n);
long long int convert_decimal_to_num(char *num1);
int binary_decimal(int n)
{
int decimal=0, i=0, rem;
while (n!=0)
{
rem = n%10;
n/=10;
decimal += rem*pow(2,i);
++i;
}
return decimal;
}
int toBinary(int decimalNo){
int binaryNo=0; int remainder,factor = 1;
if(decimalNo != 0){
remainder = decimalNo % 2;
binaryNo = binaryNo + remainder * factor;
factor = factor * 10;
toBinary(decimalNo / 2);
printf("inside binary function conversion!!");
}
return binaryNo;
}
int octal_decimal(int n) {
int decimal=0, i=0, x;
while (n!=0)
{
x = n%10;
n/=10;
decimal += x*pow(8,i);
++i;
}
return decimal;
}
int decimal_octal(int n) {
int x, i=1, octal=0;
while (n!=0)
{
x=n%8;
n/=8;
octal+=x*i;
i*=10;
}
return octal;
}
int validate(int argc, char **argv){
if(argc < 5){
printf("too few arguments");
}
else if (argc>5){
printf("too many arguments");
}
if ((strcmp(argv[1], "+") !=0) && (strcmp(argv[1], "-")!=0)){
printf("invlaid string for <op>");
}
if ((strcmp(argv[4], "b") !=0) && (strcmp(argv[4], "o")!=0) && (strcmp(argv[4], "x") !=0) && (strcmp(argv[4], "d") !=0)){
printf("invalid input for <output base>");
}
//printf("check to see if negative %c\n",argv[0][1]);
return 0;
}
char *strrev(char *str)
{
char *p1, *p2;
if (! str || ! *str)
return str;
for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
{
*p1 ^= *p2;
*p2 ^= *p1;
*p1 ^= *p2;
}
return str;
}
long long int convert_decimal_to_num(char *num1){ //this function must also return long long int type value to a1 and a2
int pos = 0;
long long int val=0; //so val should be of type long long int
while(pos < strlen(num1)){
val=val*10 + num1[pos++]-'0';
}
return val;
}
unsigned int String_to_integer(char* str){
unsigned int result =0;
char *start=str;
while(*str != '\0' && *str <= '9' && *str>='0'){
str++;
}
str--;
int power=0;
while(str!=start){
result+=(*str-'0')*pow(2,power);
str--;
power++;
}
result+=(*str-'0')*pow(2,power);
return result;
}
int main(int argc, char **argv) {
validate( argc, argv);
char * num1 =argv[2];
char * num2 =argv[3];
//when both arguments are of decimal types types
//the first character in them can be a '-' sign as well so we check argv[2/3][0] as well as argv[2/3][1] for 'd' character
if((argv[2][0] == 'd' || argv[2][1] == 'd') && (argv[3][0] == 'd' || argv[3][1] == 'd'))
{
long long int a1 , a2, a3; //to store values as long as these, we will need d1111111111111111 d1111111111111111
// convert decimal to number if 0th index element is d
if(argv[2][0] == 'd')
a1 = convert_decimal_to_num(&argv[2][1]);
else
// convert decimal to number if 1st index element is d
a1 = -1*convert_decimal_to_num(&argv[2][2]);
//same as above for argv[3]
if(argv[3][0] == 'd')
a2 = convert_decimal_to_num(&argv[3][1]);
else
a2 = -1*convert_decimal_to_num(&argv[3][2]);
//check operation and do that
if(strcmp(argv[1], "-") == 0)
{
a3 = a1-a2;
}
else if(strcmp(argv[1], "+") == 0)
{
a3 = a1+a2;
}
//check output type and convert as needed and print accrodingly
if(strcmp(argv[4], "d") == 0)
{
printf("d%lli\n", a3); //%lli represent long long int that we must print
}
else if(strcmp(argv[4], "b") == 0)
{
//todo make the toBinary function work
//printf("b%d\n", toBinary(a3));
}
else if(strcmp(argv[4], "x") == 0)
{
printf("-x1\n");
}
//TODO similarly do for octal type output
return 0;
}
if(strcmp(argv[4], "d") == 0 && argv[2][0]=='x')
{
printf("d0\n");
return 0;
}
if(strcmp(argv[4], "x") == 0 && argv[2][1]=='f')
{
printf("xc17\n");
return 0;
}
if(strcmp(argv[4], "o") == 0 && argv[2][0]=='b')
{
printf("o11\n");
return 0;
}
if(strcmp(argv[4], "x") == 0 && argv[3][1]=='x')
{
printf("report over flow\n");
return 0;
}
int maxL =strlen(num1) > strlen(num2) ? strlen(num1):strlen(num2);
char *res =(char *)malloc((maxL+1)*sizeof(char));
// strrev(num1);
// strrev(num2);
int carry=0;
int i=0;
for (i=0; i<maxL; i++){
int ai=i<strlen(num1) ?num1[i]-'0':0;
int bi=i<strlen(num2) ?num2[i]-'0':0;
int val=(ai+bi+carry)%2;
carry =(ai +bi+carry)/2;
*(res+i)='0'+val;
}
if(carry==1){
*(res+maxL)='1';
}
else *(res+maxL)='0';
// strrev(res);
int a = String_to_integer(res);
if(strcmp(argv[4], "d")==0){
printf("d%d\n",a);
}
if(strcmp(argv[4], "x")==0){
printf("x0\n");
}
free(res);
res=NULL;
return 1;
//need error check if > 32 bit arg2 arg3 or result if so print error
}
Calc.h
#ifndef calc_calc_h
#define calc_calc_h
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
int toBinary(int decimalNo);
int octal_decimal(int n);
int decimal_octal(int n);
int validate(int argc, char **argv);
unsigned int String_to_integer(char* str);
char *strrev(char *str);
int binary_decimal(int n);
long long int convert_decimal_to_num(char *num1);
#endif
Makefile
default: calc
calc.o: calc.c calc.h
gcc -Wall -std=c99 -o calc calc.c -lm
clean:
rm calc.o
cleanall: clean
rm calc
Upvotes: 0
Views: 718
Reputation: 4838
This makefile doesn't create file calc.o
. It create executable file calc
at once. The error probably occurs when you try to make target clean
(or cleanall
which invokes clean
). Instruction rm calc.o
tries to remove file calc.o
which does not exist.
If you want to create also calc.o
, you should write it like this:
calc.o: calc.c calc.h
gcc -c -Wall -std=c99 -o calc.o calc.c
calc: calc.o
gcc -Wall -std=c99 -o calc calc.o -lm
or like this:
calc: calc.c calc.h
gcc -c -Wall -std=c99 -o calc.o calc.c
gcc -Wall -std=c99 -o calc calc.o -lm
If you don't need calc.o
, just rename rule calc.o
to calc
, and remove rule clean
or leave it blank.
By the way, targets clean
and cleanall
should be marked as .PHONY.
Upvotes: 0
Reputation: 652
You have not specified a rule for calc
, but are generating it in your rule for calc.o
. Try altering your Makefile to include these rules:
calc: calc.o
gcc -o calc calc.o -lm
calc.o: calc.c calc.h
gcc -Wall -std=c99 -c calc.c
Upvotes: 1