Hello, I have a problem with an "add calculator".
Valgrind reports no memory errors, no errors from compiler but the program doesn't show any output despite the printf - "Result is zero".
All pointers, and variables are (n my opinion) correctly initialized.
getnum function gets a number, returns a pointer to char *,
add function processes two numbers as strings, returns result which is a pointer to char (char *) as well.
Trying to work it out for the past 4 hours and can't find a mistake.
Thanks in advance!
Here's the code (sorry, it's quite long):
Code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define MAX(A,B) ((A)>(B) ? (A) : (B))
char *getnum(FILE *infile, int base)
{
int len = 10;
int c;
int pos = 0;
char *num = NULL;
char *tmpnum = NULL;
num = malloc(sizeof(char)*len);
if(num == NULL) {
perror("malloc fail");
return NULL;
}
while (((c = fgetc(infile)) != EOF) && (isalnum(c))) {
num[pos++] = c;
if (isdigit(c)) {
if (c >= base + '0') {
fprintf(stderr, "Wrong base\n");
free(num);
return NULL;
}
}
else if (isalpha(c)) {
if ( c >= base + '0' + 7) {
fprintf(stderr, "Wrong base, expected 16\n");
free(num);
return NULL;
}
}
if (pos >= len) {
len *= 2;
tmpnum = realloc(num, len*sizeof(char));
if (tmpnum == NULL) {
perror("realloc fail");
free(num);
return NULL;
}
else num = tmpnum;
}
}
num[pos] = '\0';
return num;
}
char *add(char *no1, char *no2, int base)
{
int len1, len2, length, i, j, pos, adder = 0;
char *result = NULL;
char *tmp1 = NULL;
char *tmp2 = NULL;
len1 = strlen(no1);
len2 = strlen(no2);
length = MAX(len1, len2);
if (len1 == 1 && len2 == 1) {
length++;
}
result = malloc((length + 1)*sizeof(char));
if (result == NULL) {
perror("malloc fail");
free(result);
return NULL;
}
tmp1 = realloc(no1, (length + 1)*sizeof(char));
if (tmp1 == NULL) {
perror("realloc fail");
free(result);
return NULL;
} else {
no1 = tmp1;
}
tmp2 = realloc(no2, (length + 1)*sizeof(char));
if (tmp2 == NULL) {
perror("realloc fail");
free(result);
free(no1);
return NULL;
} else {
no2 = tmp2;
}
for (i = length - 1, j = len1 - 1; j >= 0; i--, j--) {
no1[i] = no1[j];
}
for (i = 0; i < (length - len1); i++) {
no1[i] = '0';
}
no1[length] = '\0';
for (i = length - 1, j = len2 - 1; j >= 0; i--, j--) {
no2[i] = no2[j];
}
for (i = 0; i < (length - len2); i++) {
no2[i] = '0';
}
no2[length] = '\0';
pos = length - 1;
while (pos >= 0) {
if (no1[pos] > '9') {
no1[pos] -=7;
}
if (no2[pos] > '9') {
no2[pos] -=7;
}
result[pos] = no1[pos] + no2[pos] + adder - '0';
adder = 0;
if (result[pos] >= (base + '0')) {
result[pos] -= base;
adder = 1;
}
if (result[pos] > '9') {
result[pos] += 7;
}
pos--;
}
result[length] = '\0';
free(no1);
free(no2);
return result;
}
int main(int argc, char **argv)
{
FILE *infile = NULL;
char *number1 = NULL;
char *number2 = NULL;
char *result = NULL;
int base, i, j = 0, length, count = 0;
if (argc != 3) {
printf("usage: ./add infile.txt base\n");
return -1;
}
infile = fopen(argv[1], "r");
if (infile == NULL) {
perror("infile open failed");
return -1;
}
base = atoi(argv[2]);
while (!feof(infile)) {
number1 = getnum(infile, base);
if (number1 == NULL) {
fclose(infile);
return -1;
}
number2 = getnum(infile, base);
if (number2 == NULL) {
fclose(infile);
free(number1);
break; /* or return ? */
}
break;
}
printf("Base is %d\n", base);
result = add(number1, number2, base);
if (result == NULL) {
free(number1);
free(number2);
fclose(infile);
return -1;
}
length = strlen(result);
for (i = 0; i <= length - 1; i++) {
if (result[i] == '0') {
count++;
}
}
if (count == length) {
printf("Result is 0\n");
free(result);
result = NULL; /* arguable */
fclose(infile);
return 0;
}
for (i = 0; i <= length - 1; i++) {
if (result[i] != '0') {
break;
}
}
for (j = i; j == (length - 1); j++) {
printf("Result is: %s\n", &result[j]);
break;
}
free(result);
result = NULL;
fclose(infile);
return 0;
}