-3
 cout<<"enter name of file : " <<endl;
    char nof[30] ;
    for (int i=0;i<20;++i){
            cin>>nof[i];
        if (nof[i-1]=='x'){
            if (nof[i]=='t'){
               break;
            }
        }
    }
    fstream file1;
    file1.open(nof);
    if (file1.is_open()) cout<<"file is open"<<endl;

that is a code which should take the name of file from user to create but i checked if it is opened and it is not , what to do ?

  • 1
    You need to provide an MCVE. You will find instructions in the site documentation. – Ulrich Eckhardt Mar 24 '18 at 07:37
  • Compile with all warnings and debug info: `g++ -Wall -Wextra -g` with [GCC](http://gcc.gnu.org/). Read documentation, notably of [std::fstream](http://en.cppreference.com/w/cpp/io/basic_fstream). `open` can fail for several reasons (perhaps operating system specific; for Linux see errors in the underlying [open(2)](http://man7.org/linux/man-pages/man2/open.2.html) system call...). [Use the `gdb` debugger](https://sourceware.org/gdb/current/onlinedocs/gdb/). – Basile Starynkevitch Mar 24 '18 at 07:39
  • Your code to read input from `cin` is pretty fragile: there are ways it might do something you don't expect. I suggest you add a line `std::cout << "read filename '" << nof << "'\n"; before you try to open the file, so you can see what filename it's trying to read. If the filename doesn't have an absolute path, you may also want to output your current working directory to make sure your program is running where you expect, particularly if you're starting it from an IDE. – Tony Delroy Mar 24 '18 at 07:51

3 Answers3

1

Try using this:

#include <string>
#include <iostream>
#include <errno.h>
#include <fstream>
#include <cstring>

using namespace std;

int main() {
    cout << "Enter the name of the file : ";
    string file_name;
    getline(cin, file_name);

    fstream file_stream;
    file_stream.open(file_name);

    if (file_stream.is_open()) {
        // File Stuffs goes here...........
        cout << "The file is open" << endl;
    } else {
        // The file may not exists or locked by some other process.
        cout << strerror(errno) << endl; // Edited this line.
    }
}
Mohit
  • 1,225
  • 11
  • 28
  • That does not answer the question of *why* `file_stream.open` failed (could be a permission issue, a missing file, out of resources, etc...). But it does detect the failure. – Basile Starynkevitch Mar 24 '18 at 07:42
  • @BasileStarynkevitch It is difficult to say why `file_stream.open` failed, the file may not exist or it may have been locked by some other process. – Mohit Mar 24 '18 at 07:45
  • On Linux and POSIX, you might use [errno(3)](http://man7.org/linux/man-pages/man3/errno.3.html) after failure of `std::fstream::open` -which will use [open(2)](http://man7.org/linux/man-pages/man2/open.2.html)- and that gives a failure reason. AFAIK, there is no standard C++14 way of getting such a reason. – Basile Starynkevitch Mar 24 '18 at 07:47
  • @BasileStarynkevitch Thanks, I have edited the lines. `errno` also exist in windows. – Mohit Mar 24 '18 at 07:51
  • But I think that `errno` is not *officially* related to `std::fstream::open` (even if in practice it is) – Basile Starynkevitch Mar 24 '18 at 07:54
  • 2
    There are other potential issues where - for example, `cin >> file_name` will skip leading whitespace, start reading into `file_name`, but terminate should it see another whitespace character, so can't handle any filenames with embedded whitespace. It's also best practice to check for the success of input operations, as in `if (cin >> file_name) { ... } else std:cerr << "unable to read filename from stdin\n";`. `if (getline(std::cin, file_name)) { ... } else ...` handles embedded whitespace. – Tony Delroy Mar 24 '18 at 07:54
  • it gives me an error at line " file_stream.open(file_name); " ; the error is : C:\Users\mohamed\Desktop\try\main.cpp|21|error: no matching function for call to 'std::basic_fstream::open(std::string&)'| – Mohamed Abdelhamid Mar 24 '18 at 07:58
  • @MohamedAbdelhamid Sorry, I was missing include dependencies, I have addded it. Now it will compile fine. – Mohit Mar 24 '18 at 08:09
  • @Mohit i am sorry , but it still giving me the same error ! :') – Mohamed Abdelhamid Mar 24 '18 at 08:11
  • @Mohit and when i search for the file in the project folder i never find it – Mohamed Abdelhamid Mar 24 '18 at 08:12
  • @MohamedAbdelhamid But it compiled to me, I am using g++ 7.2 in windows using mingw32. I think you should update your compiler – Mohit Mar 24 '18 at 08:14
  • @Mohit will you please till me how to upgrade the compiler to your version though , :) – Mohamed Abdelhamid Mar 24 '18 at 08:16
1

The way you handle user input make variable nof a invalid file path on your running os. That's why fstream::is_open() return false.

for (int i=0;i<20; ++i){
  cin >> nof[i];
  if (nof[i-1]=='x'){
    if (nof[i]=='t'){
      break;
    }
  }
}

This code takes user input until it gets xt. But in C/C++, a valid string of char* or char[] type has to be end with \0 character. So if you still love the way you handling input, append \0 to the end of nof before you break the loops.

for (int i=0;i<20; ++i){
  cin>>nof[i];
  if (nof[i-1]=='x'){
    if (nof[i]=='t'){
      nof[i+1]=0; //or nof[i+1]='\0' or nof[i+1]=NULL;
      break;
    }
  }
}

But I suggest you use std::string and getline instead, the above way is quite awkward.

std::string nof;
std::getline(std::cin, nof);

std::fstream file;
file.open(nof.c_str(), std::fstream::in | std::fstream::out);
phuctm97
  • 136
  • 1
  • 9
  • std::string nof; std::getline(std::cin, nof); i tried that one in the begining but it did not work and kept giving me error as file.open(//takes char only) – Mohamed Abdelhamid Mar 24 '18 at 08:58
  • @MohamedAbdelhamid use file.open(nof.c_str()); – phuctm97 Mar 24 '18 at 09:01
  • cout << "Enter the name of the file : "; string nof; getline(cin, nof); fstream file1; file1.open(nof.c_str()); //it does not allow me to input anything like if it is cancelling getline fn. – Mohamed Abdelhamid Mar 24 '18 at 09:13
  • try `cin.ingore(INT_MAX)` before `getline(cin, nof)`. It seems your input buffer has already had a line. – phuctm97 Mar 24 '18 at 10:30
  • full code will be: `std::string nof;` `std::cin.ignore(INT_MAX);` `std::getline(std::cin, nof);` `std::fstream file;` `file.open(nof.c_str());` – phuctm97 Mar 24 '18 at 10:30
0

Mohit's answer tells you how to detect failure of std::fstream::open.

That function would usually use some operating system service to open a file, generally some open system call like open(2) on Linux (which can fail for many reasons).

Your program is buggy because your nof probably does not contain a valid file path. I would recommend clearing it with memset(nof, 0, sizeof(nof)) before reading it, and using your debugger, e.g. gdb to find your bug (if you enter a filename of only three characters, or one of fourty letters, your program won't work)

You could ask your operating system for a reason of that failure. On Linux you would use errno(3) (e.g. thru perror(3)).

As far as I know, the C++ standard does not specify how to query the reason of the failure of std::fstream::open (and probably do not require a relation between fstream and errno)

Pedantically, the C++ standard does not require std::fstream to use operating system files. Of course, in practice, fstream-s always use them. But in principle you might have a C++14 implementation on something without files or even without an OS (but I cannot name any).

The notion of file is in practice tightly related to operating systems and file systems. You can have OSes without files (in the past, OS/400, PalmOS, GrassHopper and other academic OSes) even if that is highly unusual today.

And the notion of file is specific to an OS: A file on Windows is not the same as a file on Unix or on z/OS.

Languages standard specifications (like C++11 n3337, C11 n1570, Scheme R5RS) are written in English and they are purposely vague on "files" or "file streams" (precisely because different OSes have different notions of them).

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547