Код C работает в VS, но терпит неудачу при переходе через valgrind и отказывается компилироваться

#c #debugging #valgrind

#c #отладка #valgrind

Вопрос:

Я написал следующий код для школьного задания (основы C)

 #include "source.h"
#include <ctype.h>
#include <string.h>


char *my_toupper(char *dest, const char *src)
{   
    
    char *RET = dest;
    while (*src!= '' ){
        if (isalpha(*src)){
            char a = *src;
            a = toupper(a);
            *dest = a; 
        }
        else if (*src =='.'){
            *dest = '!';
            dest  ;
            *dest = '!';
            dest  ;
            *dest = '!';
        }
        else if (*src == '?'){
            *dest = '!';
        }
        else {
            strcpy(dest,src);
        }

        src   ;
        dest  ;
    }
    return RET;
}
 

Предполагается, что код принимает строку, а затем меняет все буквы на прописные, меняет ‘?’ на ‘!’ и при обнаружении ‘.’, меняет его на ‘!!!’. Предполагается, что это должно быть записано в dest, и предполагается, что указатель возвращается, указывая на его исходное положение.
Теперь проблема в том, что когда я запускаю код через отладчик в Visual Studio Code, все работает просто отлично (протестировано с несколькими разными строками), но когда я пытаюсь вернуть назначение, код отказывается работать, и система дает мне 0/20 баллов.
Я получаю следующие сообщения для компиляции:

 g   -c -isystem ../../../gcheck -std=c  17 -g -Wall -Wextra -Wno-missing-field-initializers -I../../../gcheck/include test_source.cpp -o test_source.o
python3 ../../../scripts/main_remover.py ../src/source.c ../src/source.c
cc -c -isystem ../../../gcheck -std=c99 -g -Wall -Wextra -Wno-missing-field-initializers ../src/source.c -o source.o
g   test_source.o source.o -L../../../gcheck/lib -lgcheck   -o test
 

и запуск:

 rm -f test test_source.o source.o  valgrind.log mockinput mockoutput report.json
g   -c -isystem ../../../gcheck -std=c  17 -g -Wall -Wextra -Wno-missing-field-initializers -I../../../gcheck/include test_source.cpp -o test_source.o
python3 ../../../scripts/main_remover.py ../src/source.c ../src/source.c
cc -c -isystem ../../../gcheck -std=c99 -g -Wall -Wextra -Wno-missing-field-initializers ../src/source.c -o source.o
g   test_source.o source.o -L../../../gcheck/lib -lgcheck   -o test
valgrind -q --track-origins=yes --leak-check=full --log-file=valgrind_out.txt ./test --json
 

Я выяснил, что это связано с тем, что ‘!’ добавляется три раза при обнаружении ‘.’, так как когда я возвращаю следующий код с ‘!’, который печатается только один раз, он работает просто отлично.

 #include "source.h"
#include <ctype.h>
#include <string.h>


char *my_toupper(char *dest, const char *src)
{   
    
    char *RET = dest;
    while (*src!= '' ){
        if (isalpha(*src)){
            char a = *src;
            a = toupper(a);
            *dest = a; 
        }
        else if (*src =='.'){
            *dest = '!';
            
        }
        else if (*src == '?'){
            *dest = '!';
        }
        else {
            strcpy(dest,src);
        }

        src   ;
        dest  ;
    }
    return RET;
}
 

Я также помещу здесь main-function, чтобы вы могли получить представление об этом:

 #include <stdio.h>
#include <string.h>
#include "source.h"

int main(void)
{
    char dest[200];

    /* The following helps detecting string errors, e.g. missing final nil */
    memset(dest, '#', 199);
    dest[199] = 0;
    printf("%s",
        my_toupper(dest, "a?b?1.2.c??d..n"));

    printf("%s",
        my_toupper(dest, "Madam, where are you going? The health care center is over there.n"));
    
    return 0;
}
 

Комментарии:

1. Пожалуйста, отформатируйте свои вопросы, они нечитаемы

2. Ваш вызов strcpy не имеет смысла. Почему вы копируете строку для каждого символа?

3. Вам нужно добавить '' в конец dest . Похоже, что ваш код работает, потому что ни один из тестовых примеров не заканчивается специальным символом ( . или ? ), следовательно, strcpy это последнее действие в цикле, и оно добавляет '' для вас. Если вы попробуете строку, которая заканчивается специальным символом, '' добавляется no, и строка заканчивается связкой '# ‘ в конце.