String calculation - c

I got an excersice to make a string calculator which only has an add function. When digits are not seperated, the digits have te make one whole number. When the input is 11 the program may not do 1 + 1 but has to make it eleven.
When I execute the following program it is printing "Sum = 111" on my screen, does anyone know why it is not printing 11 and maybe has a solution?
int main(void)
{
int sum = Add("11");
if(sum == -1)
{
printf("Can not return a sum");
}
else
{
printf("Sum = %d\n", sum);
}
}
extern int Add(char* numbers)
{
size_t string_length = strlen(numbers);
int Sum = 0;
int index = 0;
char number_string[255];
int number = 0;
if(string_length == 0)
{
Sum = 0;
return Sum;
}
else if(string_length == 1)
{
if(isdigit(numbers[0]))
{
Sum = numbers[0] - '0';
}
else
{
return -1;
}
return Sum;
}
else if(string_length >= 2)
{
for(index; index <= string_length; index++)
{
if(isdigit(numbers[index]))
{
strcat(number_string, &numbers[index]);
}
else if(!isdigit(numbers[index]))
{
Sum += atoi(number_string);
memset(number_string, 0, 255);
}
else
{
return -1;
}
}
return Sum;
}
else
{
return -1;
}
}

you function uses strcat, you can debug and see how it works:
1st iteration - append string "11" (&numbers[0] points to begin of the string) to number_string
2nd iteration - append string "1" (&numbers[1] points to 2nd symbol) to number_string
this is how you get "111"
what you need to do is to convert your string to number without concatenation, like this:
int Add(char* numbers) {
int n = 0;
for (; *numbers; numbers++)
if (isdigit(*numbers))
n = n*10 + (*numbers - '0');
return n;
}

Your strcat cats 11 and then cats 1 to number string, so you the 111. Here is a simple way to do this without any built in functions other than printf.
#include <stdio.h>
int main(int argc, char *argv[])
{
int sum = -1;
printf("%d\n", argc);
if (argc == 2) {
sum = Add(argv[1]);
}
if(sum == -1)
{
printf("Can not return a sum\n");
}
else
{
printf("Sum = %d\n", sum);
}
}
int Add(char* numbers)
{
char *ptr = numbers;
char *end = numbers;
int sum = 0;
while (*end >= '0' && *end <= '9') {
end++;
}
for( ; ptr < end; ptr++) {
sum *= 10;
/* *ptr is always positive */
sum += *ptr - '0';
}
return sum;
}

Related

addition, subtraction, and comparison of large numbers of any base between 2 and 36

I need to put some additional code for subtraction and comparison.
and i put (bool larger) for comparison.
When i run this and input 1 '<' 2 to compare, it says "Invalid operation: < ".
and also for the 1 = 1, it says "Invalid operation: = ".
but the result need to be "Result: false" and "Result: True"
I have no idea about it. I know the code is long but not so complicated. Please get me some hint if you can.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bignum_math.h"
/*
* Returns true if the given char is a digit from 0 to 9
*/
bool is_digit(char c) {
return c >= '0' && c <= '9';
}
/*
* Returns true if lower alphabetic character
*/
bool is_lower_alphabetic(char c) {
return c >= 'a' && c <= 'z';
}
/*
* Returns true if upper alphabetic character
*/
bool is_upper_alphabetic(char c) {
return c >= 'A' && c <= 'Z';
}
/*
* Convert a string to an integer
* returns 0 if it cannot be converted.
*/
int string_to_integer(char* input) {
int result = 0;
int length = strlen(input);
int num_digits = length;
int sign = 1;
int i = 0;
int factor = 1;
if (input[0] == '-') {
num_digits--;
sign = -1;
}
for (i = 0; i < num_digits; i++, length--) {
if (!is_digit(input[length-1])) {
return 0;
}
if (i > 0) factor*=10;
result += (input[length-1] - '0') * factor;
}
return sign * result;
}
/*
* Returns true if the given base is valid.
* that is: integers between 2 and 36
*/
bool valid_base(int base) {
if(!(base >= 2 && base <= 36)) {
return false;
}
return true;
}
/*
* TODO
* Returns true if the given string (char array) is a valid input,
* that is: digits 0-9, letters A-Z, a-z
* and it should not violate the given base and should not handle negative numbers
*/
bool valid_input(char* input, int base) {
/*
* check for valid base and if negative
*/
if (!valid_base(base) || input[0]=='-') {
return false;
}
else {
int len = strlen(input);
int i;
for (i =0; i< len; i++){
/*
* check if the input string is a digit/letter
*/
if (!(is_digit(input[i]) || is_lower_alphabetic(input[i]) || is_upper_alphabetic(input[i]))){
return false;
}
/*
* if the int excesses the base?
*/
else if (is_digit(input[i])){
if (input[i]-'0'>=base){ //convert char to int and compare with the base
return false;
}
}
/*
*or if the letter excesses the base?
*/
else if (is_lower_alphabetic(input[i])){
if (input[i]-'a'+10 >=base){
return false;
}
}
else if (is_upper_alphabetic(input[i])){
if (input[i] - 'A' + 10 >=base) {
return false;
}
}
}
return true;
}
}
/*
* converts from an array of characters (string) to an array of integers
*/
int* string_to_integer_array(char* str) {
int* result;
int i, str_offset = 0;
result = malloc((strlen(str) + 1) * sizeof(int));
result[strlen(str)] = -1;
for(i = str_offset; str[i] != '\0'; i++) {
if(is_digit(str[i])) {
result[i - str_offset] = str[i] - '0';
} else if (is_lower_alphabetic(str[i])) {
result[i - str_offset] = str[i] - 'a' + 10;
} else if (is_upper_alphabetic(str[i])) {
result[i - str_offset] = str[i] - 'A' + 10;
} else {
printf("I don't know how got to this point!\n");
}
}
return result;
}
/*
* finds the length of a bignum...
* simply traverses the bignum until a negative number is found.
*/
int bignum_length(int* num) {
int len = 0;
while(num[len] >= 0) { len++; }
return len;
}
/*
* TODO
* Prints out a bignum using digits and upper-case characters
* Current behavior: prints integers
* Expected behavior: prints characters
*/
void bignum_print(int* num) {
int i;
if(num == NULL) { return; }
/* Handle negative numbers as you want
* let the last digit be -2 if negative
* */
i = bignum_length(num);
if (num[i]==-2){
printf("-");
}
/* Then, print each digit */
for(i = 0; num[i] >= 0; i++) {
if (num[i]<=9){
printf("%d", num[i]);
}
else if (num[i]>9){
char digit = num[i]+'A'-10;
printf("%c", digit);
}
}
printf("\n");
}
/*
* Helper for reversing the result that we built backward.
* see add(...) below
*/
void reverse(int* num) {
int i, len = bignum_length(num);
for(i = 0; i < len/2; i++) {
int temp = num[i];
num[i] = num[len-i-1];
num[len-i-1] = temp;
}
}
/*
* used to add two numbers with the same sign
* GIVEN FOR GUIDANCE
*/
int* add(int* input1, int* input2, int base) {
int len1 = bignum_length(input1);
int len2 = bignum_length(input2);
int resultlength = ((len1 > len2)? len1 : len2) + 2;
int* result = (int*) malloc (sizeof(int) * resultlength);
int r = 0;
int carry = 0;
int sign = input1[len1];
len1--;
len2--;
while(len1 >= 0 || len2 >= 0) {
int num1 = (len1 >= 0)? input1[len1] : 0;
int num2 = (len2 >= 0)? input2[len2] : 0;
result[r] = (num1 + num2 + carry) % base;
carry = (num1 + num2 + carry) / base;
len1--;
len2--;
r++;
}
if(carry > 0) { result[r] = carry; r++; }
result[r] = sign;
reverse(result);
return result;
}
/*
* helper function for subtract
* determine which number is larger of two positive numbers
*/
bool larger(int* input1, int* input2){
int len1 = bignum_length(input1);
int len2 = bignum_length(input2);
if (len1<=len2){
if (len1<len2){ //if input1 has less digit than input2
return false;
}
int i;
for (i =0; i < len1; i++ ){//they have the same length
if (input1[i]<input2[i]){ //if the same digit in input1 is smaller than that in input2
return false;
}
}
}
return true; //else input1 is indeed larger than/equal input2 (longer or every digit is no less than that in input2
}
/*
* helper function for subtract
* subtract from the larger
*/
int* subtractLarger(int* input1, int* input2, int base){ //input1 is larger or equal than/to input2 and both positive
int len1 = bignum_length(input1);
int len2 = bignum_length(input2);
int resultlength = ((len1 > len2) ? len1 : len2) + 2;
int *result = (int *) malloc(sizeof(int) * resultlength);
int r = 0;
int carry = 0;
int sign = -1;
len1--;
len2--;
while(len1 >= 0 ) {
int num1 = (len1 >= 0)? input1[len1]-carry : 0;
int num2 = (len2 >= 0)? input2[len2] : 0;
if (num1>=num2){
result[r] = (num1-num2);
carry = 0;
}
else {
result[r]= num1+base-num2;
carry = 1;
}
len1--;
len2--;
r++;
}
if (result[r-1]==0){
result[r-1] = sign;
}
else {
result[r] = sign;
}
reverse(result);
return result;
}
/*
* used to subtract two numbers with the same sign
*/
int* subtract (int* input1, int* input2, int base) {
if (larger(input1,input2)){
return subtractLarger(input1, input2, base);
}
else {
int* res = subtractLarger(input2, input1, base); //exchange input1 and input2, note the result is negative
int sign = -2; //negative result
res[bignum_length(res)] = sign;
return res;
}
}
/*
* TODO
* This function is where you will write the code that performs the heavy lifting,
* actually performing the calculations on input1 and input2.
* Return your result as an array of integers.
* HINT: For better code structure, use helper functions.
*/
int* perform_math(int* input1, int* input2, char op, int base) {
/*
* this code initializes result to be large enough to hold all necessary digits.
* if you don't use all of its digits, just put a -1 at the end of the number.
* you may omit this result array and create your own.
*/
int resultlength = bignum_length(input1) + bignum_length(input2) + 2;
int* result = (int*) malloc (sizeof(int) * resultlength);
if(op == '+') {
return add(input1, input2, base);
}
else if (op == '-'){
return subtract(input1, input2, base);
}
}
/*
* Print to "stderr" and exit program
*/
void print_usage(char* name) {
fprintf(stderr, "----------------------------------------------------\n");
fprintf(stderr, "Usage: %s base input1 operation input2\n", name);
fprintf(stderr, "base must be number between 2 and 36, inclusive\n");
fprintf(stderr, "input1 and input2 are arbitrary-length integers\n");
fprintf(stderr, "Two operations are allowed '+' and '-'\n");
fprintf(stderr, "----------------------------------------------------\n");
exit(1);
}
/*
* MAIN: Run the program and tests your functions.
* sample command: ./bignum 4 12 + 13
* Result: 31
*/
int main(int argc, char** argv) {
int input_base;
int* input1;
int* input2;
int* result;
if(argc != 5) {
print_usage(argv[0]);
}
input_base = string_to_integer(argv[1]);
if(!valid_base(input_base)) {
fprintf(stderr, "Invalid base: %s\n", argv[1]);
print_usage(argv[0]);
}
if(!valid_input(argv[2], input_base)) {
fprintf(stderr, "Invalid input1: %s\n", argv[2]);
print_usage(argv[0]);
}
if(!valid_input(argv[4], input_base)) {
fprintf(stderr, "Invalid input2: %s\n", argv[4]);
print_usage(argv[0]);
}
if(argv[3][0] != '-' && argv[3][0] != '+') {
fprintf(stderr, "Invalid operation: %s\n", argv[3]);
print_usage(argv[0]);
}
input1 = string_to_integer_array(argv[2]);
input2 = string_to_integer_array(argv[4]);
result = perform_math(input1, input2, argv[3][0], input_base);
printf("Result: ");
bignum_print(result);
printf("\n");
exit(0);
}
Line 344:
void print_usage(char* name) {
fprintf(stderr, "----------------------------------------------------\n");
fprintf(stderr, "Usage: %s base input1 operation input2\n", name);
fprintf(stderr, "base must be number between 2 and 36, inclusive\n");
fprintf(stderr, "input1 and input2 are arbitrary-length integers\n");
fprintf(stderr, "Two operations are allowed '+' and '-'\n");
fprintf(stderr, "----------------------------------------------------\n");
exit(1);
}
Line 390:
if(argv[3][0] != '-' && argv[3][0] != '+') {
fprintf(stderr, "Invalid operation: %s\n", argv[3]);
print_usage(argv[0]);
}
Now guess why it says "Invalid operation:"...

Adding decimal numbers as strings in C

So I understand how to perform calculations on integers represented in strings and then printing the result in a string. But I'm lost on how to do the same thing with a decimal in the number represented in a string.
Here's how I did it with integers. This part of the code is adding together two integers:
int answer = 0;
char str1[100];
int count = 0;
int total = 0;
int k = 0;
int diff = 0;
if (ele == ele2) {
for (k = strlen(op1) - 1; k > -1; k--) {
if ((strspn(operand, "+") == strlen(operand))) {
answer = (op1[k] - '0') + (op2[k] - '0');
} else if ((strspn(operand, "-") == strlen(operand))) {
answer = (op1[k] - '0') - (op2[k] - '0');
}
total += (pow(10, count) * answer);
count++;
}
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
}
Output
// 12 + 14
Answer: 26 // Answer given as a string
Example
12.2 + 14.5 // Three strings
Answer: 16.7 // Answer as string
Current Attempt:
for (k = strlen(argv[1]) - 1; k > -1; k--) {
if (argv[1][k] == '.') {
dec = k;
} else {
answer = (argv[1][k] - '0') + (argv[3][k] - '0');
total += (pow(10, count) * answer);
count++;
}
}
// needs to be converted to a long?
// ele is the length of the operand
total = total / pow(10, ele - dec);
sprintf(str1, "%d", total);
printf("Answer: %s ", str1);
Sharing a simple algo to begin with (and assuming your adding integer funciton works fine).
A decimal number is basically two integers separated by ".".
Identify the position of "." and grab the two sides of the integer as integerPart, decimalPart
One caveat on getting the decimalPart is that the length of all the decimalParts should be same, if not, add "0"s in the suffix.
Add the integerPart, add the decimalPart and handle the carryForwards in the decimalPart.
So,
12.2 + 14.95
= (12 + 14) (20 + 95)
= 26 115
= 26+1 15
= 27.15
This is a quick and dirty implementation: no parameter check, no deep test only an idea of how you should process.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int total_digits;;
int decimal_points;
int *number;
} NUMBER, *DECIMALNUMBER;
DECIMALNUMBER initilize(char *str)
{
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
int in_decimal = 0;
char *s;
int i;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->total_digits++;
if (in_decimal)
{
result -> decimal_points++;
}
}
else if (*s == '.')
{
in_decimal = 1;
}
else
{
return NULL;
}
}
result->number = calloc(result->decimal_points, sizeof(int));
i=0;
for (s = str; *s; s++)
{
if (isdigit(*s))
{
result->number[i++] = (int)(*s - '0');
}
}
// printf("result->total_digits is %d\n",result->total_digits);
// printf("result->decimal_points is %d\n",result->decimal_points);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
// printf("result is %d\n",result->number[--i]);
return result;
}
void print_number(DECIMALNUMBER p)
{
int i;
for (i=0; i<p->total_digits; i++)
{
if (i==p->total_digits - p->decimal_points) {
printf(".");
}
printf("%d", p->number[i]);
}
printf("\n");
}
DECIMALNUMBER sum(DECIMALNUMBER a, DECIMALNUMBER b)
{
int max_decimals = a->decimal_points>b->decimal_points ? a->decimal_points : b->decimal_points;
int max_digits_count = a->total_digits>b->total_digits ? a->total_digits : b->total_digits;
DECIMALNUMBER result = calloc(1, sizeof(NUMBER));
result->total_digits = max_digits_count;
result->decimal_points = max_decimals;
result->number = calloc(max_digits_count, sizeof(int));
int i1 = a->total_digits-1;
int i2 = b->total_digits-1;
int i3 = result->total_digits-1;
int remainder = 0;
int summed;
while (i1 >= 0 || i2 >=0)
{
int aa = i1 < 0 ? 0 : a->number[i1];
int bb = i2 < 0 ? 0 : b->number[i2];
summed = aa + bb + remainder;
result->number[i3] = summed % 10;
remainder = summed / 10;
i1--;
i2--;
i3--;
}
return result;
}
int main()
{
DECIMALNUMBER a = initilize("12.2");
DECIMALNUMBER b = initilize("16.7");
print_number(a);
print_number(b);
DECIMALNUMBER c = sum (a,b);
print_number(c);
return 0;
}

Converting int to char and reversing

Task is to convert int to char . Here is my code for converting
#include <conio.h>
#include <stdio.h>
main(void)
{
int number,reserve ;
scanf_s("%d",&number);
if (number > 0 || number == 0)
{
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
else
{
number *= -1;
printf("-");
do
{
reserve = number % 10;
printf("%c", reserve + '/0');
number /= 10;
} while (number != 0);
}
_getch();
return 0;
}
The problem is this is printing the result in the reversed of what I want. So I'm searching for a way to reverse it back. However my code is printing char by char. Probably I just need to save all chars into some string but I`m not sure of how do it. Appreciate any help.
Have you tried storing them in an array and printing the array in reverse?
#include <stdio.h>
int main(void)
{
int number,reverse,i ;
scanf("%d",&number);
char string[20];
int index = 0;
if (number< 0){
number *= -1;
printf("-");
}
do
{
reverse = number % 10;
//printf("%c", reverse);
string[index++] = reverse;
number /= 10;
} while (number != 0);
for (i = index ; i >= 0 ; i--)
printf("%c", string[i]);
return 0;
}
As you assumed in your question, you need to store the characters to print them reverse.
Using an array for this task is quite simple:
// I never know how much memory I need ...
char reverse[200];
int i = 0;
reverse[i++] = next calculated character
later
while (i) {
print reverse[--i];
}
This method should suffice in converting an integer to a string without using any standard library functions.
void ReverseString(char *sBuf, int iLength)
{
char *String1 = NULL;
char *String2 = NULL;
for (String1 = sBuf, String2 = sBuf + iLength - 1; String2 > String1; ++String1, --String2)
{
*String1 ^= *String2;
*String2 ^= *String1;
*String1 ^= *String2;
}
}
int YourVeryOwn_itoa(int iINValue, char *sOUTValue)
{
unsigned short writePosition = 0;
if (iINValue < 0)
{
sOUTValue[writePosition++] = '-';
}
do
{
sOUTValue[writePosition++] = (unsigned char)48 + (iINValue % 10);
} while ((iINValue /= 10) > 0);
sOUTValue[writePosition] = '\0';
ReverseString(sOUTValue, writePosition);
return writePosition;
}
void main()
{
char buf[255];
YourVeryOwn_itoa(123456789, buf);
printf("%s", buf);
}

How do you return a string array inside a recursive function or copy it?

I have a problem at the add2_recur function. I am trying to add up a single character digit within a string. But I do not know how to return a string to my main function so I can print out the result. I try using function pointer but i only return the first value of the string.
Any suggestion on how to do this would be helpful.
//check if string is valid
int digcheck_helper(char *theno, int start, int length) {
int charToInt = *(theno+start);
if(!((charToInt >= 48) &&(charToInt <= 57)))
return 0;
if(length == 0)
return 1;
return digcheck_helper(theno,start+1,length-1);
}
int digcheck(char *str, int start, int length) {
return digcheck_helper(string,start,length);
}
/**********************
****add recursive function**/
void add2_recur(char *num1, char *num2, int start, int carryDig) {
int singleChar1 = *(num1 + start), singleChar2 = *(num2 + start);
char *str = (char*) malloc(strlen(num1) + 2);
sum = singleChar1 + singleChar - 96;
if(carryDig == 1)
sum = sum + 1;
if(start < strlen(num1)) {
if(sum >= 10) {
sum = sum - 10;
str[start] = sum + 48;
carryDig = 1;
printf("sum of single digit is: %c\n", str[start]);
}
else if( sum < 10) {
str[start] = sum + 48;
carryDig = 0;
printf("sum of single digit is: %c\n", str[start]);
}
add2_recur(num1,num2,start+1,carryDig);
}
else if ((start == strlen(num1)) && (carryDig ==1)){
str[start+1] = 48;
printf("sum of single digit is: %c\n", str[start+1]);
}
}
void add2(char *n1, char *n2) {
add2_recur(n1,n2,0,0)
}
/*******************/
int main() {
char string1[20000], string2[20000], revStr1[20000], revStr2[20000];
int digit_1, digit_2, i;
printf("Enter first number >");
fgets(string1,20000,stdin);
string1[strlen(string1)-1] = '\0';
digit_1 = digcheck(string1,0,strlen(string1)-1);
//Check if string is valid integer
if(digit_1 = 0)
printf("This number is invalid\n");
else{
printf("Enter second number >");
fgets(string2,2000,stdin);
string2[strlen(string2)-1] = '\0';
digit_2 = digcheck(string2,0,strlen(string2-1);
if(digit_2 == 0)
printf("This number is invalid\n");
else
printf("1st num is %s\n2st num is %s\n", string1, string2);
}
// reverse string
for(i=0;i<strlen(string1);i++)
revStr1[i] = string1[(strlen(string1)-1) - i];
for(i=0;i,strlen(string2);i++)
revStr2[i] = string2[(strlen(string2) -1) - i];
// compare string and pass to add2
if(strlen(revStr1) < strlen(revStr2)) {
for(i = strlen(revStr1); i < strlen(revStr2); i++)
revStr1[i] = '0';
add2(revStr1,revStr2);
}
else if(strlen(revStr2) < strlen(revStr1)) {
for(i = strlen(revStr2); i < strlen(revStr1); i++)
revStr2[i] = '0';
add2(revStr1,revStr2);
}
else
add2(revStr1,revStr2);
return 0;
}
In C something like this is typically achieved by not returning the actual string. Instead you can just work with a pointer to a buffer passed to you. Use the actual return value to report status messages instead.
To not spoil the actual task for you, let's define a simple recursive function that will return a string with all non-alphanumerical characters being stripped:
#include <stdio.h>
#include <string.h>
int strip_stuff_rec(const char *input, char *output, unsigned int offset_input, unsigned offset_output) {
// Retrieve the character and move the offset
const char c = input[offset_input++];
if (c == '\0') { // Terminator; we're done!
// Terminate the output string
output[offset_output] = '\0';
return 1; // Signal success
}
// Character is alphanumeric?
if (isalnum(c)) {
// Append the character to our result and move the offset
output[offset_output++] = c;
}
// To have an error case, let's just pretend the string must not include #!
if (c == '#') {
return 0; // Signal an error
}
// Now handle the next position
return strip_stuff_rec(input, output, offset_input, offset_output);
}
int strip_stuff(const char *input, char *output) {
// Reset the output
output[0] = '\0';
// Start the recursive calls
return strip_stuff_rec(input, output, 0, 0);
}
int main(int argc, char **argv) {
// First let's set some input string
const char *input = "Hello World! -- I've had a wonderful day!";
// And we'll need a buffer for our result
char result[256];
// Now call the function and check the return value to determine
// whether it's been successful.
if (strip_stuff(input, result) == 0) {
printf("Some error happened!\n");
}
else {
printf("The stripped string is '%s'.\n", result);
}
}
this function:
void add2(char *n1, char *n2)
{
add2_recur(n1,n2,0,0)
}
this function has a couple of problems.
1) it will not compile because the statement that calls add2-recur()
is missing a trailing ';'
2) this function is not needed as add2_recur can be called directly
3) this is expected to add two numbers together ..
How is it to return the result?
It (probably) should be more like:
void add2(char *n1, char *n2, char *sum)
{
strcpy(sum, add2_recur(n1,n2,0,0) );
}
ok, i fix the code by creating a pointer function and storing the value into the str array by using malloc. I commented out the code. But it still only return the first element of the array to the main function from the heap. How do i get it to return the whole array?
//check if string is valid
int digcheck_helper(char *theno, int start, int length) {
int charToInt = *(theno+start);
if(!((charToInt >= 48) &&(charToInt <= 57)))
return 0;
if(length == 0)
return 1;
return digcheck_helper(theno,start+1,length-1);
}
int digcheck(char *str, int start, int length) {
return digcheck_helper(string,start,length);
}
/**********************
****add recursive function**/
char *add2_recur(char *num1, char *num2, int start, int carryDig) {
int singleChar1 = *(num1 + start), singleChar2 = *(num2 + start);
char *str = (char*) malloc(strlen(num1) + 2), sum;
sum = singleChar1 + singleChar - 96;
if(carryDig == 1)
sum = sum + 1;
if(start < strlen(num1)) {
if(sum >= 10) {
sum = sum - 10;
str[start] = sum + 48; //store value in each element of an array
carryDig = 1;
printf("sum of single digit is: %c\n", str[start]);
}
else if( sum < 10) {
str[start] = sum + 48; //store value in each element of an array
carryDig = 0;
printf("sum of single digit is: %c\n", str[start]);
}
add2_recur(num1,num2,start+1,carryDig);
}
else if ((start == strlen(num1)) && (carryDig ==1)){
str[start+1] = 49; // store value in each element of an array
printf("sum of single digit is: %c\n", str[start+1]);
}
return str;
}
/*******************/
int main() {
char string1[20000], string2[20000], revStr1[20000], revStr2[20000], *addResult;
int digit_1, digit_2, i;
printf("Enter first number >");
fgets(string1,20000,stdin);
string1[strlen(string1)-1] = '\0';
digit_1 = digcheck(string1,0,strlen(string1)-1);
//Check if string is valid integer
if(digit_1 = 0)
printf("This number is invalid\n");
else{
printf("Enter second number >");
fgets(string2,2000,stdin);
string2[strlen(string2)-1] = '\0';
digit_2 = digcheck(string2,0,strlen(string2-1);
if(digit_2 == 0)
printf("This number is invalid\n");
else
printf("1st num is %s\n2st num is %s\n", string1, string2);
}
// reverse string
for(i=0;i<strlen(string1);i++)
revStr1[i] = string1[(strlen(string1)-1) - i];
for(i=0;i,strlen(string2);i++)
revStr2[i] = string2[(strlen(string2) -1) - i];
// compare string and pass to add2
if(strlen(revStr1) < strlen(revStr2)) {
for(i = strlen(revStr1); i < strlen(revStr2); i++)
revStr1[i] = '0';
add2(revStr1,revStr2);
}
else if(strlen(revStr2) < strlen(revStr1)) {
for(i = strlen(revStr2); i < strlen(revStr1); i++)
revStr2[i] = '0';
addResult = add2(revStr1,revStr2);
}
else
addResult = add2(revStr1,revStr2);
// print out
printf("sum is: %s\n", addResult);
return 0;
Since passing the whole array is not very optimal, C usually in most of the expressions convert it to pointer.
One way to pass whole array is by enclosing it in a struct. (Not a good solution though)
typedef struct
{
char s[128];
}MYSTR;

program adding numbers doesn't show any output

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 - "Base is ".
All pointers, and variables are (n my opinion) correctly initialized.
getnum function gets a number, returns a pointer to char - char *,
add function processes two numbers as strings, returns result which is a pointer to char (char *) as well.
I don't know whether the problem is memory allocation or procedures connected to processing arrays...
Here's the 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);
while (((c = fgetc(infile)) != EOF) && (isalnum(c))) {
if (isdigit(c)) {
/* irrelevant*/
}
else if (isalpha(c)) {
fprintf(stderr, "Wrong base, expected 16\n");
free(num);
return NULL;
}
if (pos >= len) {
/*realloc*/
}
}
return num;
}
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;
infile = fopen(argv[1], "r");
base = atoi(argv[2]);
while (!feof(infile)) {
number1 = getnum(infile, base);
number2 = getnum(infile, base);
break;
}
printf("Base is %d\n", base);
result = add(number1, number2, base);
length = strlen(result);
for (i = 0; i <= length - 1; i++) {
if (result[i] == '0') {
count++;
}
}
for (j = i; j == (length - 1); j++) {
printf("Result is: %s\n", &result[j]);
break;
}
free(result);
result = NULL;
fclose(infile);
return 0;
}
Trying to work it out for the past 4 hours and can't find a mistake.
Thanks in advance!
There is one severe typo near the end of main().
for (j = i; j == (length - 1); j++) {
/* ^^ SHOULD BE <= */
printf("Result is: %s\n", &result[j]);
break;
}
Looking at this code:
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;
}
Instead of counting the total number of zeroes in the output number, and then counting the number of leading zeroes again, why not combine the two?
What is the last loop about? It's not even really a loop - it will execute once if i is length - 1, or not at all if not (presumably you're hitting the latter case in your test input).
e.g.
for (count = 0; count < length; count++) {
if (result[count] != '0')
break;
}
if (count == length) {
printf("Result is 0\n");
free(result);
result = NULL; /* arguable */
fclose(infile);
return 0;
}
printf("Result is: %s\n", &result[count]);

Resources