У меня проблема с моим кодом, который должен быть
Шифр Виженера из Гарвардской программы CS50. Я встретил все
требований, кроме случаев, когда ключ - "baz", а открытый текст - "привет,
мир! ". Поскольку здесь есть запятая и пробел, мой код принимает это, и
переходит от z к a на b и т. д. Я хочу, чтобы он игнорировал пробелы и
пунктуация, чтобы символы "b" "a" "z" менялись только для символов.
Вам следует смотреть только на первую строку "else if", так как это
.
когда открытый текст длиннее ключа, и ключ будет иметь значение
чередовать.
Пожалуйста помоги! Я занимаюсь этой проблемой несколько часов и не могу понять
решение.
https://gyazo.com/3a7b3e692d210262ae15f580b10f296d
https://gyazo.com/0b25bfc010d937840f09ff4294d0dd41
https://gyazo.com/c1b85208ecae1b9ad57d48d5b5af59b5
Это мой код:
#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
int main(int argc, string argv[])
{
if (argc == 2)
{
string key = argv[1];
int key_length = strlen(key);
for (int i = 0; i < key_length; i++)
{
key[i] = toupper(key[i]);
}
for (int k = 0; k < key_length; k++)
{
if (key[k] < 'A' || key[k] > 'Z')
{
printf("Not a valid key!\n");
return 1;
}
}
for (int i = 0; i < key_length; i++)
{
key[i] = key[i] - 'A';
}
string plain = get_string("Plaintext: ");
int plain_length = strlen(plain);
if (key_length == plain_length)
{
for (int i = 0; i < key_length; i++)
{
if (islower(plain[i]))
{
for (int q = 0; q < key[i]; q++)
{
plain[i]++;
if (plain[i] > 'z')
{
plain[i] = 'a';
}
}
}
if (isupper(plain[i]))
{
for (int q = 0; q < key[i]; q++)
{
plain[i]++;
if (plain[i] > 'Z')
{
plain[i] = 'A';
}
}
}
}
printf("ciphertext: %s\n", plain);
}
else if (key_length < plain_length)
{
float truncate_not = plain_length / key_length;
int truncate = trunc(truncate_not);
int mod = strlen(plain) % key_length;
for (int i = 0; i < truncate; i++)
{
for (int k = 0; k < key_length; k++)
{
int pos = k + (i * key_length);
if (islower(plain[pos]))
{
for (int q = 0; q < key[k]; q++)
{
plain[pos]++;
if (plain[pos] > 'z')
{
plain[pos] = 'a';
}
}
printf("%c\n", plain[pos]);
}
else if (isupper(plain[pos]))
{
for (int q = 0; q < key[k]; q++)
{
plain[pos]++;
if (plain[pos] > 'Z')
{
plain[pos] = 'A';
}
}
printf("%c\n", plain[pos]);
}
else
{
printf("error\n");
}
}
}
for (int j = 0; j < mod; j++)
{
int pos = j + (truncate * key_length);
if (islower(plain[pos]))
{
for (int q = 0; q < key[j]; q++)
{
plain[pos]++;
if (plain[pos] > 'z')
{
plain[pos] = 'a';
}
}
}
else if (isupper(plain[pos]))
{
for (int q = 0; q < key[j]; q++)
{
plain[pos]++;
if (plain[pos] > 'Z')
{
plain[pos] = 'A';
}
}
}
else
{
plain[j] = plain[j];
}
}
printf("ciphertext: %s\n", plain);
}
else
{
int mod = plain_length % key_length;
for (int i = 0; i < mod; i++)
{
if (islower(plain[i]))
{
for (int q = 0; q < key[i]; q++)
{
plain[i]++;
if (plain[i] > 'z')
{
plain[i] = 'a';
}
}
}
if (isupper(plain[i]))
{
for (int q = 0; q < key[i]; q++)
{
plain[i]++;
if (plain[i] > 'Z')
{
plain[i] = 'A';
}
}
}
}
printf("ciphertext: %s\n", plain);
}
}
else
{
printf("Incorrect number of arguments!\n");
return 1;
}
}
Actual results: iekmo, wnslc!
Expected results: iekmo, vprke!
As you can see, my code shifted the "baz", when it shouldn't have in the
space and comma places.
Я бы разделил это на несколько функций с именами, описывающими, для чего они предназначены. Я бы также добавил комментарии, почему определенные части кода такие, какие они есть. И я бы никогда не стал ссылаться на изображения вне StackOverflow. Пожалуйста, разместите текст вместо этого.
Ну да. Я не занимался дизайном или облегчением чтения. Я просто хочу сначала опустить основные функции, прежде чем я начну добавлять комментарии и прочее. Может ли кто-нибудь помочь мне с моей конкретной проблемой, о которой я упоминал выше?
Повторяю @AnttiHaapala здесь. Не используйте поддельный string от CS50.. Это сбивает с толку то, как вы используете строки char *, и значительно затрудняет понимание Си.
Используйте строку CS50. Это не подделка. Это подходящая абстракция для первых задач курса. В последующих лекциях / наборах он будет заменен на "настоящие", то есть malloc, calloc и free, о боже! (@AndrewHenle)
@DinoCoderSaurus Конечно, это так. Он учит совершенно неправильному использованию. Он объединяет указатели и массивы с простыми объектами lvalue целочисленного типа. Обо всем этом позже придется забыть. Это как учить первоклассника 2 + 2 = 5, а затем во втором классе говорить: «Нет, мы тебе солгали!» Что хорошего в этом? А выделение динамической памяти с помощью malloc()и другие ортогонально запутыванию базового типа C.
Да, мы еще не узнали о char * и других вещах в этом курсе. Пожалуйста, просто используйте синтаксис, который я использовал, чтобы сказать мне, что я должен исправить, а не проблему с тем, как курс учит языку.
Спасибо за комментарии, проблемы исправил!
Добро пожаловать в Stack Overflow. Обратите внимание, что предпочтительный способ сказать здесь `` спасибо '' - проголосовать за хорошие вопросы и полезные ответы (если у вас достаточно репутации для этого) и принять наиболее полезный ответ на любой вопрос, который вы задаете (что также дает Вы немного повысите репутацию). См. Страницу О, а также Как мне здесь задавать вопросы? и Что мне делать, когда кто-то отвечает на мой вопрос?





Основная проблема в этой программе - привязать key_length к plain_length. Они дискретны и требуют отдельного рассмотрения; они «движутся» с разной скоростью и должны использовать отдельные и отличные индексы.
Сначала я предлагаю вам пересмотрите прохождение.. Вероятно, вы захотите записать (да, карандаш и бумагу) пример «baz» в том же формате, что и Zamyla с примером «panda». А потом напишите псевдокод.
Вам, вероятно, придется отказаться от большей части написанного кода; обычно этот pset может быть выполнен с помощью одного цикла, который просматривает открытый текст по индексу, а затем независимо управляет индексом ключевого слова в этом цикле.
Можно ли выполнять эти тренировочные наборы, не просматривая пошаговое руководство, правильно?
Да, это возможно.
Я искренне презираю CS50 и
<cs50.h>. Например, здесьstringможет бытьchar *, и нет никаких указаний на то, что символы, передаваемые функциямis*, должны быть беззнаковыми.