Необходимо раскритиковать код и дать советы по исправлению
Помогите исправить мой недо-код, пожалуйста. Даны две строки равной длины. Объединить их в одну строку и записать на место первой так, чтобы на нечётных местах шли буквы первой строки, а на чётных - второй.
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
int output(char* s);
int st_len(char* st);
int main()
{
char* st1, * st2, * st;
int i = 0;
st1 = (char*)calloc(1, 1);
fgets(st1, 255, stdin);
output(st1);
st2 = (char*)calloc(1, 1);
fgets(st2, 255, stdin);
output(st2);
st_len(st1);
st = 0;
do
{
st += st1[i];
st += st2[i];
i++;
}
while (i<=2*st_len(st1));
st1 = st;
output(st1);
}
int output(char* s)
{
int i = 0;
printf("\n");
while (s[i] != '\0')
{
printf("%c", s[i]);
i++;
}
printf("\n");
return 0;
}
int st_len(char* st)
{
int n = 0;
for (; st[n] != '\0'; n++);
return n;
}
Ответы (2 шт):
Массиву букв нужно выделить память по больше. И обнуление не нужно вообще.
st1 = (char*)malloc(510);
st2 = (char*)malloc(255);
st = (char*)malloc(510);
Функция fgets считывает строку вместе с символом конца строки \n. Желательно его убрать, а то будет лишние переносы строк. Проверять надо его наличие потому-что заведённая строка могла быть очень большой.
fgets(st1, 255, stdin);
if(st1[strlen(st1)-1] == '\n')
st1[strlen(st1)-1] = '\00' ;
fgets(st2, 255, stdin);
if(st2[strlen(st2)-1] == '\n')
st2[strlen(st2)-1] = '\00' ;
Проверять надо условие задачи : что строки одинаковой длины. Иначе может быть ошибка доступа к памяти.
if(strlen(st1) != strlen(st2)) {
fputs("String lengths is different\n",stderr);
goto Exit ; }
Циклом заполняем буквы этих строк и команда += изменяет указатель а не строку. Так как строка это массив букв нужно работать как с массивом. Индексы массива длины Length это 0 .. Length-1. И доступ к элементу [Length] будет неправильным. Цикл i<=2*st_len(st1) нужно заменить на i<st_len(st1). Попроще можно так :
size_t sl = strlen(st1);
while ( i < sl )
{
st [i * 2] = st1[i];
st [i * 2 + 1] = st2[i];
++ i ;
}
st [i * 2] = '\00' ;
После копирования букв в конце нужно добавить нулевой символ, так как функция печати ориентируется именно на него.
После создания результата нужно строку st записать в первую строку st1 как было сказано в задаче. Ваше присвоение st=st1; это присвоение указателя, а не строки. Копировать можно циклом :
for(int j=i * 2;j>=0;--j)
st1[j] = st[j];
Или если кто-то неправильно понял задачу, то так :
size_t sl = strlen(st1);
while ( i < sl )
{
if ( i % 2 == 0 )
st [i] = st1[i];
else
st [i] = st2[i];
++ i ;
}
st [i] = '\00' ;
for(int j=i;j>=0;--j)
st1[j] = st[j];
Освобождать память нужно всегда, чтобы не забывать. Забывание приведёт к утечке памяти.
Exit :
free(st);
free(st2);
free(st1);
По-моему, вы делаете ошибку - не смо'трите на это: записать на место первой так... - т.е. если строки abcdef и ghijkl, то вместо первой должно быть ahcjel... Далее, я не вижу условия, что нельзя выводить строку как строку или что нельзя использовать ту же strlen().
Поэтому - я бы делал так:
int main()
{
#define len 300
char st1[len], st2[len];
printf("1st string: ");
fgets(st1, len, stdin);
printf("2nd string: ");
fgets(st2, len, stdin);
if (strlen(st1) != strlen(st2))
{
fprintf(stderr,"strlen(st1) != strlen(st2)\n");
return 1;
}
printf("\n\n1st string: %s",st1);
printf("2nd string: %s",st2);
for(int i = 1; i < strlen(st2); i+=2)
st1[i] = st2[i];
printf("Res string: %s",st1);
}