简体   繁体   English

C ++不确定如何让我的程序输出空间的位置

[英]C++ Not sure how to have my program output the location of a space

Alright, so I have two questions and if anyone can help me out I would greatly appreciate it! 好吧,所以我有两个问题,如果有人可以帮助我,我将不胜感激! This is my first programming class, so it would also be my first C++ class and I'm a bit stuck. 这是我的第一门编程课,所以这也是我的第一门C ++课,我有点受困。

So I created a Caesar cipher that shifts the string that the user inputs to the right by a pseudo random number between 8-15. 因此,我创建了一个Caesar密码,将用户输入的字符串向右移动8-15之间的伪随机数。 What the complete program needs to do is give the number it is shifted by at the beginning, followed by the encrypted string. 完整程序需要做的是在开始时给出要移动的数字,然后是加密的字符串。 If there are spaces in the string that are inputed, they need to take the letter/number that is before the space and shift it by 4. I need to terminate the encryption with an '&' character and that is followed by a '#' character and then the number location of the first space followed by another '#' character and another location of a second space if there is one and so on. 如果输入的字符串中有空格,则需要使用空格前的字母/数字并将其移位4。我需要以“&”字符终止加密,然后以“#”结尾。 '字符,然后是第一个空格的数字位置,然后是另一个'#'字符和第二个空格的另一个位置(如果有),依此类推。

So for example, if I were encrypting a string that was being shifted by 9 and said: 因此,例如,如果我正在加密一个被移位了9的字符串并说:

Hello World 123

It should look like this when encrypted: 加密后应如下所示:

9qnuuxsfxaumh012&#6#12
  1. My first and more important question. 我的第一个也是更重要的问题。 I can't figure out how to make the program output the '#' character followed by the number that tells the location of the space. 我不知道如何使程序输出“#”字符,后跟告诉空格位置的数字。 I've thought of maybe doing some kind of loop that reads the string but I'm coming up blank. 我想过可能要做某种循环来读取字符串,但是我空白了。 If I could get some advice that would be great as this is the only part holding me up from turning this in. 如果我能得到一些建议,那将是很棒的,因为这是阻止我上交的唯一部分。

  2. My second question comes from a little confusion within my own code that I would love an English interpretation on how it works since I don't understand it myself. 我的第二个问题来自我自己的代码中的一些混乱,因为我自己不理解它,所以我希望对它的工作原理进行英语解释。 I was first using just for loops to make it so that the character 'z' would wrap back around to 'a' but no matter what I did, I kept getting it to only wrap around after a '{' character which is the next character after 'z' on the ascii table. 我首先使用just for循环来使字符“ z”回绕到“ a”,但是不管我做什么,我一直让它仅在“ {”字符之后回绕,这是下一个ASCII表格上“ z”后的字符。 So I decided to change my method and I read on wikipedia under "Caesar cipher" that you could use a modulus. 因此,我决定更改我的方法,并在Wikipedia上的“ Caesar cipher”(凯撒密码)下阅读,可以使用模数。 So I used the equation they gave me which was E(x) = (a + b) mod 26. Well it didn't work. 因此,我使用了他们给我的方程式,即E(x)=(a + b)mod 26。 So I started to do a google search and saw 2 different posts where people subtracted the character 'a' and then added the chracter 'a' back on at the end as well as added the variable to itself with +=. 因此,我开始进行Google搜索,并看到2条不同的帖子,人们在其中减去了字符“ a”,然后又在最后添加了字符“ a”,并使用+ =将变量添加到其自身中。 So I put it in and it worked. 所以我把它放进去了。
    It looks like this: 看起来像这样:

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

and I thought it would look like this after reading the wiki and it not working when i put this in 而且我认为在阅读Wiki后会看起来像这样,当我将其放入时它不起作用

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

Same goes for wrapping the numbers as well: 包装数字也是如此:

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

So if someone could explain to me why I am adding output to itself as well as subtracting 'a' in the beginning and then re-adding 'a' at the end so I could understand what's going on. 因此,如果有人可以向我解释为什么我要向自身添加输出并在开始时减去“ a”,然后在末尾重新添加“ a”,这样我就可以理解发生了什么。 I really don't like having code in a program that I'm going to turn in that I don't even understand myself. 我真的不喜欢在程序中添加代码,因为我什至不了解自己。

Anyways, I'm sorry for the long read, I just thought I would explain what's going on and what I need clearly so that anyone willing to help would completely understand what I'm saying without me having to follow up with a second post explaining. 无论如何,很抱歉我读了很长时间,我只是想我会解释发生了什么事和我需要什么,以便任何愿意帮助的人都能完全理解我在说什么,而无需我继续第二篇文章的解释。 。

And finally here's the full program that I have written: 最后是我编写的完整程序:

#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;   
}

Thanks so much for anyone willing to help! 非常感谢任何愿意提供帮助的人!

Two answer the second question: 两个回答第二个问题:

input[count] - 'a'

This gives you 0 for the letter a, 1 for the letter b, ... 25 for the letter z. 这将为字母a提供0,为字母b提供1,...为字母z提供25。

input[count] - 'a' + n

Then you add the number n. 然后添加数字n。 Having "a" as an input and being n==2 you will get a 3. But for a "z" as input you will get a 27. 以“ a”作为输入且n == 2时,您将得到3。但是,以“ z”作为输入时,您将得到27。

To solve the problem you use the modulus: 要解决此问题,请使用模数:

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

The result is a 1 for the "z". 结果为“ z”的1。

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

Now you transfer the number from 0 to 25 back to the corresponding ASCII code. 现在,您可以将数字从0传输到25,再传输回相应的ASCII码。

The point of the seemingly odd expansion is to do the following: 看似奇怪的扩展的目的是要执行以下操作:

  • Create a number from 0..25: input[count] - 'a' 从0..25创建一个数字: input[count] - 'a'
  • Adjust that number by adding your shift amount: + n 通过增加班次数量来调整该数字: + n
  • Modulo the result with 26 to wrap overflow of 26+ back into 0..25: % 26 用26取模结果以将26+的溢出包装回0..25: % 26
  • And finally, add that result back to the base character: + a`` 最后,将结果添加回基本字符: + a``

Your idea of a shortcut: 您的捷径构想:

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

simply takes the ascii value of the input char, adds the shift, then modulo 26. The result is a value in 0..25, nowhere near the range of 'a'..'z' . 简单地获取输入char的ascii值,加上移位,然后取模26。结果是0..25中的值,远不及'a'..'z'

And before you think just adding 'a' would work, it isn't that simple. 在您认为仅添加'a'将起作用之前,它并不是那么简单。 For example, suppose you had a shift of 9 and in input char of 'z' 例如,假设您的位移为9,输入字符为'z'

The presented formula that works: (ch - 'a' + n) % 26 + 'a' 给出的有效公式: (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'

Your formula, with 'a' adjustment: (ch + n) % 26 + 'a' 您的公式经过'a'调整: (ch + n) % 26 + 'a'

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

The problem is the distance from the beginning of the char sequence that is being modulo-adjusted is never accounted for in the modulo reduction. 问题在于,从模调整后的char序列的开始到距离的距离永远不会在模减少中得到考虑。 Thus the reason for the formula you find odd. 因此,您发现该公式的原因很奇怪。


Regarding how to accumulate a list of space locations. 关于如何累积空间位置列表。 a ostringstream will make that trivial , as would a std::vector<int> . ostringstreamstd::vector<int>一样会使琐碎 An example of the former looks like this: 前者的示例如下所示:

#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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM