使用strlen和完整阵列时,阵列长度不同吗?

时间:2019-04-11 01:56:45

标签: c cs50

我正在尝试将字符串plaintext复制到C语言中的另一个字符串ciphertext中,以使它们具有相同的长度和数组字符。我似乎无法获得匹配的字符串长度或内容。任何指导将不胜感激!

我尝试将strlen初始化为与ciphertext相同的大小时使用plaintext,然后将plaintext的每个字符复制到ciphertext中并打印两个字符串及其长度。

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

bool is_number(int input);

int main(int argc, string argv[])
{
    //checking that user provides only one input argument
    if (argc != 2)
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    //check that user key input is an integer
    for (int i = 0, l = strlen(argv[1]); i < l; i++)
    {
        if(is_number(argv[1][i]) == 0)
        {
            printf("Usage: ./caesar key\n");
            return 1;
        }
    }

    //prompts user for message
    string plaintext = get_string("plaintext:  ");
    char ciphertext[strlen(plaintext)];
    printf("length p: %lu\n", strlen(plaintext));
    printf("length c: %lu\n", strlen(ciphertext));   
    for (int i = 0; plaintext[i] != '\0'; i++)
    {
        ciphertext[i] = plaintext[i];
        //printf("p[i] = %c\n", plaintext[i]);
        //printf("c[i] = %c\n", ciphertext[i]);
        //printf("i= %i\n", i);
    }
    printf("ciphertext: %s\n", ciphertext);    
}

//checks if a char is a number
bool is_number(int input)
{
    if(input < '0' || input > '9')
    {
        return 0;
    }
    else
    {
        return 1;
    }
}

运行此代码时,我的字符串长度不匹配,并且ciphertext不会打印其所有字符或随机打印多余的字符。

命令行示例:

$ make caesar
clang -fsanitize=signed-integer-overflow -fsanitize=undefined -ggdb3 -O0 -std=c11 -Wall -Werror -Wextra -Wno-sign-compare -Wno-unused-parameter -Wno-unused-variable -Wshadow    caesar.c  -lcrypt -lcs50 -lm -o caesar
$ ./caesar 1
plaintext:  hello
length p: 5
length c: 6
ciphertext: hell

1 个答案:

答案 0 :(得分:3)

未定义的行为(UB)

printf("ciphertext: %s\n", ciphertext);尝试打印ciphertext,假设它是一个字符串(字符序列,包括并以空字符结尾)不是。

strlen(ciphertext)需要一个字符串

在C语言中,调用字符串 必须,其中必须包含空字符,否则它不是 string 。许多str...()函数需要 string


代码可以尝试

printf("ciphertext: %.*s\n", (int) strlen(plaintext), ciphertext); 

打印最多为 null字符或长度或 string plaintext的字符数组。

strlen(ciphertext)是错误的,因为ciphertext缺少空字符


或者考虑

char ciphertext[strlen(plaintext) + 1];  // 1 more 
size_t i;
for (i = 0; plaintext[i] != '\0'; i++) {
    ciphertext[i] = plaintext[i];  // ciphertext is not yet a _string_.
}
ciphertext[i] = '\0'; // Now ciphertext is a _string_.

还请注意:

printf("length p: %lu\n", strlen(plaintext));不正确,因为strlen()返回size_t,不一定返回unsigned long

使用匹配的说明符并输入。

// printf("length p: %lu\n", strlen(plaintext));
printf("length p: %zu\n", strlen(plaintext));

提示:下面的2个在功能上是等效的,第二个在C语言中是惯用的。

for (int i = 0, l = strlen(argv[1]); i < l; i++)
for (int i = 0; argv[1][i]; i++)
// of better
for (size_t i = 0; argv[1][i]; i++)

`