2015-10-14 80 views
1

我是C新手,这是一个来来去去的任务的奖金问题,但我仍然试图通过它来解谜。在C建立一个凯撒密码解码器C

其目的是接受来自用凯撒密码编码的文件的输入(在字母表中左移或右移字母),找出哪个字母具有最高频率,然后用此来猜测移位值并解码输入。

我分别设法读取频率并计算移位值,然后使用此结果解码输入。但是当我把所有的东西放回到一个文件中时,我无法做到这一点。 事实上,除了通过主打印和打印Success1之外,它甚至不会像现在这样做。

关于如何改善这个问题或者为什么它不工作的原因的任何建议都会很好。我觉得我在那里大概有90%,但是无法弄清楚最后的10%。

谢谢。

int count_freq(int count[]); 
int decode(int shift, int ch); 
int rotate_right(int ch); 
int rotate_left(int ch); 

                       // count the number of occurrences of each letter 
int count_freq(int count[]) 
{ 
    int ch; 
    int shift, maximum, size = 26, c, location = 1, i; 

    while((ch = getchar()) != EOF) 
    { 
     ch = toupper(ch);              // convert to upper case 
     if(ch >= 'A' && ch <= 'Z') 
     { 
      i = ch - 'A'; 
      count[i]++;               // increment i'th element 
     } 
    } 

    maximum = count[26];              //Sets maximum size of count 

    for(c = 1; c < size; c++) 
    { 
     if(count[c] > maximum)            //not 100% sure what is happening here but it works 
     { 
      maximum = count[c]; 
      location = c+1; 
     } 
    } 

    shift = 5-(location-1);              //Compares the value of the letter with the highest frequency to E to find the shift 
    return(shift); 
    printf("shift = %d", shift); 
    printf("Success2"); 
} 

int decode(int ch, int shift) 
{ 
    int j; 
    if(shift >= 0) 
    {                   //If shift is greater than zero 
      for(j=0; j < shift; j++)           //Start at i=0, increment by one while i is less than shift 
      {    
        ch = rotate_right(ch);         //Use the function that increases the characters 
      } 
    } 
    else 
    {                   //For shifting values less than zero  
      for(j=0; j < -shift; j++)           //Start at i=0, increment by one while i is less than negative shift (ie. if shifting value is -10 this goes up to i=10) 
      {     
        ch = rotate_left(ch);         //Use the function that decreases the characters   
      } 
    } 

    printf("Success3");  
} 

int rotate_right(int ch) 
{ 
    if(ch == 'Z') {               //If the character is Z then make it A 
     return('A'); 
    } 
    else if(ch == 'z') {              //Same for lower case 
     return('a'); 
    } 
    else if( (ch >= 'A' && ch < 'Z')           //If the Character is greater than or equal to A and less than Z, add one to the value of the character. Eg. B -> C 
      ||(ch >= 'a' && ch < 'z')) { 
     return(ch + 1); 
    } 
    else {                  //This is for the characters that are not letters. Punctuation and spaces 
     return(ch); 
    } 
    printf("Success4"); 
} 

int rotate_left(int ch)              //This is all the same but it shifts the value of the characters the other way. Eg. C -> B     
{ 
    if(ch == 'A') { 
     return('Z'); 
    } 
    else if(ch == 'a') { 
     return('z'); 
    } 
    else if( (ch > 'A' && ch <= 'Z') 
      ||(ch > 'a' && ch <= 'z')) { 
     return(ch - 1); 
    } 
    else { 
     return(ch); 
    } 
    printf("Success5"); 
} 

int main() 
{ 
    int count[26] = { 0 };              //Initialize array elements 
    int ch, shift; 
    count_freq(count);              //Count frequencies 

    while((ch = getchar()) != EOF)           //While the variable ch is not the end of the string entered 
    {  
     putchar(decode(ch, shift));           //Calls the decode function from above using ch from getchar and shift from scanf 
    } 

    printf("Success1"); 
    return 0; 
} 
+2

该代码包含很多问题。例如这些行:'return(shift); printf(“shift =%d”,shift); printf(“Success2”); '表示函数在'return'语句处退出,所以两个printf()语句永远不会被执行。编译器应该告诉你:编译时始终启用所有警告(对于gcc,至少使用:'-Wall -Wextra -pedantic'),然后修复警告。 'decode()'函数表示它返回一个'int',但是没有'返回值'。该函数中的声明。编译器应该告诉你这一点。 – user3629249

+0

发布的代码无法正确处理标点符号和类似的可打印字符 – user3629249

+0

rotate_left()和rotate_right()函数可以被减少到(说)6行和一个单一的return语句在确定字符是大写还是小写之后输入字符(尝试从'ctypes'使用'isupper()'和'islower()'。h')通常,在一个函数中有多个'return'语句是非常糟糕的编程习惯。 – user3629249

回答

2

至少,您的代码不起作用,因为decode()中没有返回语句。

如果你的编译器没有警告/错误,你应该得到一个更好的编译器。

+0

这是一个很好的观点,谢谢。我使用Dev C++,我认为这很不错。也许我需要切换到Visual Studio – Ampersand

2

第一件事,我注意到:

,当你调用count_freq()

所以,当你通过shift解码它得到的一切是在栈上垃圾值传递你从来不会使用intialize shift

+0

I.E.这一行:'count_freq(count);'应该是:'shift = count_freq(count);' – user3629249

+0

'shift'在栈上,它包含了什么值在'shift'的地址。在32位体系结构中,'shift'为0的概率是1/4gig。所以垃圾将被传递给函数:'shift'参数中的'decode()'。 – user3629249

1

您需要使用模运算%转移字符

result = 'A' + (c - 'A' + shift) % 26 

% 26确保没有字符超出范围。

如果移位是2和字符是 'A'=>结果为 'C'

如果移位是2和字符 'Z'=>结果为 'B'

为了解码该消息,将shift更改为26 - shift

void rotate(char* msg, int shift) 
{ 
    for (int i = 0, len = strlen(msg); i < len; i++) 
    { 
     if (msg[i] >= 'a' && msg[i] <= 'z') 
      msg[i] = 'a' + (msg[i] - 'a' + shift) % 26; 
     else if (msg[i] >= 'A' && msg[i] <= 'Z') 
      msg[i] = 'A' + (msg[i] - 'A' + shift) % 26; 
    } 

    printf("%s\n", msg); 
} 

void encode(char* msg, int shift) 
{ 
    rotate(msg, shift); 
} 

void decode(char* msg, int shift) 
{ 
    rotate(msg, 26 - shift); 
} 

int main() 
{ 
    char message[100]; 
    strcpy(message, "ABCD XYZ"); 
    encode(message, 2); 
    decode(message, 2); 
    return 0; 
}