【问题标题】:Block Cypher Code块密码代码
【发布时间】:2013-03-29 21:05:47
【问题描述】:

我的任务是编写一个程序,它读取标准输入,存储文本直到遇到 EOF,然后使用凯撒分组密码对文本进行加密。

解决方案的步骤:

  1. 所以:将您的消息读入一个大缓冲区或字符串对象。
  2. 是否删除空格和标点符号
  3. 然后计算消息中的字符数。
  4. 选择第一个大于消息长度的完美正方形, 分配一个大小为 char 的数组。
  5. 将消息读入正方形 该大小的数组从左到右,从上到下。
  6. 从上到下、从左到右写出消息,您就已经对其进行了加密。

这就是我目前所拥有的......它可以编译但不做任何事情。我知道我一定错过了什么。任何帮助将不胜感激。

#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <ctype.h>
#include <cstring>
#include <cmath>
#include <string>
using namespace std;

int main()
{
    // read in char from keyboard
    string buff;
    do
    {
        cin >> buff;
    } while ( ! cin.eof()) ;

    // delete spaces and punctuation
    for ( int i = 0 ; i < sizeof ( buff ) ; i++ )
    {
        if  ( !isalnum ( buff[i] )  )
        {
            buff.erase( i,1 );
            --i;
        }
    }

    // get length of edited string
    int static SIZE = buff.length(); //strlen (buff);

    // pick first perfect _square_ greater then the message length (ex:7x7)
    int  squared = static_cast <int> ( sqrt( static_cast <double> ( SIZE )) + .5f );

    // allocate an array of char that size
    char ** board;
    board = new char *[squared];      // array of 'squared' char pointers
    for ( int i = 0 ; i < squared ; i++ )
        board[i] = new char[squared];

    // read messsage into a square array of that size from left to right top to bottom
    for ( int c = 0 ; c < squared  ; c++ )
        for ( int r = 0 ; r < squared ; r++ )
            buff[r] = board[r][c];

    // write the message out top to bottom, left to right and its been encyphered
    for ( int r = 0 ; r < squared  ; r++ )
        for ( int c = 0 ; c < squared ; c++ )
            cout << board[r][c] << endl;

    // delete array
    delete [] board;
    for ( int i = 0 ; i < squared ; ++i )
        delete [] board[i] ;

} // end main

【问题讨论】:

  • 关闭delete[] 逻辑的顺序将使事情变得相当……有趣……在关机期间。
  • 哈哈谢谢@WhozCraig。我把它换了。

标签: c++ arrays string encryption multidimensional-array


【解决方案1】:

这很奇怪

string buff;
do
{
    cin >> buff;
} while ( ! cin.eof());

不确定您认为这会实现什么。为什么不只是这个?

string buff;
cin >> buff;

另一个错误

for ( int i = 0 ; i < sizeof ( buff ) ; i++ )

应该是

for ( int i = 0 ; i < buff.length() ; i++ )

几行之后你就对了,所以不知道为什么这里是错的。

【讨论】:

  • 谢谢约翰,好收获!我试图使其成为“水泵”类型的代码,您可以在其中继续输入字符直到 EOF 并一次又一次地执行此操作。
  • @user2255496,好的,但是你的整个程序必须在do while循环中,而不仅仅是输入语句。
  • 好的,我明白了。现在我已经在开始时编辑了它,不带 while 循环,它会编译不带错误,但在我输入任何文本并按 Enter 后崩溃。这可能是什么原因造成的?
【解决方案2】:

我尝试编译并运行您的代码 - 发现了许多问题。

1) 您的“擦除”循环进入无限循环。从数组的开头开始,循环遍历所有元素,在遍历时删除元素,并期望事情在最后是正确的,这通常是非常糟糕的做法。从头到尾从头开始倒更安全:

for(ii = buff.length() - 1; ii>=0; ii--) {
  if  ( !isalnum ( buff[i] )  )
    {
    cout << "erasing " << buff[i] << endl;
    buff.erase( i,1 );
    }
  }
}

你会的

delete [] board;

在删除数组中的单个元素之前...不确定语法是什么,但我觉得它不正确!

你的板子不够大。你必须使用ceil 函数来确保你真的得到了“下一个最大”的数字:

square = ceil(sqrt(buff.length()));

还有一个大问题:您将(空)缓冲区复制到输入字符串中,而不是相反:

buff[r] = board[r][c];

应该是这样的

ii = 0;
for(( int c = 0 ; c < squared  ; c++ )
  for ( int r = 0 ; r < squared ; r++ )
    board[r][c] = buff[ii++];

可能还有其他人......仍在解决问题。

编辑:这是完整的工作代码。

    // read in char from keyboard
    int i;
    string buff;
    cout << "enter the text to be encoded" << endl;
    getline(cin,buff);
    cout << "done reading in the text!" << endl;
    cout << "buffer size is " << buff.length() << endl;
    cout << "the string is " << endl << buff << endl;
    // delete spaces and punctuation
    for ( i = buff.length()-1 ; i >=0 ; i--)
        {
            if  ( !isalnum ( buff[i] )  )
           {
           buff.erase( i,1 );
            }
        }

// get length of edited string
 int static SIZE = buff.length(); //strlen (buff);
cout << "the string length is " << SIZE << endl;

 // pick first perfect _square_ greater then the message length (ex:7x7)
int  squared = static_cast <int> ( ceil(sqrt( static_cast <double> ( SIZE ))));
cout << "size of board is " << squared << endl;
// allocate an array of char that size
char ** board;
board = new char *[squared];      // array of 'squared' char pointers
for ( i = 0 ; i < squared ; i++ )
    board[i] = new char[squared];

// read messsage into a square array of that size from left to right top to bottom
i = 0;
for ( int c = 0 ; c < squared  ; c++ )
    for ( int r = 0 ; r < squared ; r++ )
       board[r][c] = toupper(buff[i++]);

  // write the message out top to bottom, left to right and its been encyphered
 for ( int r = 0 ; r < squared  ; r++ ){
    for ( int c = 0 ; c < squared ; c++ ){
        cout << board[r][c];}
    cout << endl;
    }

   // delete array
    for ( i = 0 ; i < squared ; ++i )
     delete [] board[i] ;

    delete [] board;
} // end main

注意我改变输入法是为了得到一个完整的句子,而不是一个单词;我将所有字符转换为大写(非常罗马 - 这意味着在句子开头、名称等处没有关于字符的提示),仅在完整的输出行(而不是每一行)的末尾添加了一个回车符,以及之前发现的问题。

加密愉快! 哦 - 事后才想到。一旦您确认事情看起来不错(通过阅读列中的文本很容易做到),您将希望摆脱输出中的回车。它当然应该显示为没有这些中断的单行文本!

【讨论】:

  • 非常感谢!这是很好的建议。请注意,我已经切换了删除数组的顺序,但我相信您也会在代码中捕捉到这一点。
  • 非常感谢您的宝贵时间!
  • 不客气。您可以通过“接受”答案来表达您的感谢...(点击最能解决您问题的答案旁边的小复选标记)。
猜你喜欢
  • 2012-11-20
  • 2010-12-13
  • 2023-04-05
  • 2020-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-12
相关资源
最近更新 更多