首页 > 解决方案 > 为什么在 For 循环中数组不填充值,其中每个数组元素 [i] 都分配有变量?

问题描述

代码编译正常。我尝试使用调试器,但无法找出问题所在。每次迭代“c”都被填充,但似乎我尝试将此变量“c”分配到数组中的方式没有任何反应,因此结束打印语句以“ciphertext:EMPTY NOTHING”结束

非常欢迎任何帮助或想法。我正在学习课程并尝试解决一组问题。我只是初学者,请不要努力:)

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

int main (int argc, string argv[])
{

    if(argc < 2 || argc<2 )
    {
        printf("Usage: ./caesar key \n");
        return 1;
    }
    
   
    else if(argc == 2)
    {
        for (int i = 0; i < strlen(argv[1]); i++)
        {
            if(!isdigit(argv[1][i]))
            {
                printf("Usage: ./caesar key \n");
                return 1;
            }
        }
    }



    int key = atoi(argv[1]);


    string initial_text = get_string("plaintext: ");

    
    int cipher[strlen(initial_text)];
    int i = 0;
    int n = strlen(initial_text);

    for (i = 0; i < n; i++)
    {
        int c = 0;

        if (isupper(initial_text[i]))
        {
            c = (((int)initial_text[i] - 65 + key) % 26) + 65;
            cipher[i] += c;
        }

        else if (islower(initial_text[i]))
        {
            c = (((int)initial_text[i] - 97 + key) % 26) + 97;
            cipher[i] += c;
        }

        
        else
        {
            c=initial_text[i];
            cipher[i] += c;
        }
    }

    //////////////////
    printf("ciphertext: %c\n", (char)cipher);

}

标签: arraysccs50

解决方案


有很多问题:

  1. 当您 [可能] 需要时使用intfor 。cipherchar
  2. cipher没有为尾随的 0x00 [EOS] 字符串终止符定义足够的空间
  3. 最后没有设置EOS。
  4. %c%sprintf.
  5. if ((argc < 2) || (argc < 2))是错误的,可以替换为if (argc != 2).
  6. 因为这样if做了,所以不再需要return后续检查。else if
  7. “硬连线”十进制值(例如65for 'A')。
  8. 在循环strlen中的条件表达式中使用。for这将循环的运行时间从 O(n) 增加到 O(n^2)。
  9. 这可以替换为(例如)将数组元素与 0x00 进行比较。
  10. 使用strtol代替atoi和检查结束可以在单个操作中进行解码和验证。
  11. string定义时不要使用argv--use char **argv
  12. 你最后main缺少一个return 0;
  13. 有很多可以简化的复制代码。

这是重构的代码:

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

// I don't have cs50 handy, so a quick hack ...
#define string  char *
string
get_string(const char *prompt)
{
    char buf[1000];
    char *cp;

    printf("%s",prompt);
    fflush(stdout);

    do {
        cp = fgets(buf,sizeof(buf),stdin);
        if (cp == NULL)
            break;

        // strip newline
        buf[strcspn(buf,"\n")] = 0;

        // IIRC, [real] get_string does heap allocation (vs. static buffer) but
        // for demo purposes here, doesn't really matter
        cp = strdup(buf);
    } while (0);

    return cp;
}

int
main(int argc, char **argv)
{

    // check if there is exactly 2 arguments passing, otherwise prompt for a
    // valid key(+return 1, to signal mistake)
    if (argc != 2) {
        printf("Usage: ./caesar key \n");
        return 1;
    }

    // otherwise check if the key is only a digit and prompt for a valid
    // key(+return 1, to signal mistake)
    // loop through each character in the second argument and validate
    char *arg = argv[1];

    // convert a string to int variable to be used in transformation of letters
    int key = strtol(arg,&arg,10);
    if (*arg != 0) {
        printf("Usage: ./caesar key \n");
        return 1;
    }

    // prompt for plaintext
    string initial_text = get_string("plaintext: ");

    // create an array of int to store encrypted letters to then be converted
    // in print by (char)
    // NOTE: we need one extra to make room for the trailing EOS
    char cipher[strlen(initial_text) + 1];

    const char *src = initial_text;
    char *dst = cipher;

    for (int chr = *src++;  chr != 0;  chr = *src++, ++dst) {
        if (isupper((unsigned char) chr)) {
            *dst = (((chr - 'A') + key) % 26) + 'A';
            continue;
        }

        if (islower((unsigned char) chr)) {
            *dst = (((chr - 'a') + key) % 26) + 'a';
            continue;
        }

        // for all none alphabetic symbols leave them as they are
        *dst = chr;
    }

    // set the trailing EOS
    *dst = 0;

    // ////////////////
    printf("ciphertext: %s\n", cipher);

    return 0;
}

推荐阅读