#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, и строка заканчивается связкой'#
‘ в конце.