【问题标题】:printf displays "-858993460" or "╠╠╠╠╠╠╠╠"; what are these?printf 显示“-858993460”或“╠╠╠╠╠╠╠╠”;这些是什么?
【发布时间】:2018-08-09 15:47:09
【问题描述】:

我正在尝试构建一个程序来加密密码,然后执行相反的过程(从加密的密码中告诉正确的密码)。

为此,我有:

  • 密码(char[] 类型);

  • 与密码的char 长度相同的加密密钥(vector - int[] 类型);

  • 两步(也放在int step[2] 类型的向量中)。

要求是必须使用以下两个步骤来构建加密过程:

  • 第一个(step[0]中的值)用于将从密码char的第一个位置开始的值(ASCII)添加到加密密钥的第一个位置向量步数等于第一步step[0]

例如,将char password[0] 添加到int key[0],然后将char password[1] 添加到int key[1],以此类推,步数等于step[0] 中的值。

  • 第二个(step[1])从密码char的ASCII值的对应位置减去步数等于第二步(step[1])的加密密钥值。

例如,从int key[5] 中减去char password[5],然后从int key[6] 中减去char password[6],依此类推,步数等于step[1] 中的值。

然后,该过程重复直到密码字符的长度结束。

我构建了一个如下所示的函数(添加一些步骤,然后减去一些其他步骤,并重复该过程直到密码字符结束 - 加密密钥向量具有相同的长度为密码字符)。

结果被放置在一个新的向量中(用于加密)或一个新的char(用于查找密码的反向过程)。

void criptareFinal(char password4[255], 
                   int longKey1[255], 
                   int b4, 
                   int step2[2]) {
    int encryptedPass[255];
    int a = step2[0], 
        b = step2[1], 
        n = b4, 
        i,
        ap = a, 
        bp = b; 

    for (i = 0; i < n; i++) {
        if (ap > 0) {
            encryptedPass[i] = longKey1[i] + password4[i];
            ap--;
        }
        else if (bp > 0) {
            encryptedPass[i] = longKey1[i] - password4[i];
            bp--;
        }
        else if (ap == 0 && bp == 0) {
            ap = a;
            bp = b;
        }
    }

    int i1;
    printf("\n");
    for (i1 = 0; i1 < b4; i1++)
        printf("%d ", encryptedPass[i1]);
}

然后如果我尝试printf 向量(用于加密过程)以显示向量的内容,则会出现类似于此的消息:

1090 923 916 1151 942 913 962 998 960 936 962 917 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460

为什么会显示“-858993460”?


另外,如果尝试使用以下代码在printfchar 中显示密码(将加密密码转换为可读密码),

void decriptareFinal(int encryptedPass5[255], 
                     int longKey2[255], 
                     int b5, 
                     int steps3[2]) {   
    char Password1[255];
    int a = steps3[0], 
        b = steps3[1], 
        n = b5, 
        i2, 
        ap = a, 
        bp = b;

    for (i2 = 0; i2 < n; i2++) {
        if (ap > 0) {
            Password1[i2] = encryptedPass5[i2] - longKey2[i2];
            ap--;
        }
        else if (bp > 0) {
            Password1[i2] = longKey2[i2] - encryptedPass5[i2];
            bp--;
        }
        else if (ap == 0 && bp == 0) {
            ap = a;
            bp = b;
        }
    }

    int j2;
    printf("\n");
    for (j2 = 0; j2 < b5; j2++)
        printf("%c", Password1[j2]);
}

然后出现这条消息:

côő~ypaXOF╠╠╠╠╠╠╠╠

什么是“╠”?

这个“╠╠╠╠╠╠╠╠”是不正确的显示(其余的“côő~ypaXOF”是正确的)。


还有。我尝试将[0]手动 形式添加和减去到字符串/向量的末尾,如果这样做,则不会出现-858993460 类型或╠╠╠╠╠╠╠╠ 类型的错误消息。 它工作正常,这告诉我char(密码)或int(密钥)中的值是正确的。

如果它很重要,我在 Windows 64 位 上工作,但我使用 Visual Studio。 另外,我有一个 Mac。那里我有同样的问题,但不是-858993460╠╠╠╠╠╠╠╠ 我收到其他消息(例如0 而不是-858993460)。

【问题讨论】:

  • 哇。你能把整个事情简化为问题描述的几句话和minimal reproducible example吗?
  • 这些字符来自code page 437或经典的DOS字符。你是在那种环境下运行这个编译器的吗?
  • 当您使用 Visual Studio 编写 C++ 代码时,-858993460 是一个神奇的数字。 0xcccccccc,它告诉你你正在使用一个未初始化的变量。字符串也是如此,代码页 437 中也是 0xcc。使用未初始化的变量总是一个错误,它们的不稳定值可以帮助您找到错误。
  • b6 和 b7 定义在哪里?
  • @tadman:在参数列表中,char x[255] 不传递特定长度字符数组的副本,它传递一个指针,就像char * x。 255 被忽略并且具有误导性。长度用于多维数组,但总是忽略第一个大小,例如char x[][42] 很好。

标签: c printf display


【解决方案1】:

在第一个函数中,您一次将 i0 迭代到 n。但是,并非所有通过循环体的路径都将任何内容分配给encryptedPass[i] - 这是最后一个else ifif 条件都不匹配的情况。对于第二个函数也是如此,但对于 Password1[i]

但是,在每个函数的末尾,您都会无条件地打印这些数组中的所有值,这意味着它们是未初始化的值。 (并且您迭代到未知值 b6b7,而您可能应该迭代到您在第一个循环中使用的相同 n。)

要解决这个问题,要么确保每次迭代都向索引写入内容,要么具有单独的写入位置索引或指针,并且仅在写入内容时将其推进。

【讨论】:

  • 我想到的。算完这两个步骤之和的长度,感觉有些不对劲。谢谢,我会尽量利用你的观察。
【解决方案2】:

我对您的代码做了很多更改。这是列表:

  • 为标准库添加了更多 #include 标签(我猜你已经有了一些但没有发布)
  • 将函数参数更改为 char* 而不是 char[],在函数参数中使用 char 数组是不习惯的,我什至不确定它们在您的代码中是如何工作的。
  • 摆脱了不必要的/额外的变量:apbp 和其他一些变量。由于 C 是按值传递,您不需要为 steps 变量提供临时变量。
  • 固定变量命名。您的许多变量名称不直观/奇怪,我觉得我必须将名称更改为更准确的名称。
  • 使用malloc(动态内存分配)而不是在堆栈上放置char 数组。这更灵活,减少了这些陷阱的机会,但确实为段错误打开了更多的可能性。
  • 修复了您的加密/解密算法,因为如果它刚刚完成两个步骤 (ap == 0 &amp;&amp; bp == 0),它将使 char 保持不变。
  • 修复了一些语法错误。
  • 添加了一些调试fprintf 语句,这样您就可以看到发生了什么。

至于你奇怪的 ╠ 字符,我不明白为什么你的代码会打印,除了你可能有一些内存错误或者你的环境在 Unicode 和 ASCII 之间切换或其他东西。坦率地说,我不想弄清楚,因为你的代码有点乱,而且我不认为你发布了所有代码,因为我第一次运行它时出现编译错误。

我还在malloc'd 字符串的末尾添加了一些空终止字符('\0'),以便在调试时正确打印字符串。


总之,够了。这是代码:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

char *criptareFinal(char *plaintext, int *key, int len, int *steps) {
    char *ciphertext = malloc(len + 1);
    int a = steps[0], b = steps[1], n = len;

    for (int i = 0; i < n; i++) {
        if (a == 0 && b == 0) {
            a = steps[0];
            b = steps[1];
        }

        if (a > 0) {
            ciphertext[i] = key[i] + plaintext[i];
            a--;
        }
        else if (b > 0) {
            ciphertext[i] = key[i] - plaintext[i];
            b--;
        }
    }

    ciphertext[len] = '\0';

    fprintf(stderr, "\n");
    fprintf(stderr, "ENCRYPTION: ");
    for (int i = 0; i < n; i++)
        fprintf(stderr, "%d ", ciphertext[i]);

    return ciphertext;
}

char *decriptareFinal(char *ciphertext, int *key, int len, int *steps) {   
    char *plaintext = malloc(len + 1);
    int a = steps[0], b = steps[1], n = len;

    for (int i = 0; i < n; i++) {
        if (a == 0 && b == 0) {
            a = steps[0];
            b = steps[1];
        }

        if (a > 0) {
            plaintext[i] = ciphertext[i] - key[i];
            a--;
        }
        else if (b > 0) {
            plaintext[i] = key[i] - ciphertext[i];
            b--;
        }
    }

    plaintext[len] = '\0';

    fprintf(stderr, "\n");
    fprintf(stderr, "DECRYPTION: ");
    for (int i = 0; i < n; i++)
        fprintf(stderr, "%d ", plaintext[i]);

    return plaintext;
}

int main() {
    char *toEncrypt = "Hello World!";
    int steps[] = {2, 3};
    int key[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17};

    int len = strlen(toEncrypt);

    fprintf(stderr, "INITIAL: ");
    for (int i = 0; i < len; i++)
        fprintf(stderr, "%d ", toEncrypt[i]);

    fprintf(stderr, "\n");
    char *encrypted = criptareFinal(toEncrypt, key, len, steps);
    fprintf(stderr, "\n");
    fprintf(stderr, "ENCRYPTED: %s\n", encrypted);
    char *decrypted = decriptareFinal(encrypted, key, len, steps);
    fprintf(stderr, "\n");
    fprintf(stderr, "DECRYPTED: %s\n", decrypted);

}

注意:此代码中没有错误处理,因此如果用户输入几乎以任何方式无效,代码将中断并可能导致段错误、无限循环等。您应该添加错误处理在您在正确制作的应用程序中使用它之前,对每个 char* 操作和数组迭代。


还有一些示例输出:
INITIAL: 72 101 108 108 111 32 87 111 114 108 100 33

ENCRYPTION: 73 103 -105 -104 -106 38 94 -103 -105 -98 111 45
ENCRYPTED: Igùÿû&^Öù₧o-

DECRYPTION: 72 101 108 108 111 32 87 111 114 108 100 33
DECRYPTED: Hello World!

如果您有任何问题,请告诉我。

【讨论】:

  • sizeof(char) 根据定义为 1,因此无需乘以它。
  • @Arkku 好的,谢谢我修复了sizeof(char) 引用。
  • 还要注意,你分配了len空间,但后来分配给plaintext[len],这需要len + 1空间(因为0是第一个索引)。
  • @agillgilla;谢谢你。我会试试的。我很熟悉(对您所做的修改有点熟悉),但作为初学者,我必须坚持上面示例中显示的功能,因为我的教育过程(在我跟随的学校)并没有走得太远来涵盖您使用的功能。我会试试的,让你知道。也感谢 cmets。
  • 这也看起来像不是所有通过循环的路径都将任何内容分配给结果数组,即,如果是这样,未初始化数据的风险仍然存在。但是,在实践中,我认为这可能永远不会发生,在这种情况下,else if (b &gt; 0) 应该只是else 而没有条件。 (编辑:好的,好吧,因为第一个条件是a == 0 &amp;&amp; b == 0,你不能让b 变成负数,否则永远不会匹配。所以要么需要a == 0b == 0 作为单独的if s,或者a == 0 || b == 0,或者其他东西坏了。)
【解决方案3】:

感谢大家的回答,尤其是 Arkku。 这有很大帮助。 我修复了它,现在它工作正常。 我在最后一个条件下添加了“i = i - 1”,在“else if (ap == 0 && bp == 0)”之后,以便在同一位置保持迭代。

这就是我所做的:

for (i2 = 0; i2 < n; i2++) {
if (ap > 0) {
    Password1[i2] = encryptedPass5[i2] - longKey2[i2];
    ap--;
}
else if (bp > 0) {
    Password1[i2] = longKey2[i2] - encryptedPass5[i2];
    bp--;
}
else if (ap == 0 && bp == 0) {
    ap = a;
    bp = b;
    i = i - 1;
}

这解决了问题。

其他功能也一样:

for (i = 0; i < n; i++) {
if (ap > 0) {
    encryptedPass[i] = longKey1[i] + password4[i];
    ap--;
}
else if (bp > 0) {
    encryptedPass[i] = longKey1[i] - password4[i];
    bp--;
}
else if (ap == 0 && bp == 0) {
    ap = a;
    bp = b;
    i = i - 1;
}

加密时不再出现“-858993460”,反向打印密码时不再出现“╠╠╠╠╠╠╠╠”。

再次感谢大家,并对原始消息的长度感到抱歉。 下次我会考虑到这一点。

光盘

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-06
    • 2012-10-26
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-09
    相关资源
    最近更新 更多