Странное поведение массива при декодировании кода по длине прогона
((ссылка на оригинальный вопрос, если вы знаете немецкий язык: https://stepik.org/lesson/193516/step/9?unit=167933)
Задача: printf("falsche eingabe") всякий раз, когда во входных данных есть что-то ложное, если все правильно, тогда просто распечатайте декодированную версию. Также есть 2 режима (одиночный (abc) / мульти (aaa)), и когда есть изменение в режимах, вам также нужно напечатать "" (режим запуска - одиночный режим).
Пример ввода 1:
abcdefghijklmnopqrstuvwxyzabcdefghijkl
Пример вывода 1:
Falsche Eingabe
Пример ввода 2:
АБВГДЕЖ
Пример вывода 2:
АБВГДЕЖ
Пример ввода 3:
"a2b3c2d2'efg
Пример вывода 3:
aabbbccddefg
Привет. Это моя домашняя работа, и мне уже удалось проделать долгий путь, просто расшифровав ввод и продумав каждое условие, в котором исходный ввод неверен. Тогда я хорошо подумал.. Это не должно быть лучшим способом сделать это. Поэтому я решил декодировать код и снова закодировать его, и если сохраненный ввод совпадает с моей закодированной версией, просто распечатайте декодированные данные, в противном случае ошибка. Проблема в том, что всякий раз, когда я пробую входы 1- 'a2 2- топор
Декодирование не работает правильно. Я получаю результаты, как 1-аа * || aaİ || аа? || ..... (аа + случайный знак) 2- топор + случайный знак
Когда я пробую ввод с той же логикой, но большей длины, программа работает просто отлично.
Я был бы рад, если кто-то знает и покажет способ исправить декодирование. Я также не хочу решать эту проблему, просто добавив цикл for в конце, если это возможно..
Спасибо уже
#include <stdio.h>
int main()
{
char el[50];
scanf("%s", &el); // 'a2b2c3'dfh
char saved[50]; // 'a2b2c3'dfh
char decoded[50]; //aabbcccdfh
int k, h, y = -1, b = -1; //
int multi = 0; //(while decoding) 1 -> multi , 0 -> not
char encoded[50]; // 'a2b2c3'dfh
int multi2 = 0; //(while encoding)
for (k = 0; el[k] != '\0'; k++) { //saving
saved[k] = el[k]; // 'a2b2c3'dfh
}
for (k = 0; el[k] != '\0'; k++) { //decoding
if (el[k] == 39) {
continue;
}
if (50 <= el[k + 1] && el[k + 1] <= 57) { // 2->9
if (multi == 0)
multi = 1;
}
if (multi == 0) {
y++;
decoded[y] = el[k];
}
else { //multi ==1 //a2
for (h = 0; h < (int)el[k + 1] - 48; h++) {
y++;
decoded[y] = el[k];
multi = 0;
}
k++;
}
} // decoded = aabbcccdfh ( hier ist k = laenge )
if (k > 30) {
printf("falsche eingabe");
return 0;
}
for (k = 0; k < y + 1; k++) {
if (decoded[k] == decoded[k + 1]) {
if (multi2 == 0) {
multi2 = 1;
b++;
encoded[b] = 39;
}
}
if (multi2 == 0) {
b++;
encoded[b] = decoded[k];
}
else {
b++;
encoded[b] = decoded[k];
// 0 -> decoded[k], 1 -> for, 2-> '
for (h = k; decoded[h] == decoded[h + 1]; h++)
;
b++;
encoded[b] = ((h - k + 48) + 1);
k = h;
if (decoded[k + 1] != decoded[k + 2]) {
multi2 = 0;
b++;
encoded[b] = 39;
}
}
}
//wurde die erste eingabe richtig codiert ? ( also gibt es fehler oder nicht ? )
for (k = 0; saved[k] != '\0'; k++) {
if (saved[k] != encoded[k]) {
printf("falsche eingabe\n");
return 0;
}
}
printf("%s", decoded);
}
Я пытался сделать это как можно более ясным, извините, если бы это было более ясно.
2 ответа
В спецификации сказано:
начинается в одиночном модусе
когда
'
видно, он переключается между режимамив мультимодусе за буквой (Zeichen) следует цифра (Ziffer, то есть одна цифра), которая говорит о том, как часто буква (Zeichen) должна повторяться. (Таким образом, максимальный повтор 9).
Просто реализуйте это, как указано, и все готово.
Пример:
abc'd2e4'ma'r2 --> abcddeeeemarr
Я вижу 2 проблемы
1) ты звонишь scanf
неверно
scanf("%s",&el);
должно быть
scanf("%s",el);
потому что вы передаете это строку
2) вы не NUL прекращаете свои строки. Это может привести к неопределенному поведению, так как код не будет знать, где заканчивается строка, и будет радостно заполнять ваши массивы.
Добавьте завершающий символ после ваших циклов, как показано ниже. После завершения цикла k
будет указывать на последнее значение.
for (k = 0; el[k] != '\0'; k++) { //saving
saved[k] = el[k]; // 'a2b2c3'dfh
}
saved[k] = '\0';
Также еще одна проблема, которую я только что заметил, это то, что вы заполняете такие строки, как decoded
странным образом, что затрудняет NUL прекратить их.
y++
должно идти после того, как вы сохраните значение в массив, как показано ниже (и, очевидно, вы должны инициализировать его с 0
не -1
).
decoded[y] = el[k];
y++;
Это означает, что когда вы закончили заполнять decoded
ты можешь сделать decoded[y]='\0'
прекратить это как y
будет указывать на конец так же, как k
делает с saved
цикл выше.
То же самое касается encode
а также b