Search code examples
c++recursion

A strange over-append by the function


In this section of homework, we are asked to write a function ctx_append (abbreviation of context append, I guess), which should operate like this:

Before:     ctx_k: { "a", "b", "" }
            ctx_v: { 42,  43 }

Operation:  ctx_append("c", 44, ctx_k, ctx_v, 20);

After:      ctx_k: { "a", "b", "c", "" }
            ctx_v: { 42,  43,  44 }

The following represents an empty context:

ctx_k: { "" }
ctx_v: { }

The program should use a helper function ctx_append_impl that has to operate in a recursive approach.

The following is my work:

#include <iostream>
#include <sstream>
#include "interpreter.h" //the only use of this header file in the following functions is 
                         //provide the definition of MAX_INDENT_LEN

#include "raise.h" //the only use of this header file is provide the definition of raise() and
                   //ctx_overflow

using namespace std;



int find_empty_string(char ctx_k[][MAX_IDENT_LEN], unsigned int idx){

    //since the ctx_k ends with "", we have to use this function to locate where shall we append the content in the char array ident[]
    //MAX_INDENT_LEN = 64

    if (ctx_k[idx][0] == '"' && ctx_k[idx][1] == '"'){ //find the empty string
        return idx;
    }
    else{
        find_empty_string(ctx_k, idx + 1);
    }
}

int find_zero_val(int ctx_v[], unsigned int idx){

    //since the ctx_v ends with 0, we have to use this function to locate where shall we append the value in the int array val[]
    //MAX_INDENT_LEN = 64

    if (ctx_v[idx] == 0){
        return idx;
    }
    else{
        return find_zero_val(ctx_v, idx + 1);
    }
}

void ctx_append_impl(const char ident[], int val, char ctx_k[][MAX_IDENT_LEN], int ctx_v[], unsigned int size, unsigned int idx){ 

    // the function for appending the content inside ident[] to ctx_k and val to ctx_v
    // size is the max number of strings allowed to contain
    // idx is the current index of the ident
    // MAX_INDENT_LEN = 64

    int empty_string_position = find_empty_string(ctx_k, 0);
    cout<<"empty_string_position: "<<empty_string_position<<endl;
    int zero_val_position = find_zero_val(ctx_v, 0);
    cout<<"zero_val_position: "<<zero_val_position<<endl;

    if (idx>size){
        raise(ctx_overflow);
    }
    else if(idx==size || ident[idx] == '\0'){
        return;
    }
    
    else {
        ctx_append_impl(ident, val, ctx_k, ctx_v, size, idx+1);
        ctx_k[empty_string_position][idx] = ident[idx];
    }
    
    ctx_k[empty_string_position+1][0] = '"'; //closing string, step 1
    ctx_k[empty_string_position+1][1] = '"'; //closing string, step 2
    ctx_v[zero_val_position] = val; //update the value
    ctx_v[zero_val_position+1] = 0; //close the ctx_v array
    
}

void ctx_append(const char ident[], int val, char ctx_k[][MAX_IDENT_LEN], int ctx_v[], unsigned int size){
    ctx_append_impl(ident, val, ctx_k, ctx_v, size, 0);
}

int main(){
    char s[100][MAX_IDENT_LEN]={{'a', 'b','\0'}, {'"','"','\0'}};
    cout<<"s: "<<s[0][1]<<s[1][1]<<s[2][2]<<endl;
    const char t[]={'c'};
    int v[100] = {1, 2, };
    int a=3;
    
    ctx_append(t, a, s, v, 100);
    cout<<"new s: "<<s[0][0]<<s[0][1]<<s[1][0]<<s[1][1]<<endl;
    cout<<"new v: "<<v[0]<<v[1]<<v[2]<<v[3]<<endl;
}

The expected output of "new s" should be abc only, but when I compile and run it, the ourput become abca, where I have no idea where the last "a" appears.

Initially I suspect that the bug was due to the absence of '\0' in const char t[], so I edited t[] toconst char t[]={'c', '\0'}

But the bug still occurs, the only change is that the output is abc" now.


Solution

  • So the problem occured because initially there are a '"' in ctx_k[1][1] and I forgot to deal with it... the problem was solved after I inserted the following code 'ctx_k[empty_string_position][idx] = '\0';' between else if(idx==size || ident[idx] == '\0'){return}

    Thanks for all you guys that helped me to debug!