【问题标题】:decrypt and encrypt text with command line arguments使用命令行参数解密和加密文本
【发布时间】:2016-07-10 19:35:02
【问题描述】:

我正在尝试制作一个程序,当用户为argv[2] 输入他们想要加密/解密的字符串并为argv[3] 输入“加密”或“解密”时,该程序将加密和解密。这是我现在尝试编译和运行的代码

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main(int argc, char **argv)
{
    int i;
    // char *string;
    char *key_ch;
    char  key_int;
    char *string_ = calloc(80, 1);
    string = argv[1];
    char encrypted_string[strlen(string)];
    char decrypted_string[strlen(string)];
    //char *key_ch;
    //char key_int;
    string = argv[1];
    key_ch = argv[2];
    key_int = atoi(key_ch);

    if (argc < 3)
    {
       printf("Not enough arguments!\n");
       exit (1);
    }

    if (strcmp(argv[3], "encrypt") == 0)
    {
            i = 0;
            while(i <= strlen(string)-1)
            {
                    encrypted_string[i] = string[i] + key_int;
                    i++;
            }

    //      printf("Encrypted string: ");
            i = 0;
            while (i <= strlen(string) -1)
            {
                    printf("%c", encrypted_string[i]);
                    i++;
            }
            printf("\n");
    }
    if (strcmp(argv[3], "decrypt") == 0)
    {
            i = 0;
            while(i <= strlen(string) -1)
            {
                    decrypted_string[i] = string[i] - key_int;
                    i++;
            }

    //      printf("Decrypted String: ");
            i = 0;
            while (i <= strlen(string) -1)
            {
                    printf("%c", decrypted_string[i]);
                    i++;
            }

            printf("\n");

    }
    return 0;
}

当我尝试在不使用 -Wall 命令的情况下编译它时,它编译得很好,但是当我运行程序时出现分段错误,当我使用 -Wall 编译时,我得到了

sam0.c:9:24: 警告:“字符串”在此函数中未初始化 [-Wuninitialized]

char encrypted_string[strlen(string)];

谁能解释一下这个错误?谢谢

编辑: 将我的代码更改为您的建议。即使使用“-Wall”,我也根本没有收到编译错误,但是在我的程序中的某个地方它导致我遇到分段错误......有什么想法吗?我在更改代码的地方加上引号,以防我做错了。

【问题讨论】:

  • 问题出在您最近的编辑中,您创建了字符串变量的两个变体:char *string_,然后在其他任何地方使用string。让它们都一样。

标签: c debugging segmentation-fault


【解决方案1】:

警告:“字符串”在此函数中未初始化使用 [-Wuninitialized]

char *string; 创建一个指向 char 的指针。此时它还不是字符串,但您将其用作字符串参数。

在使用char *string;之前,它必须分配内存,并且应该被初始化。在其他方法中,可以通过以下方式完成:

char *string = calloc(80, 1);//initializes with known values (NULL).  

现在string 可用,但长度为零。可以通过字符串函数赋值:

strcpy(string, argv[1]);
sprintf(string, "%s", argv[1]);
strcat(string, argv[1]);

... more string functions

使用命令行输入时,argv, argcmalloc/calloc 和字符串 cpy 函数可以通过使用 strdup 来避免。可以这样赋值:

if(argc == 2)
{
    char *string = strdup(argv[1]);
    if(!string) return -1;
    ...

EDIT(解决您的 OP 编辑​​问题)
您现在使用两个不同的变量:string_string

char *string_ = calloc(80, 1);
            ^
string = argv[1];

在您的代码中使它们相同,它应该可以构建和运行。

【讨论】:

  • 合并两个答案并不总是最好的选择:-)。 +1
【解决方案2】:

当可以确定变量有意义的值时,尝试一步声明和初始化变量:

char *string = argv[1];
char encrypted_string[strlen(string)];
char decrypted_string[strlen(string)];
char *key_ch = argv[2];
char key_int = atoi(key_ch);

这将修复警告:您试图获取未初始化字符串的长度。

(这里假设 C99。char encrypted_string[strlen(string)]VLA。如果您仅限于 C89,则只有 Rykker's answer 有效)。

还有:

  • 使用const 防止不必要的修改,例如

    const char *string = argv[1];
    /* ... */
    const char *key_ch = argv[2]
    
  • string 是一个常数,因此您只能获得一次它的长度(不要每次都重新计算长度......看看Shlemiel the painter's algorithm)。所以

    const char *string = argv[1];
    const int length = strlen(string);
    
    char encrypted_string[length];
    char decrypted_string[length];
    
    const char *key_ch = argv[2];
    char key_int = atoi(key_ch);
    
  • 检查输入:如果发生会发生什么

    • argc &lt; 4
    • argv[3] 不在(“加密”、“解密”)中
    • key_ch 不是数字
    • key_int 太大了
  • 您一次打印encrypted_string / decryped_string 一个字符...并且它有效,但请考虑,如果您想将它们作为“字符串”进行操作,它们不会以空值结尾并且它们的长度不正确。

  • 不要重复自己。加密阶段和解密阶段之间的差异很小:您可以只使用一个缓冲区并将key_int 更改为负值来解密。

【讨论】:

    【解决方案3】:
    char *string;
    char encrypted_string[strlen(string)];
    char decrypted_string[strlen(string)];
    

    这会导致未定义的行为 - 您尝试获取一块未初始化的内存的长度(我很惊讶您的程序没有崩溃)。你只能在给string分配一些东西后才能调用strlen

    最简单的解决方法(假设您不想开始使用mallocstrdup 等)将在string = argv[1]; 之后移动最后两行

    另外,您需要检查argc 以确保传递了足够多的参数!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-11-27
      • 2016-06-05
      • 2020-11-29
      • 1970-01-01
      • 1970-01-01
      • 2014-10-24
      • 2014-04-15
      • 2021-11-06
      相关资源
      最近更新 更多