2

I'm trying to open a C++ .txt file as shown in my code below. This is part of a larger program that I'm working on where I write the contents of one file into another so that it contains the same information as the original but I am required to provide user-input. If the user-provides a .txt file that is not the one we are using, I have to produce an error message and prompt them to re-enter an input until they input the correct one (test.txt):

#include <iostream>
#include <fstream>
#include <string>

using namespace std; 

int main()
{
  /* Refers to test.txt */
  ofstream mainfile; 
  std::string filename; 

  std::cout << "Please enter the name of your data file: ";
  std::cin >> filename; 

  mainfile.open(filename.c_str());
  mainfile << "test.txt"; 
  if(!mainfile) {
    std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl; 
    std::cout << "Please enter another name: " << 
      std::endl;
    std::cin >> filename;
  } else {
    std::cout << "File '" << filename << "' opened successfully!" << std::endl;
  }

  return 0; 
}

My current issue is that the program is terminating too early, even when I input incorrect inputs such as jaguar.txt or flowers.txt, anything that isn't "test.txt". In fact, when I input just about any .txt file name it will output saying that it opened successfully.

joemamah24
  • 35
  • 5
  • 3
    What does "o" in `ofstream` mean? Why do you expect `ofstream` not to be opened for `jaguar.txt` filename? – Evg Feb 16 '23 at 19:25
  • Also, converting `filename` to a C-string is no longer necessary. And then there's the using of the file stream *before* the validation of the stream. – sweenish Feb 16 '23 at 19:26
  • 2
    This code is so confused that I'm not sure what you are trying to do. First things first, are you trying to open the file for input or output? – john Feb 16 '23 at 19:27
  • @Evg Sorry, but this is part of a bigger program that I'm working on and I'm writing or copying the contents of one file to another. That's why I'm using ofstream. Don't know if that's what you meant? But it means output, no? – joemamah24 Feb 16 '23 at 19:27
  • 1
    Yes, that's correct. Why shouldn't you be able to output some data into `jaguar.txt`? (I'm trying to give you a hint instead of a direct answer.) – Evg Feb 16 '23 at 19:28
  • @Evg because it doesn't exist? Or is it because I haven't properly declared that "test.txt" will be the main file that I copy the information from? – joemamah24 Feb 16 '23 at 19:30
  • @joemamah24 Why is "jaguars.txt" incorrect input? Seems like a reasonable file name to me/ – john Feb 16 '23 at 19:30
  • 1
    @joemamah24 When you open a file for **output** (like you do in the code above) it does not have to exist, it will be created if it does not exist. – john Feb 16 '23 at 19:31
  • @john because the file I am copying information from is called "test.txt". I want to be able to open the correct .txt file which is test.txt. Don't know if I'm being clear. Sorry if not. – joemamah24 Feb 16 '23 at 19:31
  • @joemamah24 If you are trying to open a file for **input** then why are you using `ofstream`, which is for **output**. – john Feb 16 '23 at 19:32
  • @joemamah24 And if you are trying to open a file called "test.txt" then that is the string that needs to be passed to `open`. I.e. `file.open("test.txt")` – john Feb 16 '23 at 19:33
  • @john it is for output. I'm trying to copy the contents of test.txt into another file. – joemamah24 Feb 16 '23 at 19:33
  • @joemamah24 So if you are trying to open a file for output, why do you consider the name of a file that does not exist to be an error? That is only an error when you try to open a file for input. – john Feb 16 '23 at 19:34
  • @joemamah24 Maybe describe what you really want to do in your question. You can [edit] it to clarify. I think it's better to ask "I want to do X; how to fix my code?" and not "my code does the wrong thing; what to do?". That X is the most important part; you should state it explicitly. – anatolyg Feb 16 '23 at 19:34
  • 1
    @joemamah24: If you want to copy the contents of `test.txt` into "another file", then you should open the file `test.txt` for **input** and open "another file" for **output**. – Andreas Wenzel Feb 16 '23 at 19:36
  • 2
    @joemamah24 Plus (in case it's not clear) `mainfile << "test.txt"` is not going to copy any file anywhere. All it does is write a **file name** to another file. – john Feb 16 '23 at 19:36
  • @joemamah24 I think it's fairly clear that you are confused. My suggestion is that you start practising your file handling skills with some simpler programs. When you've got the basics you can come back and try this task. – john Feb 16 '23 at 19:40
  • @joemamah24 If I'm understanding correctly your task is to ask the user for a file name until they enter the right one which is "test.txt". If the only correct input is "test.txt" then why ask the user at all? This makes no sense, are you sure you've understood the requirements? – john Feb 16 '23 at 19:46
  • Upvote for providing a minimal reproducible example. – Jesper Juhl Feb 16 '23 at 20:02

2 Answers2

2

It seems that what you want to do is open up 2 different files, where one is used as the file to copy from (test.txt), and the other is the file to copy to (jaguar.txt). Instead of checking if test.txt exists with std::ofstream, you should instead use std::ifstream.

Using ifstream, if the file does not exist, your code will work properly. Instead, because you are currently using ofstream, the file will open correctly, because you're essentially telling it to make the file for you.

So basically, where you have used ofstream mainfile, instead it should be:

ifstream mainfile;

Later in the code, you can prompt the user for the file to copy to (i.e. jaguar.txt), and this will be the one where you output data using ofstream.

JMVR
  • 21
  • 1
1

Use ifstream to read from a file, and ofstream to write to a file.

To check whether the source file exists, test the corresponding ifstream after trying to open it:

  ifstream mainfile; // ifstream stands for "input file stream"
  std::cout << "Please enter the name of your data file: ";
  std::cin >> filename;
  mainfile.open(filename);
  while (!mainfile) { // asking endlessly, until the user inputs a good file
    std::cout << "I'm sorry, I could not open '" << filename << "'." << std::endl;
    std::cout << "Please enter another name: " << 
      std::endl;
    std::cin >> filename;
    mainfile.open(filename);
  }
  std::cout << "File '" << filename << "' opened successfully!" << std::endl;

By the way, in the error message "open" is programmer's jargon. It's a general word which includes both reading and writing. If your application copies stuff from one file to the other, the user may get confused: is there a problem with input or output? You might want to say "read" instead of "open", even though technically you didn't read anything yet. That would make a clearer error message.


If you want to copy one file to another, use one of the methods described in a dedicated question.

anatolyg
  • 26,506
  • 9
  • 60
  • 134