Упражнение 3.3 из книги Кернигана и Ритчи (строки) - C (СИ)
Формулировка задачи:
Всем привет.
Упражнение такое:
Напишите функцию expand(s1, s2), заменяющую сокращенную запись наподобие a-z в
строке s1 эквивалентной полной записью abc. . . xyz в s2. В s1 допускаются буквы (прописные и строчные) и
цифры. Следует уметь справляться с такими случаями, как a-b-c, a-z0-9 и -а-b. Считайте знак - в начале или в
конце s1 обычным символом минус.
Решил немного усложнить себе задачу и понапихать проверок на такие случаи: "а- ", "а--", "---...-" и "z-a". В таких случаях все должно печататься как есть. То есть подстановка полной записи должна происходить только в случае "a-z" или "a-b-...-z".
Вот, что вышло:
В текущем примере в s2 записывается только
первыми будут выполняться проверки в скобках, ибо приоритет выше. Соответственно s1[i+1] и s1[i+2] могу дать фигню, если символ последний.
#include <stdio.h> #include <stdlib.h> #include <ctype.h> void strExpand(char[],char*); int main() { char s1[]="-a-g0-9",s2[256]; system("cls"); strExpand(s1,s2); printf("After expanding:\ns1 = %s\ns2 = %s\n",s1,s2); return 0; } /*Идем посимвольно, проверяем, попадается ли х-у через s1[i+1] и s1[i+2], т.е. проверяем последующие символы за текущим*/ void strExpand(char *s1,char s2[]) { int i,j,k=0,chain,chainLen; for(i=0;i<sizeof(s1);i++) { printf("Nachalo for\n%i\n",i); /*Печатаем текущий символ, если это:*/ if(s1[i]=='-' //знак "-" (-) || isspace(s1[i]) //"пробел" ( ),(\t) || s1[i+1]=='\0' //последняя буква (а\0) || s1[i+2]=='\0' //предпоследняя буква (аа\0) || s1[i+1]!='-' //следующий символ не "-" (аа) || (s1[i+1]=='-' && s1[i+2]=='-') //следующие два символа "-" (а--) || (s1[i+1]=='-' && isspace(s1[i+2])) //следующие два символа "- " (а- ),(а-\t) || s1[i]>=s1[i+2] //в "n1-n2" n2 меньше n1 (z-a),(9-0) ) s2[k++]=s1[i]; /*В противном случае, печатаем цепочку х-у-...-z с подставлением промежуточных символов*/ else { /*Высчитываем длину цепочки a-b-...-z*/ chain=1; j=i+3; chainLen=3; while(chain) if(s1[j]=='\0' || s1[j]!='-' || s1[j+1]=='\0' || s1[j+1]=='-' || isspace(s1[j+1]) || s1[j-1]>=s1[j+1] ) chain=0; else { j+=2; chainLen+=2; } for(j=s1[i];j<=s1[i+chainLen-1];j++) s2[k++]=j; /*Пропускаем всю цепочку, вставая на следующий за ней символ; i++ в конце цикла*/ i+=chainLen-1; printf("Konec for\n%i\n",i); } } s2[k]='\0'; printf("EOFunc %i\n\n",i); }
-abcdegf
Вопрос следующий: почему не выполняется 3ий шаг цикла, хотя все условия соблюдаются (i равно 4, что есть меньше sizeof(s1), т.е. 8). Для этого в конце функции, в начале и конце цикла написал printf, чтобы видеть, когда и с какими значениями начинается и заканчивается шаг цикла. Проверял в CodeBlocks и в BorlandC. ПС Ессно только изучаю язык, многого не понимаю. Может это из-за "насильного" пропуска нескольких щагов цикла, когда i увеличиваем в теле цикла?
Хм, нашел косяк в коде уже.
В проверках:
if(s1[i]=='-' //знак "-" (-) || isspace(s1[i]) //"пробел" ( ),(\t) || s1[i+1]=='\0' //последняя буква (а\0) || s1[i+2]=='\0' //предпоследняя буква (аа\0) || s1[i+1]!='-' //следующий символ не "-" (аа) || (s1[i+1]=='-' && s1[i+2]=='-') //следующие два символа "-" (а--) || (s1[i+1]=='-' && isspace(s1[i+2])) //следующие два символа "- " (а- ),(а-\t) || s1[i]>=s1[i+2] //в "n1-n2" n2 меньше n1 (z-a),(9-0) )
Решение задачи: «Упражнение 3.3 из книги Кернигана и Ритчи (строки)»
textual
Листинг программы
for(i=0;i<sizeof(s1);i++) {
Объяснение кода листинга программы
- Переменная
i
инициализируется значением 0. - Условие цикла for проверяет, что значение переменной
i
меньше, чем размер строкиs1
(возможно, это означает, чтоs1
является массивом символов). - Если условие истинно, то выполняется тело цикла.
- Внутри цикла переменная
i
увеличивается на 1. - Цикл продолжается до тех пор, пока условие не станет ложным.
- Если условие ложно, то выполнение программы продолжается после тела цикла.
- В данном случае, в теле цикла ничего не написано, поэтому цикл выполняется без каких-либо действий.
- Если в теле цикла были бы написаны действия, они бы выполнялись при каждой итерации цикла.
- Значение переменной
i
изменяется от 0 до sizeof(s1)-1. - sizeof(s1) возвращает количество байтов в строке
s1
. - Размер строки в байтах может отличаться от количества символов в строке (если символы занимают больше одного байта).
- В данном случае, количество итераций цикла будет равно количеству байтов в строке
s1
. - Если строка
s1
является массивом символов, то каждая итерация цикла будет проходить по каждому символу в этом массиве. - В теле цикла можно было бы написать действия, которые бы выполнялись для каждого символа в строке
s1
. - В данном случае, никаких действий в теле цикла не написано, поэтому цикл выполняется без каких-либо действий.
- Если в теле цикла были бы написаны действия, они бы выполнялись при каждой итерации цикла.
- Значение переменной
i
изменяется от 0 до sizeof(s1)-1. - sizeof(s1) возвращает количество байтов в строке
s1
. - Размер строки в байтах может отличаться от количества символов в строке (если символы занимают больше одного байта).
- В данном случае, количество итераций цикла будет равно количеству байтов в строке
s1
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д