2014-07-17 179 views
-3

这是凯撒密码加密在edx.org cs50x课程pset2中的问题。C:用凯撒密码中的符号输出加密,为什么? pset2 cs50

我已经用另一种算法解决了这个问题,但这是我的第一次尝试,我仍然好奇为什么在凯撒文本的右侧出现所有这些符号。

即。我输入文字“Testing”,输出是“Fqefuz�����w����l��B��”,但没有符号的答案是正确的。

任何人都可以解释我吗?

int main(int argc, string argv[]) 
{ 
    bool keyOk = false; 
    int k = 0; 
    do 
    { 
     if(argc != 2) // Checking if the key was correctly entered. 
     { 
      printf("You should enter the key in one argument from" 
       " the prompt(i.e. './caesar <key>').\n"); 
      return 1; 
     } 
     else 
     { 
      k = atoi(argv[1]); // Converting string to int. 
      keyOk = true; // Approving key. 
     } 
    } 
    while(keyOk == false); 

    string msg = GetString(); // Reading user input. 
    char caesarMsg[strlen(msg)]; 

    for(int i=0, n = strlen(msg); i < n; i++) 
    { 

     if((msg[i] >= 'a') && (msg[i] <= 'z')) 
     // Processing lower case characters 
     { 
      caesarMsg[i] = ((((msg[i] - 97) + k) % 26) + 97); 
     } 
     else if((msg[i] >= 'A') && (msg[i] <= 'Z')) 
     // Processing upper case characters 
     { 
      caesarMsg[i] = ((((msg[i] - 65) + k) % 26) + 65); 
     } 
     else 
     { 
      caesarMsg[i] = msg[i]; 
     } 

    } 
    printf("%s", caesarMsg); 
    printf("\n");   
} 
+5

您最近编码的字符串缓冲区太小了1个字节。您还需要有终止零的空间。 (此外,你甚至不添加终止零。) – usr2564301

+0

可能重复[它是什么意思是“零终止”](http://stackoverflow.com/questions/2667648/what-does-it - 将被终止的零) – Deduplicator

+0

'char caesarMsg [strlen(msg)];' - >'char caesarMsg [strlen(msg)+1];' – BLUEPIXY

回答

2

问题的根源是C确实有一个完整的,适当的,或第一级“字符串”的数据类型。 C strings实际上是以NUL'\0')(*)字符结尾的字符数组。

string msg = GetString(); // Reading user input. 
    char caesarMsg[strlen(msg)]; 

这相当于

char* msg = GetString(); /* User or library function defined elsewhere */ 

/* calculates the length of the string s, excluding the terminating null 
    byte ('\0') */ 
    size_t len = strlen(msg); 

    char caesarMsg[len]; /* Create an character (byte) array of size `len` */ 

希望这使得它更清楚,为什么这部分不能正常工作。我已经添加的变量len是字符串msg中非NUL字符序列的长度。因此,当您创建长度为len的字符数组caesarMsg时,NUL字符无法存储。

for循环正确执行,但printf("%s", caesarMsg);将继续打印字符,直到找到NUL或崩溃。

顺便说一句,您可以轻松地将最后两个printf语句简化为单个printf语句。

printf("%s\n", caesarMsg); 

字符串和字符数组是混乱的常见来源任何新的C,还有一些不那么新C.一些其他参考资料:


咆哮:无论谁创造了string的typedef是邪恶/制作一个严重的错误,通过误导学生说,以为C'S字符串是一个“真正的”(或第一级)的数据类型。


(*)NUL是从NULL不同,因为NULL(空指针)被强制转换为指针,以便它的大小相同其它指针,其中作为NUL是一个空字符(和任一charint的大小)。

+0

迈克尔泰勒,感谢您的出色信息。 在for循环我更改此: N = strlen的(MSG) 此 N = strlen的(MSG)+ 1 和工程就像一个魅力。 谢谢你,我真的很感激这个信息。 – EduDeBacker