Ваше задание в цикле задом наперед. Ваша переменная a [] является исходной строкой, а b [] является адресатом, но ваше назначение a[j]=b[i];
, которое присваивает b [i] a [j]. Кстати, это действительно хороший пример того, почему имена переменных, таких как a и b, плохие. Если бы вы использовали имена переменных, такие как big_string и sub_string, у вас не было бы этой проблемы. Точно так же имена, такие как i и j, когда у вас есть несколько строк, сбивают с толку - big_index и sub_index или что-то подобное будет гораздо более понятным.
С точки зрения стилистики, вы бы лучше держали i и j ближе друг к другу, вместо того, чтобы объявлять и увеличивать i в строке for, а декларировать и увеличивать j совершенно по-разному:
int i, j;
for (i = s - 1, j = 0 ; i <= e - 1 ; i++, j++)
b[j] = a[i];
b[j] = '\0';
мне кажется намного чище.
Еще лучше, на мой взгляд, было бы использовать одну переменную для отслеживания количества обработанных символов и использовать ее в качестве смещения к исходной строке и индекса для подстроки:
start--; // adjust user's input to start at 0 instead of 1
end--;
int dex;
for (dex = 0 ; dex <= end - start ; dex++)
sub_string[dex] = orig_string[start + dex];
sub_string[dex] = '\0';
(я также перешел на более понятные имена переменных и перенес поправку для индексации с 1 на 0 вместо переменных, вместо того, чтобы выполнять математику внутри цикла, что просто добавляет путаницу).
И, наконец, самый простой способ сделать это - использовать встроенную функцию strncpy ():
strncpy(sub_string, &orig_string[start], end - start + 1);