【问题标题】:How do you get a file in C++?如何在 C++ 中获取文件?
【发布时间】:2009-03-07 06:28:37
【问题描述】:

所以老师提出了这个作业:

您已受雇于执法联合网络司令部,并且您已获得包含必须解密的空密码的文件。

所以对于给定的第一个文件(例如),其他每个字母都是正确的(即:'hielqlpo' 是你好(假设你从第一个字母开始)。我的第一个问题是,我如何读取文件? 该文档位于我桌面上的一个文件夹中,该文件名为 document01.cry。我不确定将该文件放入程序所需的命令。

我也不太清楚如何抓住一封信和跳过一封信,但老实说,我想在发布这个问题之前先修改一下!所以现在......我的问题如标题中所述:如何获取文件以在 C++ 中读取?

如果它有所作为(我确信确实如此),我正在使用 Visual C++ 2008 Express Edition(因为它是免费的,我喜欢它!我还附上了我目前拥有的东西,请继续关注请注意它 - 非常 - 基本......我在最后添加了getchar();,所以当它正常运行时,窗口保持打开状态,所以我可以看到它(因为 Visual Express 往往会在它完成运行后立即关闭窗口.)

到目前为止的代码:

#include<iostream>

using namespace std;

int main()
{
    while (! cin.eof())
    {
        int c = cin.get() ;
        cout.put(c) ;
    }
    getchar();
}

PS:我意识到这段代码会抓取并输出每个字符。现在这很好,一旦我可以读取文件,我想我可以从那里修改它。我还在戳一两本关于 C++ 的书,看到它弹出并尖叫着“选我!”再次感谢!

EDIT:: 也很好奇,有没有办法输入你想要的文件? (即:

char filename;
cout << "Please make sure the document is in the same file as the program, thank you!" << endl << "Please input document name: " ;
cin >> filename;
cout << endl;
ifstream infile(filename, ios::in);

此代码不起作用。它返回一个错误,说 char 不能转换为 const char *。如何解决这个问题?

编辑 2: 没关系说第2部分,我发现了!再次感谢您的帮助!

【问题讨论】:

    标签: c++ file io


    【解决方案1】:

    要进行文件操作,你需要正确的包含:

    #include <fstream>
    

    然后,在你的 main 函数中,你可以打开一个文件流:

    ifstream inFile( "filename.txt", ios::in );
    

    或者,对于输出:

    ofstream outFile( "filename.txt", ios::out );
    

    然后,您可以像使用 cin 一样使用 inFile,也可以像使用 cout 一样使用 outFile。完成后关闭文件:

    inFile.close();
    outFile.close();
    

    【讨论】:

    • 非常感谢! Niyaz 发布的网站也向我展示了,但是,如果文件位于文件夹中(即:C:\Documents and Settings\J\Desktop\College work\CSIS 296\asst4\Documents)怎么办?当然,我是在测试之前询问的,但是我一点击“添加评论”就在测试!
    • 发现如果您使用“filename.txt”,如果它与程序的 .cpp 文件位于同一文件夹中,则它可以工作......但如果它位于不同的文件中怎么办?万一我上面说的有点混乱
    • 您总是可以将文件名作为参数传递给程序 foobar.exe c:\myFile.txt 然后检查该参数以确定要打开的文件
    • 恐怕我不明白你的意思,你能再解释一下吗?
    • main(char*, int) 函数有两个参数,一个字符串列表和传递的字符串数。从命令提示符运行 exe 时,您可以像这样传递这些参数: foobar.exe c:\a.txt (如果它在不同的目录中,则带有完整路径)。从您的代码中打开此文件。
    【解决方案2】:

    [EDIT] 包括对命令行参数的支持 [编辑] 修复了可能的内存泄漏 [编辑] 修正了一个缺失的参考

    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char *argv){
        ifstream infh;  // our file stream
        char *buffer;
    
        for(int c = 1; c < argc; c++){
            infh.open(argv[c]);
    
            //Error out if the file is not open
            if(!infh){
                cerr << "Could not open file: "<< argv[c] << endl;
                continue;
            }
    
            //Get the length of the file 
            infh.seekg(0, ios::end);
            int length = infh.tellg();
    
            //reset the file pointer to the beginning
            is.seekg(0, ios::beg);
    
            //Create our buffer
            buffer = new char[length];
    
            // Read the entire file into the buffer
            infd.read(buffer, length);
    
            //Cycle through the buffer, outputting every other char
            for(int i=0; i < length; i+= 2){
                cout << buffer[i]; 
            }
            infh.close();
        }
        //Clean up
        delete[] buffer;
        return 0;
    }
    

    应该做的伎俩。如果文件非常大,您可能不应该将整个文件加载到缓冲区中。

    【讨论】:

    • 看起来棒极了!谢谢! :D 但这仍然依赖于文件在同一目录中,如果文件在另一个目录中怎么办?
    • 现在我们支持命令行参数和读取多个文件。如 foobar.exe myfile.txt myfile1.txt myfile2.txt
    • 我认为,虽然确实很棒,但这可能超出了我迄今为止在课堂上学到的知识。我这么说是因为虽然它确实看起来很棒而且我可以(有点)弄清楚它的过程,但我不太了解它。我不太确定从哪里开始指出我缺乏理解..
    • 我确实了解 infh.seekg (查找文件的长度,从第 0 个位置开始,直到文件末尾 (ios::end)),但类似buffer = new char[length] 或在主括号中使用 argc 和 *argc...是的,可悲的是。
    • delete[] 缓冲区应该在外部 for 循环内。
    【解决方案3】:

    虽然您的问题已得到解答,但有两个小提示: 1) 除了计算 x 和 y 来查看您是在奇数还是偶数字符上,您还可以执行以下操作:

    int count=0;
    while(!infile.eof())
    {       
        infile.get(letter);
        count++;
        if(count%2==0)
        {
            cout<<letter;
        }
    }
    

    % 本质上是指“除以余数”,所以 11%3 是二。在上面它给出奇数或偶数。

    2) 假设你只需要在 windows 上运行它:

    system("pause");
    

    将在窗口完成运行后保持打开状态,因此您不需要最后一次 getchar() 调用(您可能需要#include&lt;Windows.h&gt; 才能工作)。

    【讨论】:

    • 那个系统暂停命令很棒,但遗憾的是,虽然我可能正在使用 Visual C++ express,但老师正在使用 buffy(或者不管他怎么称呼它,无论如何它都是某种形式的 linux),所以我不认为我可以在程序中使用任何真正基于窗口的东西。
    • 但是,余数 2 的东西非常简洁,我会记住这一点!我一直在调整程序,在这一点上我已经设置了你可以在不重新编译的情况下执行多个文件的位置,现在正在努力让它不仅解密,而且加密,我认为这将是棘手的部分!跨度>
    • 啊哈,只是随便想了一下,我认为其余的都行不通。虽然我的示例显示了所有其他字符,但这只是一个部分,它必须能够适用于不同的数字(即每 537 个字母很好),当前设置允许我进行调整,我认为没有,或者没有是吗?
    • 是的,如果你想要每 537 个字母,你会想要 if(count%537==0){cout
    【解决方案4】:

    我想通了!老实说,没有一个答案有帮助,这是三者的结合,再加上他们的 cmets。非常感谢大家!我附上了我使用的代码以及文档的副本。程序读入每个字符,然后吐出解密的文本。 (IE:1h.e0l/lqo 是你好)下一步(额外的功劳)是设置它,以便用户在读取下一个要输入的字符之前输入要跳过的字符数。

    这一步我打算自己做,但再次感谢大家的帮助!再次证明这个网站有多棒,一行代码!

    EDIT:: 代码调整为接受用户输入,并允许在不重新编译的情况下多次使用(我意识到它看起来像一个巨大的草率的混乱,但这就是为什么它被极度评论......因为在我看来它看起来不错而且整洁)

    #include<iostream>
    #include<fstream>   //used for reading/writing to files, ifstream could have been used, but used fstream for that 'just in case' feeling.
    #include<string>    //needed for the filename.
    #include<stdio.h>   //for goto statement
    
    using namespace std;
    
    int main()
    {
        program:
        char choice;  //lets user choose whether to do another document or not.
        char letter;  //used to track each character in the document.
        int x = 1;    //first counter for tracking correct letter.
        int y = 1;    //second counter (1 is used instead of 0 for ease of reading, 1 being the "first character").
        int z;        //third counter (used as a check to see if the first two counters are equal).
        string filename;    //allows for user to input the filename they wish to use.
        cout << "Please make sure the document is in the same file as the program, thank you!" << endl << "Please input document name: " ;
        cin >> filename; //getline(cin, filename);
        cout << endl;
        cout << "'Every nth character is good', what number is n?: ";
        cin >> z;   //user inputs the number at which the character is good. IE: every 5th character is good, they would input 5.
        cout << endl;
        z = z - 1;  //by subtracting 1, you now have the number of characters you will be skipping, the one after those is the letter you want.
        ifstream infile(filename.c_str()); //gets the filename provided, see below for incorrect input.
        if(infile.is_open()) //checks to see if the file is opened.
        {
            while(!infile.eof())    //continues looping until the end of the file.
            {   
                    infile.get(letter);  //gets the letters in the order that that they are in the file.
                    if (x == y)          //checks to see if the counters match...
                    {
                        x++;             //...if they do, adds 1 to the x counter.
                    }
                    else
                    {
                        if((x - y) == z)            //for every nth character that is good, x - y = nth - 1.
                        {
                            cout << letter;         //...if they don't, that means that character is one you want, so it prints that character.
                            y = x;                  //sets both counters equal to restart the process of counting.
                        }
                        else                        //only used when more than every other letter is garbage, continues adding 1 to the first
                        {                           //counter until the first and second counters are equal.
                            x++;
                        }
                    }
            }
            cout << endl << "Decryption complete...if unreadable, please check to see if your input key was correct then try again." << endl;
            infile.close();
            cout << "Do you wish to try again? Please press y then enter if yes (case senstive).";
            cin >> choice;
            if(choice == 'y')
            {
                goto program;
            }
        }
        else  //this prints out and program is skipped in case an incorrect file name is used.
        {
            cout << "Unable to open file, please make sure the filename is correct and that you typed in the extension" << endl;
            cout << "IE:" << "     filename.txt" << endl;
            cout << "You input: " << filename << endl;
            cout << "Do you wish to try again? Please press y then enter if yes (case senstive)." ;
            cin >> choice;
            if(choice == 'y')
            {
                goto program;
            }
        }
        getchar();  //because I use visual C++ express.
    }
    

    编辑:::

    我尝试插入文本,但无法正确显示,它一直在处理某些字符,例如编码(即撇号显然相当于粗体命令),但您可以尝试输入在没有括号的“0h1e.l9lao”中放入.txt,它应该给出相同的结果。

    再次感谢大家的帮助!

    【讨论】:

    • 我建议在没有“goto”语句的情况下执行此操作。几乎从不需要使用“goto”,这会使程序更难阅读、调试和维护。弄清楚如何在这里使用另一个循环而不是 goto 是一个很好的练习。 (您可能需要使用“break”或“continue”关键字)
    • 我在发布几小时后决定不使用 goto 语句,改为使用 while 循环,没有它看起来更干净,谢谢你的提示!
    • 从 istream 读取时,切勿使用“!eof”作为循环的条件,因为如果发生错误,可能永远无法达到 eof,从而使您的程序陷入无限循环。此外,应该在输入操作之后和使用其结果之前检查流的状态。对于您的程序,这意味着应将 while(!infile.eof()){ infile.get(letter);... 替换为 while(infile.get(letter)){...
    猜你喜欢
    • 2010-11-25
    • 2021-08-17
    • 2011-07-07
    • 2020-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多