Преобразуйте строку в верхний регистр с циклом «для»

#c #for-loop #c-strings #uppercase #lowercase

Вопрос:

Я работаю над кодом на C, который на основе 26-символьного ключа, введенного пользователем в командной строке (например: BCDEFGHIJKLMNOPQRSTUVWXYZA), шифрует исходное сообщение (открытый текст) в зашифрованное сообщение (зашифрованный текст), заменяя каждую букву источника буквой, содержащейся в ключе в позиции i, где i-позиция буквы исходного сообщения в классическом алфавите. Следует сохранить прописные и строчные буквы.

Ожидаемый результат следующий: открытый текст: «Привет» зашифрованный текст: «Ifmmp»

Для этого мне нужна «верхняя клавиша», строка, состоящая из символов верхнего регистра, введенных пользователем в качестве ключа, и «нижняя клавиша», строка, состоящая из символов нижнего регистра, введенных пользователем в качестве ключа.

Пример: upkey = argv[1] = [BCDEFGHIJKLMNOPQRSTUVWXYZA] lowkey = [bcdefghijklmnopqrstuvwxyza]

Я добавляю здесь ниже фрагмент кода, который вызывает у меня проблемы. В приведенном ниже слоге я стремлюсь просто повторить upkey и заменить каждый символ i в нем соответствующим строчным символом, в соответствии с гипотезой ключ, введенный пользователем, только в верхнем регистре, как в приведенном выше примере (argv[1] = [BCDEFGHIJKLMNOPQRSTUVWXYZA]).

 string upkey = argv[1]; //key uppercase
string lowkey = upkey; //key lowercase temporary initialized as upkey

//generate lowkey
for (int i = 0, n = strlen(upkey); i < n; i  ) 
{ 
     lowkey[i] = upkey[i]   32; //convert to lowercase
}
 

Что происходит, когда я запускаю его, так это то, что манипулируются как lowkey, так и upkey.

 i=0:
lowkey = [bCDEFGHIJKLMNOPQRSTUVWXYZA] //correct
upkey = [bCDEFGHIJKLMNOPQRSTUVWXYZA] //why?!

i=1:
lowkey = [bcDEFGHIJKLMNOPQRSTUVWXYZA] //correct
upkey = [bcDEFGHIJKLMNOPQRSTUVWXYZA] //why?!
 

и так далее.

Кто-нибудь может, пожалуйста, объяснить мне, чего я не вижу?

Комментарии:

1. клавиши low и up указывают на одну и ту же область памяти. вам нужно сделать копию upkey.

2. Каков ваш typedef string ? Похоже, что это упражнение по пониманию указателей на массивы. Когда вы устанавливаете lowkey = upkey , вы указываете на одно и то же хранилище. Выясните, как объявить или выделить отдельное хранилище для двух массивов.

Ответ №1:

Причина проблемы в том, что оба указателя upkey и lowkey точки указывают на одну и ту же строку argv[1]

 string upkey = argv[1]; //key uppercase
string lowkey = upkey; //key lowercase temporary initialized as upkey
 

Последняя строка эквивалентна

 string lowkey = argv[1]; //key lowercase temporary initialized as upkey
 

Вам нужно выделить массив для строчных букв. Если ваш компилятор поддерживает массивы переменной длины, вы могли бы написать

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

//...

string upkey = argv[1]; //key uppercase
size_t n = strlen( upkey );

char lowkey[ n   1 ]; //key lowercase temporary initialized as upkey
lowkey[ n ] = '';

and then

//generate lowkey
for ( size_t i = 0; i < n; i   ) 
{ 
     lowkey[i] = tolower( ( unsigned char )upkey[i] ); //convert to lowercase
}
 

Если компилятор не поддерживает VLAs, то вам необходимо динамически выделять память, например

 string lowkey = malloc( n   1 );
lowkey[ n ] = '';
 

Комментарии:

1. Спасибо, это очень помогло. Я не знал об этой технике, я должен вернуться к учебе! 🙂