В этом разделе домашнего задания нас просят написать функцию ctx_append (я думаю, сокращение от context add), которая должна работать следующим образом:
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 }
Следующее представляет пустой контекст:
ctx_k: { "" }
ctx_v: { }
Программа должна использовать вспомогательную функцию ctx_append_impl, которая должна работать рекурсивно.
Ниже представлена моя работа:
#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;
}
Ожидаемый результат "new s" должен быть только abc , но когда я его компилирую и запускаю, наш результат становится abca, где я понятия не имею, где появляется последняя буква "a".
Изначально я подозревал, что ошибка возникла из-за отсутствия '\0' в const char t[], поэтому я отредактировал t[] доconst char t[] = {'c', '\0'}
Но ошибка по-прежнему возникает, единственное изменение заключается в том, что теперь выводится abc".
Если вы сравните find_empty_string и find_zero_val, вы увидите, что что-то забыли.
Также неясно, какую задачу должен выполнить рекурсивный процесс в ctx_append_impl. Есть два случая, которые завершаются, и один, который просто повторяется бесконечно, не выполняя никакой полезной работы. Предположительно, намерение вашего учителя заключалось в том, чтобы ctx_append_impl проверил, является ли ctx_k[idx] «пустой строкой», и в противном случае повторится idx+1. Вы уверены, что «пустая строка» должна быть представлена двумя символами ", а не одним NUL-байтом?
Да, пустая строка должна быть представлена двумя символами ' " '. И наш инструктор только упомянул, что мы должны реализовать 'ctx_append_impl' рекурсивно, а 'ctx_append' должен вызывать 'ctx_append_impl'.
Разрешено ли вам изменять сигнатуру функции ctx_append_impl? Если вы можете добавить два флага, чтобы проверить, были ли замечены нулевое значение и пустая строка, это станет намного проще.
Нет, нам не разрешают...
Если подпись идентична ctx_append, нет смысла иметь отдельную вспомогательную функцию. Проверьте задание еще раз.
Ваш преподаватель указал main в вашем примере? Кажется, они учат «C с std::cout» вместо C++.





Итак, проблема возникла из-за того, что изначально в ctx_k[1][1] было '"', и я забыл с этим разобраться... проблема была решена после того, как я вставил следующий код 'ctx_k[empty_string_position][idx] = ' \0';' между else if (idx==size || ident[idx] == '\0'){return}
Спасибо всем вам, ребята, которые помогли мне отладить!
У вас включены предупреждения? Если нет, то вам следует выяснить, что компилятор кричит о том, что
find_empty_stringне возвращается по всем путям. Этот код также достаточно прост, и вы можете просмотреть его в отладчике и определить, где что-то идет не так.