-3

这是 edx.org 中 cs50x 课程的 pset2 中的凯撒密码加密问题。

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

IE。我输入文本“ 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");        
}
4

1 回答 1

2

根本问题是 C 没有完整的、正确的或一流的“字符串”数据类型。在C 中,字符串实际上是以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我添加的变量是 string 中非 NUL 字符序列的长度msgcaesarMsg因此,当您创建长度的字符数组时len,没有空间存储 NUL 字符。

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

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

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

字符串和字符数组是 C 新手的常见混淆源,对 C 来说也有一些不那么新的人。一些额外的参考资料:


咆哮:而创建stringtypedef 的人是邪恶的/犯了一个严重的错误,误导学生认为 C 的字符串是“真实的”(或一流的)数据类型。


(*) NULNULL不同,因为NULL(空指针)被转换为指针,因此它与其他指针的大小相同,其中 asNUL是空字符(以及 achar或的大小int)。

于 2014-07-17T21:28:58.967 回答