2013-08-01 7 views
0

Проблема в том, что файл не будет читаться ... По-видимому, есть проблема с массивом, но я действительно не знаю, как исправить эту проблему ... Я начинаю с C++ ' массивы и „строки“ ...Хранение переменной в 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; 
} 
+7

«По-видимому, есть проблема с массивом, но я действительно не знаю, как исправить эту проблему ...» Если вы получаете сообщения об ошибках, вы должны предоставить их нам для просмотра. –

+1

Вы передаете одиночный символ 'strlen', который ожидает тип' const char * '. Зачем вообще называть strlen? char всегда будет 1. – greatwolf

+1

Что вы ожидаете 'char cipher [sizeof (character)];' делать точно? – greatwolf

ответ

0

Глядя на ваш код, «символ» объявлен как char, который означает, что он может хранить только один байт информации. Но позже вы начнете использовать его, как если бы это был массив символов.

Вы также объявляете «шифр» как массив символов, который вы управляете вручную, как строка, подверженная ошибкам. Однако реальная проблема заключается в том, что вы смешиваете 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 для удобства чтения.Также в моем примере сдвиг выполняется случайным образом для прототипирования, но вы должны изменить его, чтобы вместо этого использовать его как пользовательский ввод.

+0

В вашем коде есть ошибка, при которой 'cipher' не объявляется ... Вы объявляете 'cipher' как 'array' или 'string' ??? – Cris

+0

@ user2066703 похоже, что я пропустил копию и вставлю. упс! теперь исправлено – greatwolf

+0

эй спасибо за помощь ... Я только начинаю на C++, поэтому я действительно не знаю, что разница между C и C++ – Cris

0

Вы работаете с одним полукокса, например, только одна буква или номер. Так что все дело с обработкой размера бесполезно, потому что размер всегда равен 1. Вам, вероятно, следует использовать const char *. Но тогда вы не можете использовать filestream.get() вообще, потому что он возвращает только один символ (not и cstring aka 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++ использование станд :: вектор или станд :: список или ... один из других контейнеров STL, так что вам не придется тратить свое время управления памятью и использование массивов статического размера. И std :: string - путь для строк в C++. Это нечто похожее на контейнеры STL, но только для char.

+0

, так как я могу исправить эту проблему, и это то, что я пытаюсь понять ... Я имею в виду, что вы говорите, чтобы удалить одну часть, чтобы другая работала ... но как я могу удалить filestream.get()? – Cris

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); 
} 
+0

... В компиляции есть ошибка в коде ... – Cris

+0

Можете ли вы рассказать мне, как и почему вы использовали «catch» и «throw» – Cris

+0

'final.cpp: 42: 15: error:' character 'не называет Тип» 'final.cpp: 47: 5: ошибка: ожидается ';' перед ''' станд 'final.cpp: 48: 3: ошибка: ожидается, первичное выражение, прежде чем '}' маркер' 'final.cpp: 48: 3: ошибка: ожидается, 'маркер} ')' перед '}' маркер' «ожидать первичного выражение до final.cpp: 48: 3:: ошибка' ' final.cpp: 48: 3: ошибка: ожидается „;“ перед „}“ маркер – Cris