О Rot13-реализации
Я пытаюсь реализовать алгоритм rot13 на языке C. Но, поскольку я не очень хорошо знаком с этим языком, у меня есть некоторые проблемы с моим кодом прямо здесь.
По сути, я хочу повернуть каждую букву в args[] на 13 позиций вверх. Но этот код кажется довольно вялым:
#include <stdio.h>
char[] rotate(char c[]) {
char single;
int i;
int alen = sizeof(c)/sizeof(c[0]);
char out[alen];
for(i=0;i<=alen;i+=1) {
if(c[i]>='a' && (c[i]+13)<='z'){
out[i] = c[i]+13;
}
}
return out;
}
int main(int argc, char *argv[]) {
printf("The given args will be rotated\n");
int i;
char rotated[sizeof(argv)/sizeof(argv[0])];
rotated = rotate(argv);
/* printing rotated[] later on */
return 0;
}
Я знаю, что здесь много дыр - не могли бы вы показать мне, как это исправить?
4 ответа
Большое спасибо, ребята, я решил проблему с этим кодом
#include <stdio.h>
int rot13(int c){
if('a' <= c && c <= 'z'){
return rot13b(c,'a');
} else if ('A' <= c && c <= 'Z') {
return rot13b(c, 'A');
} else {
return c;
}
}
int rot13b(int c, int basis){
c = (((c-basis)+13)%26)+basis;
return c;
}
int main() {
printf("The given args will be rotated");
int c;
while((c = getchar()) != EOF){
c = rot13(c);
putchar(c);
}
return 0;
}
Как @Michael сказал это char out[alen]
не принимается компилятором, потому что вы не можете объявить размер массива с непостоянным значением. Другая проблема вашего кода - цикл for for( i = 0; i < = alen; i+=1 )
массивы начинаются с 0, так что если вы делаете для до lenght's
Положение вы будете вне массива.
О коде:
- Вы должны использовать указатель на начало строки в качестве аргумента функции, потому что вы не можете возвращать массивы в C (но вы можете возвращать указатели).
- Ваш
if( str[i] >= 'a' && (str[i]+13) <='z')
неверно, потому что вы будете конвертировать некоторые буквы в символы взглянуть.
________ --------------------------!
void rotate( char * str )
{
int i = 0;
/* You do this until you find a '\0' */
for( i = 0; str[ i ] != '\0' ; i++ ){
/* Use the pointer notation if you passed a pointer. */
/* If the letter is between a and m you can simply sum it. */
if( *( str + i ) >= 'a' && *( str + i ) < 'n')
*( str + i ) += 13;
/* If the letter is between the n and z you have to do the opposite.*/
else if( *( str + i ) >= 'n' && *( str + i ) <= 'z')
*( str + i ) -= 13;
}
}
Эта функция может кодировать / декодировать в / из строки rot13. Это совместимо с VIM g?
кодировщик rot13.
void rot13 (char *s) {
if (s == NULL)
return;
int i;
for (i = 0; s[i]; i++) {
if (s[i] >= 'a' && s[i] <= 'm') { s[i] += 13; continue; }
if (s[i] >= 'A' && s[i] <= 'M') { s[i] += 13; continue; }
if (s[i] >= 'n' && s[i] <= 'z') { s[i] -= 13; continue; }
if (s[i] >= 'N' && s[i] <= 'Z') { s[i] -= 13; continue; }
}
}
Размер массивов в C должен быть установлен во время компиляции, поэтому вы не можете использовать не константное выражение для размера массива.
Рассмотрим следующую реализацию:
// in place rotate
void rotate(char *str)
// str must be a zero-terminated string
{
int i =0;
// loop until str itself is not NULL and str[i] is not zero
for(i=0;str && str[i]; ++i) // ++i is a pre-increment
{
if(str[i] >= 'a' && (str[i]+13) <='z')
{
str[i] = str[i]+13; // modifying str in place
}
}
}
Тогда ваш main()
может выглядеть так:
int main(int argc, char *argv[])
{
printf("The given args will be rotated: %s\n", argv[1]);
rotate(argv[1]);
printf("Rotated: %s\n", argv[1]);
return 0;
}
Обновите более продвинутую версию преобразования, которая позаботится о случае, когда str[i] + 13 > 'z'
for(i=0;str && str[i]; ++i) // ++i is a pre-increment
{
// ignore out of range chars
if (str[i] < 'a' || str[i] > 'z') continue;
// rotate
for (off = 13; off > ('z' - str[i]); )
{
off-= (1 + 'z' - str[i]);
str[i] = 'a';
}
str[i]+=off;
}