2016-03-23 67 views
1

我正在嘗試製作一個程序,當用戶輸入他們想要對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]

炭encrypted_string [strlen的(字符串)];

任何人都可以照亮這個錯誤嗎?謝謝

編輯: 更改我的代碼爲您的建議。即使在使用「-Wall」時,我也沒有收到編譯錯誤,但是在我的程序中的某處它正在導致我得到一個分段錯誤......任何想法?我把引號放在我改變我的代碼的地方以供參考,以防我做錯了。

+0

問題是在你最近的編輯中,你創建了兩個字符串變量的變體:'char * string_',然後你在其他地方使用'string'。讓他們都一樣。 – ryyker

回答

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]不在( 「加密」, 「解密」)
    • key_ch不是數字
    • 發生什麼事key_int太大
  • 你正在印刷encrypted_string/decryped_string一次一個字符...它的工作原理,但考慮如果你想操縱它們作爲'字符串',它們不是空終止,他們的長度是不正確的。

  • 不要重複自己。加密和解密階段之間的差異很小:您只能使用一個緩衝區並將key_int更改爲負值以解密。

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

這將導致不確定的行爲 - 你試圖獲得未初始化的內存塊的長度(我很驚訝,你的程序不會崩潰)。在分配string之後,您只能撥打strlen

最簡單的修復(假設你不想開始使用mallocstrdup等)會後string = argv[1];

而且最後兩行動,你需要檢查argc,以確保有足夠的論據有已通過!

1

警告: '字符串' 在這個函數中使用的未初始化 [-Wuninitialized]

char *string;創建一個字符指針。此時它還不是一個字符串,但是您將它用作字符串參數。

使用之前char *string;它必須分配內存,並且應該被初始化。在其他methoods,這可以來完成的:

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; 
    ... 

編輯(解決您的OP編輯)
您現在正在使用兩個不同的變量:string_string

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

讓他們在整個同你代碼,它應該建立並運行。

+0

合併兩個答案並不總是最好的選擇:-)。 +1 – manlio