1

Тема: Подвоєння першої літери при виводі рядка

Не розумію чому опісля заміни літер у всьому рядку при виводі подвоюється перша літера.

2 Востаннє редагувалося koala (12.08.2018 20:03:57)

Re: Подвоєння першої літери при виводі рядка

А я так сподівався, що є:).
Ще там помилка при невірному вводі цілого числа k  я можу повторно ввести вірне, але функція при цьому не спрацьовує.
Ось, тільки я дужки квадратні біля "і" прибрав, бо писало, що це не дозволено:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

char caesar_crypt(char *input, int key);

int main(int argc, char **argv)
{
    int k = atoi(argv[1]);
    char to_crypt[100];
    
    while(k < 1 || k > 25)
      {
        if (k < 1 || k > 25)
          printf("Wrong k, try again: ");
          scanf("%d", &k);
      }
    
    fgets(to_crypt, 100, stdin);
    char crypted = caesar_crypt(to_crypt, k);
    puts(&crypted);
    return 0;

}

char caesar_crypt(char *input, int key)
{
    for(int i = 0, n = strlen(input); i < n; i++)
      {
        if (isalpha(inputi) && (int) inputi <= 90 && (int) inputi >= 65 && ((int) inputi + key <= 90))
          {
            inputi = (int)inputi + key;
          }
        else if (isalpha(input[i) && (int) inputi <= 90 && (int) inputi >= 65 && ((int) inputi + key > 90))
          {
            inputi = 65 + (((int)inputi + key) - 91);
          }
        else if (isalpha(inputi) && (int) inputi >= 97 && (int) inputi <= 122 && ((int) inputi + key <= 122))
          {
            inputi = (int)inputi + key;
          }
       else if (isalpha(inputi) && (int) inputi >= 97 && (int) inputi <= 122 && ((int) inputi + key > 122))
          {
            inputi = 97 + (((int)inputi + key) - 123);
          }
      }
    return *input;

}

3 Востаннє редагувалося koala (12.08.2018 20:12:40)

Re: Подвоєння першої літери при виводі рядка

0. Не забувайте тег code
1. atoi при неправильному параметрі дає UB: http://www.cplusplus.com/reference/cstdlib/atoi/
Тобто зовсім не гарантується, що якщо рядок 10 не спрацював, то потім спрацює рядок 13 - у k буде сміття.
2. Якщо рядок 13 спрацював, то спрацює і рядок 15.
3. Якщо те, що ввели в scanf, буде неправильним, то буде встановлено ferror на stdin, і подальше читання без скидання цього прапорця буде неможливим. Значення k при цьому, знову ж таки, невизначене. http://www.cplusplus.com/reference/cstd … /?kw=scanf
Викликайте

clearerr(stdin);

а ще краще - читайте стрічку і обробляйте всередині програми, а не покладайтеся на стандартні функції, вони в C незручні, як на цей час.
4. За розміщення рядків 16 і 17 на одному рівні вбив би.

Подякували: Teg Miles, leofun012

4

Re: Подвоєння першої літери при виводі рядка

З одною помилкою розібрався, але подвоєння першої літери при виводі обробленого рядка все ще зберігається.

5

Re: Подвоєння першої літери при виводі рядка

А ви в курсі, що код, який ви надали, не компілюється?

6

Re: Подвоєння першої літери при виводі рядка

А ви про прибрані квадратні дужки не забули? Ось його нова версія:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>

char caesar_crypt(char *input, int key);

int main(int argc, char **argv)
{
    int k = atoi(argv[1]);
    char to_crypt[100];

    if ((argc > 2) || (argc == 1) || (k < 0))
    {
        printf("Error.\n");
        return 1;
    }
    else
    {
        k = k % 26;
        fgets(to_crypt, 100, stdin);
        char crypted = caesar_crypt(to_crypt, k);
        puts(&crypted);
        return 0;
    }
}

char caesar_crypt(char *input, int key)
{
    for(int i = 0, n = strlen(input); i < n; i++)
    {
        if (isalpha(input[i]) && (int)input[i] <= 90 && (int) input[i] >= 65 && ((int)input[i] + key <= 90))
        {
            input[i] = (int)input[i] + key;
        }
        else if (isalpha(input[i]) && (int)input[i] <= 90 && (int) input[i] >= 65 && ((int)input[i] + key > 90))
        {
            input[i] = 65 + (((int)input[i] + key) - 91);
        }
        else if (isalpha(input[i]) && (int)input[i] >= 97 && (int) input[i] <= 122 && ((int)input[i] + key <= 122))
        {
            input[i] = (int)input[i] + key;
        }
        else if (isalpha(input[i]) && (int)input[i] >= 97 && (int) input[i] <= 122 && ((int)input[i] + key > 122))
        {
            input[i] = 97 + (((int)input[i] + key) - 123);
        }
    }
    return *input;
}

7

Re: Подвоєння першої літери при виводі рядка

Нічого собі - "не забув"! Це ви їх по-людськи не виклали.
Приберіть всі "магічні константи".
І я щось не дуже розумію, що ви робите в рядку 23 - передаєте в puts адресу символа, щоб він вивів що завгодно, починаючи з цього символа і невідомо де це закінчується? От у вас казна-що і виводиться.

Подякували: leofun011

8

Re: Подвоєння першої літери при виводі рядка

у 23-му рядку я виводжу на екран результат роботи функції "caesar_crypt", яку я зберіг до змінної "crypted".

9

Re: Подвоєння першої літери при виводі рядка

caesar_crypt повертає char. Тобто символ. Один.
puts виводить стрічку символів, починаючи з того, вказівник на який їй передано.
Звідки там у вас стрічка?

Подякували: leofun01, Teg Miles, LoganRoss3

10

Re: Подвоєння першої літери при виводі рядка

Там вводиться стрічка для кодування шифром цезаря і виводиться відповідно теж стрічка.

11

Re: Подвоєння першої літери при виводі рядка

Де саме "там"?

Подякували: Teg Miles1

12

Re: Подвоєння першої літери при виводі рядка

Все зрозумів. Не треба було тягнути вивід у main, а просто вивести відразу у функції і return 0.
Тоді все добре виводиться без подвоєнь. Ну і ще деякі правки зробив у коді.

13

Re: Подвоєння першої літери при виводі рядка

Ви б краще реагували б на зауваження та відповідали на питання, тоді б і самі щось зрозуміли.