我的任务是编写一个程序,读取标准输入,存储文本直到遇到EOF,然后使用凯撒分组密码对文本进行加密。
解决方案的步骤:
- 所以:读取你的消息到一个大的缓冲区或字符串对象。
- 删除空格和标点符号或不删除
- 然后计算消息中的字符数。
- 选择第一个大于消息长度的完全平方,分配一个char大小的数组。
- 将消息读入正方形数组的大小从左到右,从上到下。
- 从上到下,从左到右,你已经加密了。
这是我到目前为止所拥有的…它编译,但不做任何事情。我知道我一定错过了什么。任何帮助都将非常感激。
#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
我试着编译你的代码并运行它-发现了一些问题。
1)你的"erase"循环进入无限循环。从数组的开头开始,循环遍历所有元素,在遍历过程中删除元素,并期望最后一切正常,这通常是非常糟糕的做法。从末尾开始并向后工作要安全得多:
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
注:我改变了输入法,以获得一个完整的句子,而不仅仅是一个单词;我将所有字符转换为大写(非常罗马-这意味着在句子开头,名称等处没有字符提示),仅在完整输出行(而不是每行)的末尾添加了一个回车符,以及前面发现的问题。
加密快乐!哦,再补充一下。一旦确认一切正常,您将希望删除输出中的回车(通过阅读列中的文本很容易做到)。当然,它应该显示为单行文本,没有这些中断!
这很奇怪
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++ )
你在几行之后得到了正确的,所以不确定为什么这里是错误的。