【问题标题】:How to open and read a file based on user input c++如何根据用户输入c ++打开和读取文件
【发布时间】:2018-03-08 22:57:55
【问题描述】:

我有一个任务要我编写一个读取文本文件的程序,然后使用 Ceasar 密码版本输出该文件的修改版本,该版本根据移位量移动用户调用的文件的字符他们输入。例如,如果我的文件读取“hi”并且他们将其移动 1,则它应该读取“ij”。但是当我运行程序时,当我调用 in1 或 out1 时它无法识别,我只是收到一条错误消息。谁能帮我弄清楚我做错了什么或就如何前进提供任何建议?提前谢谢!

#include <iostream>
#include <iomanip>
#include <fstream>
#include <cctype>
using namespace std;

int main()
{
    //Declare user variables
    int shift, file1chars = 0;
    char filename[25];
    ifstream in1;
    ofstream out1;

    do
    {
        in1.clear(); //clear status flags

        //Prompt user to enter name of input file and amount of shift
        cout << "Please enter the name of the input file." << endl;
        cout << "Filename: ";
        cin >> filename;

        //Open file name
        in1.open(filename);

        //Error message if no file
        if (!in1)
            cout << "That is not a valid file. Try again\n";

    } while (!in1);

    do
    {
        out1.clear(); //clear status flags
        //prompt user to input out file     
        cout << "Please enter the name of the output file." << endl;
        cout << "Filename: ";
        cin >> filename;

        out1.open(filename);
        //Error message if no file
        if (!out1)
            cout << "That is not a valid file. Try again\n";
    } while (!out1);

    //write some code to the input file 
    in1 >> "hi"

    //write the integers in a different order to the output file
    out1 << //idk where to go from here to initiate shift 

    //prompt user to enter shift
            cout << "Please intput the shift amount: ";
    cin >> shift;
    cout << "Processing complete" << endl;

    //Call file (?)

    //Tell user file input is complete and is now printing statistics
    cout << "\nShifted input file Complete. Now printing statistics " << endl;

    //Show statistics for file
    cout << "\nStatistics for file: " << filename << endl;
    cout << "------------------------------------------------";

    //Show characters in file and stats before shift
    cout << "\n\nTotal # of characters in file: " << file1chars << endl;
    cout << "Statistics before shift: " << endl;

    //Show file before shift

    //Show user stats after shift
    cout << "\nStatistics after shift: " << endl;

    //File after shift

    //Close files
    out1.close();
    in1.close();
    return 0;
}

【问题讨论】:

  • 根据您使用的 C++ 版本,您可能需要使用in1.open(filename.c_str())
  • 你应该在完成后close流。在您打开的循环中,使用相同的输出流打开多个文件而不关闭它。
  • 请尝试修正您的格式 - 您的缩进有点失控。
  • @ThomasMatthews:fstream 类重载了新版本的open 以将class std::string 作为其参数,而不是指向字符串的常量指针。
  • in1 &gt;&gt; "hi" 尝试从文件中读取数据并将其存储到常量字符数组中。因为数组是常量,所以这不起作用。我怀疑你不想这样做。我可以建议阅读 `std::string` 吗?

标签: c++ file input fstream caesar-cipher


【解决方案1】:

与其逐行查看您的代码以了解问题可能出在哪里,我请您考虑您的需求并编写尽可能接近表达意图的代码。创建符合预期功能的函数。

  1. 获取输入文件名。
  2. 获取输出文件名。
  3. 读取输入文件的内容。
  4. 转换输入文件的内容以创建输出字符串。
  5. 将输出字符串写入输出文件。

在伪代码中,

int main()
{
    infile = get_input_filename()
    outfile = get_output_filename()
    contents = get_file_contents(infile)
    output = transform_input(contents)
    write_output(outfile, output)
}

将其转换为 C++ 代码:

// Declare the functions.

std::string get_input_filename();
std::string get_output_filename();
std::string get_file_contents(std::string const& infile)
std::string transform_input(std::string const& contents)j
void write_output(std::string const& outfile, std::string const& output);

// Use them in main.

int main()
{
    std::string infile = get_input_filename();
    std::string outfile = get_output_filename();
    std::string contents = get_file_contents(infile);
    std::string output = transform_input(contents);
    write_output(outfile, output);
}

// Implement the functions.

std::string get_input_filename()
{
    std::string filename;
    cout << "Please enter the name of the input file." << endl;
    cout << "Filename: ";
    cin >> filename;
    return filename;
}

std::string get_output_filename()
{
    std::string filename;
    cout << "Please enter the name of the output file." << endl;
    cout << "Filename: ";
    cin >> filename;
    return filename;
}

std::string get_file_contents(std::string const& infile)
{
   std::ifstream inf(infile);
   std::string contents;
   int c;
   while ( (c = inf.get()) != EOF )
   {
      contents += c;
   }
   return contents;
}

std::string transform_input(std::string const& contents)
{
   std::string res;
   // Do the needful to transform contents to res.
   return res;
}

void write_output(std::string const& outfile, std::string const& output)
{
   std::ofstream outf(outfile);
   outf.write(output.c_str(), output.size();
}

【讨论】:

    【解决方案2】:

    如果您能够使用类或结构和函数,我会提出这样的建议:

    ma​​in.cpp

    #include <string>
    #include <iostream>
    #include <fstream>
    #include "CaesarShift.h"
    
    int main() {
        std::string filename;
        std::cout << "Please enter the name of the input file. ";
        std::cin >> filename;
    
        std::ifstream fileIn;
        std::string   text;
    
        fileIn.open( filename );
        if ( !fileIn.is_open() ) {
            std::cout << "Failed to open file: " << filename << "." << std::endl;
        }
    
        fileIn >> text;
        fileIn.close();
    
        CaesarText caesarText;
        caesarText.addText( text );    
    
        std::cout << "Contents of the Caesar Text before peforming a Caesar Shift:\n"
            << caesarText << std::endl;
    
        int amount = 0;
        std::cout << "Please enter the amount to shift the text ";
        std::cin >> amount;
        std::cout << "Now performing the Caesar Shift: " << std::endl;
    
        caesarShift( caesarText, amount );
    
        std::cout << "Caesar Text after performing a Caesar Shift:\n"
            << ceasarText << std::endl;
    
        std::ofstream fileOut;
        fileOut.open( std::string( "shifted_" + filename ) );
        if ( !fileOut.is_open() ) {
            std::cout << "Failed to open shifted_" << filename << std::endl;
        }
        // Uncomment to print original text to file otherwise only modified text will be printed.
        // fileOut << caesarText.originalText() << std::endl;
        fileOut << caesarText.shiftedText() << std::endl;
        fileOut.close();
    
        system( "PAUSE" );
        return 0;
    }
    

    CaesarShift.h

    #ifndef CAESAR_SHIFT_H
    #define CAESAR_SHIFT_H  
    
    class CaesarText {
        std::string _originalText;
        std::string _shiftedText;
    
    public:
        caesarText() = default;
        explicit CeasarText( const std::string& text ) :
            _originalText( text ) {}
    
        void addText( const std::string& text ) {
            _originalText = text;
        }
    
        std::string originalText() const {
            return _originalText;
        }
    
        std::string shiftedText() const {
            return _shiftedText;
        }
    
        friend void caesarShift( caesarText& c, int amount );    
        friend std::ostream& operator<<( std::ostream& out, const caesarText& ceasarText );
    };
    
    #endif // !CAESAR_SHIFT_H
    

    CaesarShift.cpp

    #include "CaesarShift.h"
    
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    // Overloaded ostream operator
    std::ostream& operator<<( std::ostream& o, const CaesarText& c ) {
        o << "Original Text: " << c._originalText << "\n";
        o << "Shifted Text: " << c._shiftedText << "\n";
        return o;
    }
    
    // public friend function (visible in main) not actually a part of the class
    // but performs operations on it.
    // To perform the Caesar Shift here are 3 possible variations of implementing the same task.
    void caesarShift( Caesar Text& text, int amount ) {
        // Bound amount to the number of characters in the alphabet 
        // the same value used in any of the three variations below.
        amount %= 26;
    
        // Older c++ style loop.
        /*for ( std::size_t i = 0; i < text._originalText.length(); i++ ) {
            char c = text._originalText[i] + amount;
            text._shiftedText += c;
        }*/
    
        // Modern C++ style loop
        /*for ( auto& c : text._originalText ) {
            text._shiftedText += c + amount;
        }*/
    
        // std::transform( s1.begin, s1.end, back_inserter( s2 ), lamda as predicate );
        /*std::transform( text._originalText.begin(), text._originalText.end(),
                    std::back_inserter( text._shiftedText ),
                    [amount]( unsigned char c ) -> unsigned char { return c + amount; }
        );*/    
    }
    

    至于执行 Caesar Shift 的 3 种不同变体,您只需取消注释相应的块部分即可。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-10-29
      • 2021-09-06
      • 1970-01-01
      • 1970-01-01
      • 2021-12-29
      • 1970-01-01
      • 2019-07-17
      相关资源
      最近更新 更多