使用命令行参数

时间:2016-03-23 13:22:34

标签: c debugging segmentation-fault

我正在尝试创建一个程序,当用户输入他们想要为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:警告:&#39; string&#39;在此函数中使用未初始化的[-Wuninitialized]

     

char encrypted_string [strlen(string)];

任何人都可以对此错误有所了解吗?谢谢

修改 将我的代码更改为您的建议。即使使用&#34; -Wall&#34;我也没有得到编译错误。但是在我的程序中某处导致我出现分段错误...任何想法?我把引号放在我改变代码的地方以备参考,以防我做错了。

3 个答案:

答案 0 :(得分:1)

  

警告:&#39;字符串&#39;在此函数中使用未初始化   [-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, argc可以避免使用malloc/callocstrdup和字符串cpy函数。可以像这样分配一个值:

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

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

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

在整个代码中使它们相同,它应该构建并运行。

答案 1 :(得分:0)

char *string;
char encrypted_string[strlen(string)];
char decrypted_string[strlen(string)];

这会导致未定义的行为 - 您试图获得未初始化的内存的长度(我很惊讶您的程序没有崩溃)。您只能在为strlen分配内容后致电string

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

此外,您需要检查argc以确保已传递足够的参数!

答案 2 :(得分:0)

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

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 < 4
    • argv[3]不在(&#34;加密&#34;,&#34;解密&#34;)
    • key_ch不是数字
    • key_int太大了
  • 您一次打印encrypted_string / decryped_string一个字符......但它确实有效,但请考虑一下,如果您想将它们作为&#39;字符串& #39;它们没有被终止,它们的长度也不正确。

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