尝试增加字母时出现分段错误

时间:2017-07-05 18:26:19

标签: c cs50

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

int main(int argc, string argv[])
{
    if(argc > 2){ printf("too many arguments\n"); return 51; }
    if(argc < 2){ printf("too few arguments\n"); return 50; }
    if(strlen(argv[1]) > 4){ printf("Password is greater than 4 characters\n"); return 52; }

    if(argc == 2) //make sure there are enough args
    {
        string hash_guess = "A";

        while(crypt(hash_guess, "50") != argv[1]) //while answer not correct
        {
            while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
            {
                hash_guess[0] = hash_guess[0] + 1;
                printf("%s", hash_guess);
            }
        }

    }

}

我想通过一个单词逐个字母地增加,所以它会变成a然后b然后c直到z然后它会变成aa,ab,ac,ad ....然后ba bb bc bd ...然后za ... zz ... zzz。我以一个字母开头,但我收到错误&#34;分段错误&#34;

2 个答案:

答案 0 :(得分:0)

我很惊讶你得到了一个段错误。您显示的代码甚至不应该编译。

该行:

   string hash_guess = "A";

使用string作为类型。除非您在代码的某个部分中未显示typedef'd string,否则它不能用于创建变量。

尝试:

   char hash_guess[] = "A";//creates array of char, 2 bytes long:  |A|0|

即便如此,如果您需要此变量包含的字节数不超过2个字节,请使用更多空格创建它:

   char hash_guess[10] = "A"; Creates space for 10 bytes: |A|0|0|0|0|0|0|0|0|0|

请记住,C字符串定义为以NULL结尾的char数组。

编辑 Per @ MichaelDorgan的发现,cs50 typedefs Stringchar *。所以违规行现在变得相当于:

   char *hash_guess = "A";

这就是编译和运行的原因。当您明确尝试写入内存中您不拥有的位置时,可能会发生段错误,即 UB 。 (但是,通过查看您的代码并不清楚这是发生了什么,只是一个猜测)

创建和初始化指针,然后创建空间(超过两个字节)的另一种传统方法:

String hash_guess = {0};
hash_guess = calloc(10, 1);
if(hash_guess)
{
    //... (your code here)
    //hash_guess can now contain up to 9 characters and the NULL terminator.
}
free(hash_guess);   

答案 1 :(得分:0)

好的,仅仅是为了获取信息,segfault的原因是你使用编译器的只读内存作为临时存储。

        while(hash_guess[0] <= 'Z' && hash_guess[0] >= 'A')
        {
            hash_guess[0] = hash_guess[0] + 1;

编译器生成一个2进入常量存储器数组&#39; A&#39;和&#39; \ 0&#39;。你不能写入这个记忆。这是未定义的行为。 (UB)

char my_guess[5];  // You specify a max length of 4.  Make a constant soon please.
strcpy(my_guess, hash_guess);  // Real code never uses this function for safety reasons.

// Beware that later when going to multi-letter check, you will 
// need to re- NUL terminate the string...

        while(my_guess[0] <= 'Z' && my_guess[0] >= 'A')
        {
            my_guess[0] = my_guess[0] + 1;
// ...

...

是非法的。你需要一个临时字符数组来证明这是合法的。

my_guess

DoCmd.TransferSpreadsheet在堆栈中并可安全使用。