在C ++中存储变量

时间:2013-08-01 20:33:09

标签: c++ arrays sorting file-io encryption

问题是文件无法读取...显然数组存在问题,但我真的不知道如何解决这个问题...我是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;   
}

3 个答案:

答案 0 :(得分:2)

简而言之:你使用的是c ++,所以不要使用整个C语言。

  • 请勿使用字符数组,请使用std::string
  • 请勿使用islower(char),而是使用std::islower(char,locale)
  • 不要使用C风格的数组,而是使用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;
}

您会在重构中注意到我完全取消了charchar[]数组,并将其替换为std::string。我也在明文输入上执行密码操作。这是通过为plaintext ciphertext提供引用别名来实现的,以提高可读性。同样在我的示例中,移位是随机进行的原型设计,但您应该将其更改为将其作为用户输入。