2014-10-11 37 views
1

好吧,所以我有兩個問題,如果任何人都可以幫助我,我將不勝感激!這是我的第一個編程類,所以它也是我的第一個C++類,我有點卡住了。C++不知道如何讓我的程序輸出空間的位置

所以我創建了一個凱撒密碼,它將用戶輸入的字符串通過8-15之間的僞隨機數移動到右邊。完整的程序需要做的是給出它在開始時被移動的數字,然後是加密的字符串。如果輸入的字符串中有空格,則需要採用空格前面的字母/數字並將其移位4.我需要用'&'字符終止加密,然後是'# '字符,然後是第一個空格的數字位置,後面是另一個'#'字符,另一個位置是第二個空格(如果有的話),等等。

因此,舉例來說,如果我被加密這是一個由9偏移和一個字符串:

Hello World 123 

它應該是這樣的,當加密:

9qnuuxsfxaumh012&#6#12 
  1. 我的第一個和更重要的問題。我無法弄清楚如何讓程序輸出'#'字符,後跟數字,告訴空間的位置。我曾想過可能會做一些循環來讀取字符串,但我會空白。如果我能得到一些很好的建議,因爲這是唯一使我無法接受的部分。

  2. 我的第二個問題來自我自己代碼中的一個小混亂,那就是我會喜歡英語解釋它起作用,因爲我自己不明白它。我第一次使用for循環來使得字符'z'會繞回'a',但不管我做了什麼,我總是隻在下一個'{'字符後環繞它ascii表上'z'後面的字符。所以我決定改變我的方法,並在「Caesar cipher」下的維基百科上閱讀,您可以使用模數。所以我用他們給我的等式是E(x)=(a + b)mod 26.那麼它不起作用。所以我開始做谷歌搜索,看到兩個不同的帖子,其中人們減去字符'a',然後在最後加上字符'a',並用+ =將自己的變量添加到自己。所以我把它放進去了,它工作了。
    它看起來像這樣:

    output += ((input[count] - 'a' + n) % 26) + 'a'; 
    

,我認爲這應該是這樣的閱讀維基後,當我把這個

output = ((input[count] + n) % 26) 

同去的包裹它不工作數字以及:

output += ((input[count] - '0' + n) % 10) + '0'; 

因此,如果有人可以向我解釋爲什麼我加輸出到自身,並在開始時減去'a',然後在結尾重新添加'a',這樣我就能理解到底發生了什麼。我真的不喜歡在一個我打算轉入的程序中編寫代碼,我甚至不理解我自己。

無論如何,我很抱歉長時間閱讀,我只是想我會解釋發生了什麼以及我需要清楚些什麼,以便任何願意幫助的人都能完全理解我說的話,而不必跟隨第二篇文章解釋。

最後這裏是完整的程序,我已經寫了:

#include <ctime> 
#include <iostream> 
#include <string> 
#include <cstdlib> 
#include <fstream> 
using namespace std; 

//random number generator between 8 and 15 
int random() 
{ 
    int value; 
    value = rand() % (18 - 10) + 8; 
    return value; 
} 

int main() 

{ 
    //Give random() a seed 
    srand(time(NULL)); 

    //Declare variables 
    string input; 
    int length; 
    int n = random(); 
    string output; 

    //Program 
    cout << "Enter your secret message: " << endl; 
    getline (cin, input); 
    cout << n; 

    length = input.length(); 

    for (int count = 0; count < length; count++) 
    { 
     input[count] = tolower(input[count]); 
     if (input[count] >= 'a' && input[count] <= 'z') 
     { 
      output += ((input[count] - 'a' + n) % 26) + 'a'; 
     } 
     if (input[count] >= '0' && input[count] <= '9') 
     { 
      output += ((input[count] - '0' + n) % 10) + '0'; 
     } 
     else if(input[count] == ' ') 
     { 
      if (input[count - 1] >= 'a' && input[count - 1] <= 'z') 
      { 
       output += ((input[count - 1] - 'a' + 4) % 26) + 'a'; 
      } 
      else if (input[count - 1] >= '0' && input[count - 1] <= '9') 
      { 
       output += ((input[count - 1] - '0' + 4) % 10) + '0'; 
      } 
      cout << output; 
     } 
    } 
      cout << output << endl; 
      return 0; 
} 

感謝這麼多的人願意幫助!

+0

'((輸入[COUNT] + N)%26)'將產生0和25之間的數,而不是A'和'Z之間''一個char' '。因此,爲什麼這是行不通的。你錯過了一個字符庫。 – WhozCraig 2014-10-11 08:38:10

+0

這是有道理的,但如果是這樣的話,那麼爲什麼我需要爲數字做同樣的事情呢?如果它會給我一個數字,爲​​什麼我需要減去0,然後在最後加上0來使其工作。另外,爲什麼我必須放一個+ =符號而不是一個=符號。最後,爲什麼要減去特定字符'a'並添加特定字符'a'將所有內容都轉換爲'a'和'z'之間的字符?對不起,我真的很想明白。 – Cush 2014-10-11 08:50:59

+0

請閱讀下面的答案。 – WhozCraig 2014-10-11 08:52:33

回答

0

看似奇數膨脹點是執行以下操作:通過添加偏移量input[count] - 'a'

  • 調整該號碼:+ n
    • 從0..25創建數將26+溢出的結果返回到0..25:% 26
    • 最後,將結果添加回基本字符:+ a``

    你的快捷方式的想法:

    output = ((input[count] + n) % 26) 
    

    簡單地獲取輸入字符的ASCII值,增加了移,然後模26的結果是在0..25的值,遠不範圍爲'a'..'z'

    而之前你認爲只需加入'a'就行了,事情並不那麼簡單。例如,假設你有一個9的轉變,在'z'

    所提出的公式的輸入字符的作品:(ch - 'a' + n) % 26 + 'a'

    (('z' - 'a' + 9) % 26 + 'a' 
    ((122 - 97 + 9) % 26 + 97 
    34 % 26 + 97 
    8 + 97 
    105, the ascii value of 'i' 
    

    你的配方,'a'調整:(ch + n) % 26 + 'a'

    ('z' + 9) % 26 + 'a' 
    (122 + 9) % 26 + 97 
    131 % 26 + 97 
    1 + 97 
    98, the ascii value for 'b'. 
    

    的問題在於模數調整後的char序列開始的距離從不計入模減少量。因此,公式的原因你覺得很奇怪。


    關於如何累積空間位置列表。一個ostringstream將使瑣碎,如將std::vector<int>。這樣前者長相的示例:

    #include <ctime> 
    #include <iostream> 
    #include <string> 
    #include <cstdlib> 
    #include <fstream> 
    #include <sstream> // for std::ostringstream 
    using namespace std; 
    
    int main() 
    
    { 
        //Give random() a seed 
        srand(static_cast<unsigned>(time(NULL))); 
    
        //Declare variables 
        string input; 
        int length; 
        int n = rand() % (18 - 10) + 8; 
        string output; 
    
        //Program 
        cout << "Enter your secret message: " << endl; 
        getline (cin, input); 
        cout << n; 
    
        // string stream to hold the list of space locations. 
        std::ostringstream oss; 
    
        length = input.length(); 
    
        for (int count = 0; count < length; count++) 
        { 
         input[count] = tolower(input[count]); 
         if (input[count] >= 'a' && input[count] <= 'z') 
         { 
          output += ((input[count] - 'a' + n) % 26) + 'a'; 
         } 
         if (input[count] >= '0' && input[count] <= '9') 
         { 
          output += ((input[count] - '0' + n) % 10) + '0'; 
         } 
         else if(input[count] == ' ') 
         { 
          if (input[count - 1] >= 'a' && input[count - 1] <= 'z') 
          { 
           output += ((input[count - 1] - 'a' + 4) % 26) + 'a'; 
          } 
          else if (input[count - 1] >= '0' && input[count - 1] <= '9') 
          { 
           output += ((input[count - 1] - '0' + 4) % 10) + '0'; 
          } 
    
          // add space location with preamble to string stream 
          oss << '#' << count; 
         } 
        } 
    
        // append space accumulated list string to the end after '&' 
        cout << output << '&' << oss.str() << endl; 
        return 0; 
    } 
    
  • +0

    非常感謝!你偶然知道我會如何得到我的第一個問題的答案嗎?我不需要有人爲我寫代碼。我真的需要在正確的方向邁出堅實的一步。謝謝! – Cush 2014-10-11 09:01:53

    +0

    @Cush完成。這是做到這一點的一種方式。還有其他的,但那是一件很微不足道的事情,它近乎可笑。祝你好運。 – WhozCraig 2014-10-11 09:23:16

    +0

    我將不得不打開我的書並跳過去閱讀並理解stringstream是如何工作的,因爲我不記得我們經歷過什麼課程。感謝您的幫助,我非常感謝。 – Cush 2014-10-11 09:45:59

    1

    兩個回答第二個問題:

    input[count] - 'a' 
    

    這給你0爲字母B字母a,1,... 25字母Z。

    input[count] - 'a' + n 
    

    然後你添加數字n。有「一」作爲輸入,併爲n == 2,你會得到一個3。但是,對於一個「Z」作爲輸入,你會得到一個27

    爲了解決這個問題,你使用的模量:

    (input[count] - 'a' + n) % 26 
    

    結果是「z」的1。

    ((input[count] - 'a' + n) % 26) + 'a' 
    

    現在您將數字從0到25轉移回相應的ASCII碼。

    +0

    謝謝,我真的很感謝幫助!你偶然知道我將如何得到我的第一個問題的答案?我不需要有人爲我寫代碼,我只是非常需要朝着正確的方向邁出一大步。謝謝! – Cush 2014-10-11 09:01:01

    +0

    給我們一些代碼。你試圖解決第一個問題的問題是什麼?你已經有了你的for循環中的「count」變量,只要你看到一個空格,你只需要保存這個值。 – Novi 2014-10-11 09:15:22

    +0

    沒關係,我很笨>。<我明白了。真的很容易,我會編輯第一篇文章 – Cush 2014-10-11 09:19:45

    相關問題