【问题标题】:String concatenation with variables and pointers in 'C'字符串与“C”中的变量和指针连接
【发布时间】:2019-02-17 17:22:55
【问题描述】:

我正在为一门在线课程研究 Caesar 的密码,但我对最终输出中的原始值有疑问,我似乎无法摆脱它。我怀疑是因为

strcpy(str1, &final_val);
strcat(str2, str1);

以错误的方式调用,所以当我运行时

make test && ./test 1

这为我的程序提供了参数1,并提供了转换字母和编码消息的密钥。我期待看到

plaintext: asd
ciphertext: bcd 

我得到了

plaintext: asd
ciphertext: bacbdc

如果您想试用代码,则需要在this sanbox 内进行,因为它具有所需的 CS50 库。

代码

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

bool input_valid(int count, string arg);
bool in_alphabet(int count, string arg);

int main(int argc, string argv[]) {
    int key;
    int ascii_val;
    char final_val;
    string string;

    char str1[80];
    char str2[80];

    // check input again if validation fails
    if (!input_valid(argc, argv[1])) {
        printf("Invalid input!\nUSAGE: ./caesar key\n");
        return 1;
    }

    string = get_string("plaintext: ");

    // get integer from string input
    key = strtol(argv[1], NULL, 10);

    for (int i = 0; i < strlen(string); i++) {
        ascii_val = (int)string[i];

        bool valid_lower_case = (ascii_val + key) >= 97 && (ascii_val + key) <= 122;
        bool valid_upper_case = (ascii_val + key) >= 65 && (ascii_val + key) <= 90;

        // check if value is a letter
        if (isalpha(string[i])) {
            // check if value is in the valid alphabet range
            if (valid_lower_case || valid_upper_case) {
                final_val = ascii_val + key;
            } else {
                // for lowercase: wrap around if the letter passes 'z'
                final_val = 97 + (key - (122 - (ascii_val - 1)));
            }
        } else {
            final_val = ascii_val;
        }

        strcpy(str1, &final_val);
        strcat(str2, str1);
    }
    for (int i = 0; i < 5; i++) {
        printf("%i\n", str2[i]);
    }

    printf("ciphertext: %s\n", str2);
}

bool input_valid(int count, string arg) {
    // input has more args than just the file name
    // input is an integer
    return count > 1 && isdigit(arg[0]);
}

【问题讨论】:

  • 1. strcpyC 字符串(以 NUL 结尾的字符串)作为参数;您不能只传递任意的char*。 2. str2 从未被初始化,所以strcat(str2, ...) 被附加到垃圾中。
  • str2 在第 17 行初始化为 char str2[80];
  • 不,不是。那声明 str2。作为一个局部变量,它没有被初始化为任何东西。
  • char str2[80] = {0};有帮助吗
  • 是的,这将解决初始化问题。

标签: c string string-concatenation cs50 strcat


【解决方案1】:

strcpy(str1, &amp;final_val); 是未定义的行为。 strcpy 期望两个参数都是指向以空字符结尾的字符串的指针。但是,由于数组在传递给函数时会衰减为指针,strcpy 不知道指向字符数组的指针和单个 char 变量的地址之间的区别。

它将尝试将从&amp;final_val 开始的内存复制到str1,仅当它在进程内存中的其他地方遇到空终止符时才会停止,如果有的话。要将单个字符复制到字符串中,只需使用 str[x] = chstr[x + 1] = '\0'

【讨论】:

    【解决方案2】:

    替换了strcopy()strcat()。通过像这样附加到str2 让它工作:

    str2[i] = final_val;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-03
      • 1970-01-01
      • 1970-01-01
      • 2020-03-25
      • 2013-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多