【问题标题】:"Vigenere" : String lowercasing program is appending character for some inputs“Vigenere”:字符串小写程序正在为某些输入附加字符
【发布时间】:2017-08-10 06:09:03
【问题描述】:

我发现我的小写字符串的基本代码有时会输出一个额外的字符。如果我使用一些输入运行 vigenere,它可以正常工作:

~/workspace/pset2/vigenere/ $ ./vigenere tweedDLed
tweeddled

但对于其他输入,它会在末尾插入一个额外的字符:

~/workspace/pset2/vigenere/ $ ./vigenere tweedDLedf
tweeddledfB

或者...

~/workspace/pset2/vigenere/ $ ./vigenere bkls33bf
bkls33bfW

这里发生了什么?由于未显示字符数组,因此我在调试器中找不到任何内容。这是我的代码:

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <cs50.h>

int main(int argc, string argv[]){
    if (argc!=2){
        return 1;
    }
    else{

        int n = strlen(argv[1]);
        char cipherKey[n];
        for (int i=0;i<n;i++){
            cipherKey[i]=tolower(argv[1][i]);
        }


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


    }
}

【问题讨论】:

  • printf("%s\n",cipherKey); --> printf("%.*s\n", n, cipherKey);
  • 字符串以零结束比较好。否则我真的很惊讶你只打印了一封信:)

标签: c cs50


【解决方案1】:

您需要为字符串终止字符分配空间,并且您需要终止您的字符串。否则,您的字符串未终止,printf 可能会超出字符串的边界,从而产生未定义的行为(例如,以“weired”输出的形式)。您可以按如下方式更正此问题:

    int n = strlen(argv[1]);
    char cipherKey[n+1];
    for (int i=0;i<n;i++){
        cipherKey[i]=tolower((unsigned char)argv[1][i]);
    }
    cipherKey[n]='\0';

【讨论】:

  • 非常感谢!我整天都在为此苦苦挣扎。
  • 我可以将您的答案复制并粘贴到此线程吗? reddit.com/r/cs50/comments/6so665/…
  • 看起来在 for 循环中简单地使 &lt; 成为 &lt;= 也有效,因为小写字符串中的第 n 个字符也是 \0。这对我来说看起来更干净一些。 :)
  • 是的,它也适用于&lt;=n,导致调用`tolower('\0')';不确定它是否更干净;我个人更喜欢使事情(在这种情况下是字符串终止)明确;但这显然只是个人喜好。
  • @StephanLechner 如您所愿:tolower(some_char) 可以是 未定义的行为some_char &lt; 0。使用tolower((unsigned char) some_char) 来避免这个问题。
猜你喜欢
  • 1970-01-01
  • 2016-05-01
  • 1970-01-01
  • 2012-06-26
  • 2019-12-24
  • 1970-01-01
  • 1970-01-01
  • 2011-11-30
  • 1970-01-01
相关资源
最近更新 更多