3

私はCでrot13アルゴリズムを実装しようとしています。しかし、私はその言語にあまり精通していないため、ここでのコードにいくつかの問題があります。

基本的に、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

4 に答える 4

7

たくさんの人に感謝します、私はこのコードで問題を解決しました

#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;
}
于 2012-11-24T11:44:34.360 に答える
2

@Michael が、これchar out[alen]はコンパイラによって受け入れられないと言った方法は、非定数値で配列サイズを宣言できないためです。コードのもう 1 つの問題はfor( i = 0; i < = alen; i+=1 )、配列が 0 から始まるfor ループですlenght's。位置まで for を実行すると、配列から外れます。

コードについて:

  1. 関数の引数として文字列の先頭へのポインターを使用する必要があります。これは、C では配列を返すことができないためです (ただし、ポインターを返すことはできます)。
  2. 一部の文字を記号に変換するので、あなた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;
        }
    }
于 2012-11-22T21:50:30.593 に答える
1

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;       
  }
于 2012-11-22T21:40:52.730 に答える
1

この関数は、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; }
    }
}
于 2013-01-31T22:24:52.063 に答える