【问题标题】:C Compiler thinks char type is int type - clang compilerC 编译器认为 char 类型是 int 类型 - clang 编译器
【发布时间】:2014-08-16 07:38:52
【问题描述】:

所以我正在学习其中一门计算机科学的 edX 课程(不是为了学分,只是为了有讲座来帮助自学),而高级问题集与解密密码有关。为了更好地理解用于进行加密的函数 crypt(),我编写了以下代码来确定“salts”字符串使用的是什么(终端中的 man crypt() 命令说:(“salt是从集合 [a-zA-Z0-9./] 中选择的两个字符的字符串。此字符串用于以 4096 种不同方式之一扰乱算法。")) 请告诉我你是否明白我为什么收到此错误。

下面是我使用的代码。尝试编译时出现此错误:

test.c:37:33: error: incompatible integer to pointer conversion passing 'char' to
parameter of type 'char *'; take the address with & [-Werror,-Wint-conversion]
char *salt = strcat(whatever1,whatever2);

代码:

    #define _XOPEN_SOURCE //this is needed for the unistd and crypt stuff
    #include <stdio.h>
    #include <unistd.h> //this lets me do the crypt() fcn
    #include <cs50.h> //just lets me use string as a type among w/some input fcns and       is made by the course
    #include <string.h>
    #include <ctype.h> //this lets me use toascii()

    char *word = "caesar";
    char *password;

    char toASCII_New(int i) //attempt to turn input to HEX then corresponding ASCII character
    {
        for(int num = i; num<= 172; num++)
        {
            for(int hex_num = 0x41; hex_num <= 0x7a; hex_num++)
            {
                if(num == hex_num)
                {
                    char letter = (char) toascii(hex_num); //should convert hex to ascii here
                    return letter;
                }
            }
        }
        char backup = 'a';
        return backup;
    }


    string checker(int first, int second) //Checks the inputs to see if the can be the correct SALTS input to crypt
    {
        for (int i = first; i<=first+25; i++)
        {
            for(int j = second; j<=second+25; j++)
            {
                char whatever1 = (char) toASCII_New(i);
                char whatever2 = (char) toASCII_New(j);
                char *salt = strcat(whatever1,whatever2);
                password = crypt(word,salt);
                int compare = strcmp(password,"50zPJlUFIYY0o"); // this is what i'm really checking
                if (compare == 0)
                    return salt;

            }
        }
    return "no";
    }


    int main(void)
    {
        string AA = checker(65,65);
        string Aa = checker(65,97);
        string aA = checker(97,65);
        string aa = checker(97,97);

        printf("AA: %s\nAa: %s\naA: %s\naa: %s\n",AA,Aa,aA,aa);
    }

【问题讨论】:

  • 你想用toASCII_New 实现什么?我认为您首先不应该使用toascii。而且,你为什么要把char 转换成char(当调用toASCII_New 时)?还有更多类似的细节,但它们将有助于阅读和理解您的代码。
  • C 中的string 是什么?
  • @barakmanos 在代码中,第 4 行。
  • @Nelxost:是的,我看到了,但请注意旁边的“由课程制作”评论。我们是不是应该猜测string结构是如何在那里实现的???
  • toASCII_New() 函数表明缺乏对 char、int 和“十六进制值”的理解。整个函数体可以替换为if (('A' &lt;= i) &amp;&amp; (i &lt;= 'z')) return i; return 'a'; 嵌套循环的原因让我无法理解。

标签: c compiler-errors type-conversion cs50


【解决方案1】:

strcat 用于连接 strings 而不是 2 个单独的字符。 "whatever1" 将连接的字符串保持在一起。当您所要做的就是拥有一个 2 字节的字符串时,为什么还要使用 -dangerous-strcat 操作?只需使用类似的东西:

char salt[3];
salt[0]=toASCII_New(i); /* why the casting to char ? you already returned a char... */
salt[1]=toASCII_New(j);
salt[2]='\0'; /* to terminate the string properly */

【讨论】:

    【解决方案2】:

    以下是一些一般性建议,因为需要重构整个代码:


    函数toASCII_New应改写如下:

    char toASCII_New(int c)
    {
        if (('A' <= c && c <= 'Z') || ('a' <= c && c <= 'z'))
            return (char)toascii(c);
        return 'a';
    }
    

    函数checker应改写如下:

    int checker(int first, int second, char salt[3])
    {
        for (int i=first; i<=first+25; i++)
        {
            for (int j=second; j<=second+25; j++)
            {
                salt[0] = toASCII_New(i);
                salt[1] = toASCII_New(j);
                password = crypt(word,salt);
                if (strcmp(password,"50zPJlUFIYY0o") == 0)
                    return 1;
            }
        }
        return 0;
    }
    

    函数main应改写如下:

    int main()
    {
        char salt_AA[3] = {0};
        char salt_Aa[3] = {0};
        char salt_aA[3] = {0};
        char salt_aa[3] = {0};
        int  salt_AA_OK = checker('A','A');
        int  salt_Aa_OK = checker('A','a');
        int  salt_aA_OK = checker('a','A');
        int  salt_aa_OK = checker('a','a');
        printf("AA: %s\n",salt_AA_OK? salt_AA:"failed");
        printf("Aa: %s\n",salt_Aa_OK? salt_Aa:"failed");
        printf("aA: %s\n",salt_aA_OK? salt_aA:"failed");
        printf("aa: %s\n",salt_aa_OK? salt_aa:"failed");
        return 0;
    }
    

    【讨论】:

    • crypt() 函数是旧的 Unix API:man7.org/linux/man-pages/man3/crypt.3.html
    • @MichaelBurr:所以从crypt_r(crypt 的可重入版本)的描述来看,我认为crypy 使用static 字符串来返回密码,对吧?
    • 是的。 "返回值指向静态数据,其内容被每次调用覆盖"
    • @MichaelBurr:好的,所以我删除了我对密码动态分配的评论。感谢您指出这一点:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 2012-03-10
    • 2014-02-15
    • 1970-01-01
    • 2019-08-31
    • 2015-09-08
    相关资源
    最近更新 更多