1

I am trying to build a program that could add up binary numbers, of arbitrary length, separated by a whitespace. I don't want to be limited by a maximum number length, therefore I'm doing everything without built-in number types, only chars. I read the numbers from a file. I perform everything on stack. I can't loop the part where I read and add numbers. My guess is that it's because I can't find a way to distinguish new line from EOF. The program works this way: I read first number and save it into first stack, then I read second number and save in second stack. Then I add it up, save into third stack and transfer it to first stack. I read next number, save it into second stack, add up and so on. So I basically want to loop the second reading and summing. Here is the source code part:

    while( !isspace(c=(char)getc(ifp))) {
    if( c == '0' || c == '1'){
        if(!push(&a , c)){
            clearStack(&a);
            printf("alloc error");
            return 0;
        }
    }else{
        clearStack(&a);
        printf("error1");
        return 0;
    }
}
if( a.size == 0 ){
    printf("error2");
    return 0;
}

while (!feof(ifp)) {

while( !isspace(c=(char)getc(ifp))) {
    if( c == '0' || c == '1'){
        if(!push(&b , c)){
            clearStack(&a);
            clearStack(&b);
            printf("alloc error");
            return 0;
        }
    }
    else{
        //clearStack(&a);
        //clearStack(&b);
        printf("error3");
        //return 0;
    }
}
if( b.size == 0 ){
    if (a.size == 0){
    printf("error4");
    }
}


topA = a.size;
topB = b.size;

carry = 0;
while( topA > 0 || topB > 0) {
    if ( ( topA > 0 ) ){
        topA--;
        if(a.data[topA] == '1'){
            x = 1;
        }else{
            x = 0;
        }
    }else{
        x = 0;
    }
    if ( ( topB > 0 ) ){
        topB--;
        if(b.data[topB] == '1'){
            y = 1;
        }else{
            y = 0;
        }
    }else{
        y = 0;
    }
    sum = x + y + carry;
    if (sum == 2 || sum == 3){
        carry = 1;
    }else{
        carry = 0;
    }       
    if (sum == 1 || sum == 3) {
        c = '1';
    }else{
        c = '0';
    }
    if(!push(&output , c)){
        clearStack(&a);
        clearStack(&b);
        clearStack(&output);
        printf("alloc error");
        return 0;
    }
} 
if (carry == 1) {
    if(!push(&output , '1')){
        clearStack(&a);
        clearStack(&b);
        clearStack(&output);
        printf("alloc error");
        return 0;
    }
}

clearStack(&a);

for (i=0; i < output.size; i++){
push(&a , output.data[i]);
}

clearStack(&b);
clearStack(&output);

} /*end of EOF while*/

For some reason, although it reads multiple times, it reads wrong and works only for 2 numbers. The file looks like this: "1 1", but when its "1 1 1" it will just add first 2 numbers. I don't know where am I making a mistake. Below I attach the whole source code. I invoke the program in console like this: ./program file. I know that the case is poorly described but can't do it in a better manner, I will add comments if anything is needed.

    #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct stack {
char *data;
int size;
};  
int push(struct stack * s, char c){
char * newData = (char *)realloc( s->data , (s->size + 1) * sizeof(char));
if( newData ){
    s->data = newData;
    s->data[s->size]=c;
    s->size++;
    return 1;
}else{
    return 0;
}
}

/* not needed */

char pop(struct stack * s){
if(s->size > 0){
    char result = s->data[s->size-1];
    char * newData = (char *)realloc( s->data , s->size - 1);
    if( newData ){
        s->data = newData;
        s->size--;
        return result;
    }else{
        return 0;
    }

}
else{
    return 0;   
}
}


struct stack newStack(){
struct stack s;
s.data = NULL;
s.size = 0;
return s;
}

void clearStack(struct stack * s){
free(s->data);
s->data = NULL;
s->size = 0;
}

int main (int argc, char const * argv[])
{
struct stack a = newStack();
struct stack b = newStack();
int topA, topB, x , y, carry, sum,i , start;
struct stack output = newStack(); 
char c;
FILE *ifp;

if(argc!=2){printf("Usage: ./a.out input_file."); return(1);}
if(!(ifp = fopen(argv[1], "r"))){printf("Unable to open input file!"); return(2);}



while( !isspace(c=(char)getc(ifp))) {
    if( c == '0' || c == '1'){
        if(!push(&a , c)){
            clearStack(&a);
            printf("alloc error");
            return 0;
        }
    }else{
        clearStack(&a);
        printf("error1");
        return 0;
    }
}
if( a.size == 0 ){
    printf("error2");
    return 0;
}

while (!feof(ifp)) {

while( !isspace(c=(char)getc(ifp))) {
    if( c == '0' || c == '1'){
        if(!push(&b , c)){
            clearStack(&a);
            clearStack(&b);
            printf("alloc error");
            return 0;
        }
    }
    else if (c == '\0' || c == ' ' || c == '\n'){
    }
    else{
        //clearStack(&a);
        //clearStack(&b);
        printf("error3");
        //return 0;
    }
}
if( b.size == 0 ){
    if (a.size == 0){
    printf("error4");
    //return 0; 
    }
}

topA = a.size;
topB = b.size;

carry = 0;
while( topA > 0 || topB > 0) {
    if ( ( topA > 0 ) ){
        topA--;
        if(a.data[topA] == '1'){
            x = 1;
        }else{
            x = 0;
        }
    }else{
        x = 0;
    }
    if ( ( topB > 0 ) ){
        topB--;
        if(b.data[topB] == '1'){
            y = 1;
        }else{
            y = 0;
        }
    }else{
        y = 0;
    }
    sum = x + y + carry;
    if (sum == 2 || sum == 3){
        carry = 1;
    }else{
        carry = 0;
    }       
    if (sum == 1 || sum == 3) {
        c = '1';
    }else{
        c = '0';
    }
    if(!push(&output , c)){
        clearStack(&a);
        clearStack(&b);
        clearStack(&output);
        printf("alloc error");
        return 0;
    }
} 
if (carry == 1) {
    if(!push(&output , '1')){
        clearStack(&a);
        clearStack(&b);
        clearStack(&output);
        printf("alloc error");
        return 0;
    }
}

clearStack(&a);

for (i=0; i < output.size; i++){
push(&a , output.data[i]);
}

clearStack(&b);
clearStack(&output);

} /*end of EOF while*/

for (i=a.size - 1; i >= 0; i--){
    if(a.data[i] == '1' || start){
        start=1;
        printf("%c", a.data[i]);
    }
}
printf("\n");



clearStack(&a);
//clearStack(&b);
//clearStack(&output);
return 0;
}
Alex
  • 73
  • 6
  • What happens when you walk through your code in a debugger, inspecting the inputs and comparing to what you expect, and then comparing the outputs to what you expect? Your problem is too largely scoped to ask others to debug this for you. If you're not able to use a debugger to solve the problem, you should reduce your problem to the smallest amount of code necessary to reproduce it before asking for help. – mah Sep 12 '16 at 18:20
  • 2
    [while(!feof(fp)) is always wrong](http://stackoverflow.com/a/5432517/3386109) – user3386109 Sep 12 '16 at 18:20
  • As per the getc documentation it returns the constant `EOF` at the end of a file. It would return line breaks and/or newlines at line endings. So just check `c`. You don't need the `feof` either. – Jason C Sep 12 '16 at 18:21
  • 1
    Curious you did not post the declaration of `c` as it is used in `while( !isspace(c=(char)getc(ifp))) {` 1) It _should_ be `int c`. 2) `(char)` is not needed and creates subtle problems. – chux - Reinstate Monica Sep 12 '16 at 19:04
  • 1
    To distinguish new line from EOF while reading from file is easy. `int ch = getc(ifp)` --> if the value is `'\n'`, it is a newline. If it is `EOF`, end-of-file or input error occurred. – chux - Reinstate Monica Sep 12 '16 at 19:06

0 Answers0