问题是文件无法读取...显然数组存在问题,但我真的不知道如何解决这个问题...我是C ++'数组'和'字符串的初学者” ...
我的文件应该读取代码,然后翻译文件,然后将文本输出到新文件中。
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <fstream>
#include <math.h>
#include <stdio.h>
#include <string>
#include <string.h>
using namespace std;
int main()
{
// Declarations
string reply;
string inputFileName;
ifstream inputFile;
ofstream outFile;
char character;
cout << "Input file name: ";
getline(cin, inputFileName);
// Open the input file.
inputFile.open(inputFileName.c_str());
// Check the file opened successfully.
if ( ! inputFile.is_open()) {
cout << "Unable to open input file." << endl;
cout << "Press enter to continue...";
getline(cin, reply);
return 1;
}
// This section reads and echo's the file one character (byte) at a time.
while (inputFile.peek() != EOF) {
inputFile.get(character);
//cout << character;
//Don't display the file...
char cipher[sizeof(character)];
//Caesar Cipher code...
int shift;
do {
cout << "enter a value between 1-26 to encrypt the text: ";
cin >> shift;
}
while ((shift <1) || (shift >26));
int size = strlen(character);
int i=0;
for(i=0; i<size; i++)
{
cipher[i] = character[i];
if (islower(cipher[i])) {
cipher[i] = (cipher[i]-'a'+shift)%26+'a';
}
else if (isupper(cipher[i])) {
cipher[i] = (cipher[i]-'A'+shift)%26+'A';
}
}
cipher[size] = '\0';
cout << cipher << endl;
}
cout << "\nEnd of file reached\n" << endl;
// Close the input file stream
inputFile.close();
cout << "Press enter to continue...";
getline(cin, reply);
return 0;
}
答案 0 :(得分:2)
简而言之:你使用的是c ++,所以不要使用整个C语言。
std::string
islower(char)
,而是使用std::islower(char,locale)
std::array
(编译时常量)或std::vector
(动态大小)你想要更像这样:
#include <string>
#include <fstream>
#include <iostream>
#include <stdexcept>
#include <locale>
int main (void)
{
std::string input_filename;
std::cout << "Input file name: ";
std::getline(std::cin, input_filename);
unsigned int shift;
do
{
std::cout << "Enter a value between 1-26 to encrypt the text: ";
std::cin >> shift;
}
while ((shift == 0) || (shift > 26));
try
{
std::string filestring;
std::ifstream input(input_filename, std::ios_base::in);
if (input)
{
input.seekg(0, std::ios::end);
filestring.reserve(input.tellg());
input.seekg(0, std::ios::beg);
filestring.assign
(std::istreambuf_iterator<char>(input),
std::istreambuf_iterator<char>());
}
else
{
std::string error_string("Reading failed for: \"");
error_string.append(input_filename);
error_string.append("\"");
throw std::runtime_error(error_string);
}
std::string result;
result.reserve(filestring.size());
std::locale const loc;
for (auto character : filestring)
{
char const shifter(std::islower(character, loc) ? 'a' : 'A');
result.push_back((character-shifter+shift)%26+shifter);
}
std::cout << result << std::endl;
}
catch (std::exception & e)
{
std::cout << "Execution failed with an exception: " << std::endl;
std::cout << e.what() << std::endl;
}
}
此解决方案需要C ++ 11支持。如果您没有C ++ 11,可以用以下代码替换循环:
size_t const N(filestring.length());
for (size_t i(0u); i<N; ++i)
{
char const shifter(std::islower(filestring[i], loc) ? 'a' : 'A');
result.push_back((filestring[i]-shifter+shift)%26+shifter);
}
答案 1 :(得分:0)
您正在使用单个字符,例如只需一个字母或数字。所以大小处理的全部内容都是无用的,因为大小总是1.你可能应该使用const char *。但是你根本不能使用filestream.get(),因为它只返回一个char(而不是cstring又名const char *)。 并且您可以使用fstream.get()作为循环的条件,因此您不需要请求eof标志。
char my_char;
std::ifstream infstream("filename.txt");
if(!infstream.isopen())
return -1;
while(infstream.get(my_char) {
//do some stuff
}
或
std::string my_string;
std::ifstream infstream("filename.txt");
if(!infstream.isopen())
return -1;
while(infstream >> my_string) {
//do some stuff
}
对于C ++中的动态数组,使用std :: vector或std :: list或...其他STL容器之一,因此您不必浪费时间在内存管理和使用静态大小的数组上。 而std :: string是在C ++中使用字符串的方法。它类似于STL容器,但仅限于char。
答案 2 :(得分:0)
从查看代码开始,“character”被声明为char
,这意味着它只能存储一个字节的信息。然后你就开始使用它,好像它是一个字符数组。
您还将“cipher”声明为您手动管理的字符数组,就像一个容易出错的字符串。然而,真正的问题是你在C ++中混合了类似C的代码。换句话说,编写代码的方式不被认为是惯用的C ++。
Pixelchemist已经超越了重点,所以我将只提供上述代码的最小重构工作示例:
#include <iostream>
#include <string>
#include <fstream>
#include <stdlib.h>
using namespace std;
int main()
{
string filename;
cout << "enter input file: ";
cin >> filename;
ifstream inputFile( filename.c_str() );
string plaintext;
do
{
plaintext += inputFile.get();
}while(inputFile);
cout << plaintext << endl;
string &ciphertext = plaintext;
//Caesar Cipher code...
int shift = rand() % 26 + 1;
for(size_t i = 0; i < ciphertext.size(); ++i)
{
if (islower(ciphertext[i])) {
ciphertext[i] = (ciphertext[i] - 'a' + shift) % 26 + 'a';
}
else if (isupper(ciphertext[i])) {
ciphertext[i] = (ciphertext[i] - 'A' + shift) % 26 + 'A';
}
}
cout << ciphertext << endl;
}
您会在重构中注意到我完全取消了char
和char[]
数组,并将其替换为std::string
。我也在明文输入上执行密码操作。这是通过为plaintext
ciphertext
提供引用别名来实现的,以提高可读性。同样在我的示例中,移位是随机进行的原型设计,但您应该将其更改为将其作为用户输入。