my c++ file is not opened , why? - c++

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 ?

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.
}
}

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);

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).

Related

How to move file in Linux using C++

How do you move a file from one location to another using a C++ program in Linux?
I've written a program to do this and it runs, but when I try to move a file to a different directory it doesn't move the file, I get the error message from the cout statement. When I try to just rename the file, moving it to the same directory with a new name it works. How can I fix my code so it will be able to move files to another directory?
Here's the code I've written:
#include <iostream>
#include <stdio.h>
using namespace std;
int main ()
{
int result=1;
char oldname[500];
char newname[500];
cout << "Enter the name of a file you want to move (include directory structure)";
cin >> oldname;
cout << "Enter the new location (include directory structure)";
cin >> newname;
result = rename( oldname , newname );
if ( result == 0 )
cout << "File successfully moved" << endl;
else
cout << "Error moving file" << endl;
return 0;
}
Edit:
I added perror to my code and the error message displayed is "Error moving file: No such file or directory" even though the directory I tried moving it to does exist and it has create and delete files permissions.
Your code will work in most cases. But you are ignoring some important things in which case it will break :
The obvious things like permissions, non-existing path, ...
Paths of 500 chars or more. Don't use static allocated memory for oldname and newname
Moving between filesystems is not possible with rename() so do it like this ( and include iostream )
ifstream ifs(oldname, ios::in | ios::binary);
ofstream ofs(newname, ios::out | ios::binary);
ofs << ifs.rdbuf();
remove(oldname);
Before the remove() your total disk space will be a bit less.
This doesn't matter if your are moving between filesystems because only the free space on the filesystem with newname will shrink and this is free space you have because otherwise you wouldn't able to move the file here
If oldname and newname are on the same filesystem and you really care about this temporary loss then check whether you'll be using the same filesystem and use rename() after all.
How to fix your program depends on the reason why the move (rename) failed.
The reason for the failure can be found using errno.
In this case, it was necessary to make sure that the source file exists.
For all things that need to be considered to robustly implement moving, I recommend studying an implementation of mv command.

is_open() function in C++ always return 0 value and getLine(myFile, line) does not return anything

Trying to read a file in C++ using fstream.
But the is_open() function always return 0 result and readline() does not read anything. Please see the code snippet below.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
ifstream myfile("D:\xx\xx\xx\xx\testdata\task1.in.1");
if (myfile.is_open()) {
while (getline(myfile, line)) {
cout << line << '\n';
}
myfile.close();
}
else
cout << "Unable to open file";
return 0;
}
you think you're opening D:\<somepath>\testdata\task1.in.1
but in fact you're trying to open D:\<somepath><tabulation char>estdata<tabulation char>ask1.in.1 since \t is interpreted as a tabulation.
(like \n is a newline in printf("hello world\n");)
(\x is special too BTW that's not the real path or you would have had another error: error: \x used with no following hex digits which maybe would have talked to you better!)
You have to escape the backslashes like this:
D:\\xx\\xx\\xx\\xx\\testdata\\task1.in.1
Windows also accepts paths like those, more convenient, unless you want to generate batch scripts with cd commands or the like that would require backslashes (/ is used as option switch in batch commands):
D:/xx/xx/xx/xx/testdata/task1.in.1
As NathanOliver stated, you can use the raw prefix if your compiler has C++11 mode enabled (or with --std=c++11)
R"(D:\xx\xx\xx\xx\testdata\task1.in.1)"
Last word: dirty way of getting away with it:
D:\Xx\Xx\Xx\Xx\Testdata\Task1.in.1
Using uppercase in that case would work
because windows is case insensitive
C would let the backslashes as is.
But that's mere luck. A lot of people do that without realizing they're very close to a bug.
BTW a lot of people capitalize windows paths (as seen a lot in this site) because they noticed that their paths wouldn't work with lowercase without knowing why.

Why My Language translator program in Visual C++ overwriting a file with nothing instead of the translation

I have developed a program for translating words in english to my native language.Everything works fine with no errors, except that I am not getting the desired output.
The program asks a user for an input file in which there are english words, then it will read the file and write the translations in my native language to an output file specified by the user. My problem is that the program writes nothing to the output file. I even chose a non-empty output file but all I have seen and understood is that the program overwrits all what are in the output file with nothing.
Please I am asking for someone's help in this difficult time because I have exhausted all my thinking.
Below is the complete program:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h >
#include <conio.h>
#include <iomanip>
#include <cctype>
#include <ctype.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#include <fstream>
using namespace std;
string Identifier;
ofstream outfile;
ifstream infile;
static string fname1, fname2;
char a = (char)infile.get();
void Display(){
outfile << "Nuna";
}
void gettok(){
Identifier = "";
if (isalnum(a)) { // identifier: [a-zA-Z][a-zA-Z0-9]*
Identifier = a;
while (isalnum(a = (char)infile.get()))
Identifier += a;
while (isspace(a = (char)infile.get())){
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
}
}
}
int main(){
cout << "Enter name of the file to be translated ";
cin >> fname1;
cout << "Enter new file name";
cin >> fname2;
infile.open(fname1);
if (infile.fail())
{
cerr << " No such a file Exist";
exit(1);
}
outfile.open(fname2);
if (outfile.fail())
{
cerr << "Unable to create a file";
exit(1);
}
while (!infile.eof())
{
gettok();
}
infile.close();
outfile.close();
}
Thank you sir, #TimStraubinger for your guide.
1. Firstly, based on my definition of the Display() function, I just want the program to be in such a way that whenever the english word
Display is read in the input file, then the Display() function is called whose job is to write the translation of the word display as "Nuna" to the output file. I want to have a function for translating each english word as I have done for the word Display. But if there is a better way, help me out.
2. I used "char a = (char)infile.get() " because i want to declare "a" as global variable to be known and used by all of my functions and furthermore, I can't open a file outside the "main" function. So, I searched and thought of ways but all failed!
Please any one's help is welcomed!
There are many things wrong with this, here are my main suggestions. Firstly, your code is hard to read and confusing and defies lots of good convention. I recommend you follow a few textbook examples with C++ and learn to organize your code better so that we can better help you. As for your code, some more obvious problems are as follows:
char a = (char)infile.get()
Here, you're trying to access the file before it is opened. This needs to be called after infile is opened.
And to see something written to the file, you have the condition:
if (Identifier == "Display"){
Display();
a = (char)infile.get();
}
Why does the accumulator string, Identifier, need to have "Display" stored in order to write something to the file? (I highly recommend you find a better function name for Display(), which suggests you're writing something to the screen.) Also, inside the while (isspace(a = (char)infile.get())) loop, infile.get() will be called twice every loop, once to check the loop condition and once because you wrote it in additionally. This will cause every other character to be skipped in that loop.

Unable to open file.txt with c++

I've looked up similar posts here, but none seem to be doing the job for my question. I'm basically trying take a sequence of words in a .txt file and put each word in a vector, and printing each value afterwards. For example, we have I love racing cars in array.txt, and I want my vector to have "I" at position 0, "love" at 1 and so on. Unfortunately, the code does not access "array.txt", so it never executes the code in the if condition.
Now I've heard that by using the fstream library it should work just fine, but the file is never found. I suspect that it doesn't work because it cannot find the path, but I have never opened files in C++. Also, I have not put my file anywhere in my project folder.
Some changes I've already tried:
file.open("array.txt");
omitting file.close();
include "C:\array.txt"; (with the # in front)
file.open("C:\array.txt")
And I'm using Windows 10, if this matters.
#include <iostream>;
#include <string>;
#include <vector>;
#include <fstream>;
//#include <"C:\Users\Samer El-Hage\Documents">;
using namespace std;
void main(){
vector<string> v (10);
ifstream file;
file.open("C:\array.txt", ios::in);
if (file.is_open())
{
for (int i = 0; i < 3; i++)
{
file >> v[i];
}
file.close();
}
else cout << "Could not access file.";
for (int i = 0; i < 3; i++)
{
cout << v[i] << " ";
}
}
This code prints "Could not access file."
The file cannot be opened because the file system can't find the file named "[Bell]rray.txt". the character sequence '\a' is the "Make my computer Beep" character.
Use either forward slashes: "C:/array.txt", an escaped backslash: "C:\\array.txt" or a raw string literal: R"(C:\array.txt)"
The file must also exist at the specified location. If you do not provide a drive and just say "array.txt" the location defaults to wherever the executable is (or in an IDE, the Working Directory).
Also, you have unnecessary semi-colons after your includes. (In fact, in a Treat Warnings as Errors setup, this won't compile!)
I got it! I had not put the .txt file in my folder with the source code, which, strangely enough, was not mentioned in my previous search results... I got to search better!
\a simply turns the computer beep on. Try writing "C:\\array.txt" instead in the open call.
Try not calling open explicitly:
ifstream file ("array.txt");
Look at the examples here:1

When will ofstream::open fail?

I am trying out try, catch, throw statements in C++ for file handling, and I have written a dummy code to catch all errors. My question is in order to check if I have got these right, I need an error to occur. Now I can easily check infile.fail() by simply not creating a file of the required name in the directory. But how will I be able to check the same for outfile.fail() (outfile is ofstream where as infile is ifstream). In which case, will the value for outfile.fail() be true?
sample code [from comments on unapersson's answer, simplified to make issue clearer -zack]:
#include <fstream>
using std::ofstream;
int main()
{
ofstream outfile;
outfile.open("test.txt");
if (outfile.fail())
// do something......
else
// do something else.....
return 0;
}
The open(2) man page on Linux has about 30 conditions. Some intresting ones are:
If the file exists and you don't have permission to write it.
If the file doesn't exist, and you don't have permission (on the diretory) to create it.
If you don't have search permission on some parent directory.
If you pass in a bogus char* for the filename.
If, while opening a device file, you press CTRL-C.
If the kernel encountered too many symbolic links while resolving the name.
If you try to open a directory for writing.
If the pathname is too long.
If your process has too many files open already.
If the system has too many files open already.
If the pathname refers to a device file, and there is no such device in the system.
If the kernel has run out of memory.
If the filesystem is full.
If a component of the pathname is not a directory.
If the file is on a read-only filesystem.
If the file is an executable file which is currently being executed.
By default, and by design, C++ streams never throw exceptions on error. You should not try to write code that assumes they do, even though it is possible to get them to. Instead, in your application logic check every I/O operation for an error and deal with it, possibly throwing your own exception if that error cannot be dealt with at the specific place it occurs in your code.
The canonical way of testing streams and stream operations is not to test specific stream flags, unless you have to. Instead:
ifstream ifs( "foo.txt" );
if ( ifs ) {
// ifs is good
}
else {
// ifs is bad - deal with it
}
similarly for read operations:
int x;
while( cin >> x ) {
// do something with x
}
// at this point test the stream (if you must)
if ( cin.eof() ) {
// cool - what we expected
}
else {
// bad
}
To get ofstream::open to fail, you need to arrange for it to be impossible to create the named file. The easiest way to do this is to create a directory of the exact same name before running the program. Here's a nearly-complete demo program; arranging to reliably remove the test directory if and only if you created it, I leave as an exercise.
#include <iostream>
#include <fstream>
#include <sys/stat.h>
#include <cstring>
#include <cerrno>
using std::ofstream;
using std::strerror;
using std::cerr;
int main()
{
ofstream outfile;
// set up conditions so outfile.open will fail:
if (mkdir("test.txt", 0700)) {
cerr << "mkdir failed: " << strerror(errno) << '\n';
return 2;
}
outfile.open("test.txt");
if (outfile.fail()) {
cerr << "open failure as expected: " << strerror(errno) << '\n';
return 0;
} else {
cerr << "open success, not as expected\n";
return 1;
}
}
There is no good way to ensure that writing to an fstream fails. I would probably create a mock ostream that failed writes, if I needed to test that.