Is there anyway to outfile >> something only when outfile is not existed

closed account (Sh59216C)
Basically I am trying to make a data buy .txt file. I want the first column to be title of the data, but only the first column. I dont want to type in a txt then use ios::app to achieve that, Is there any other way to do the job?

Example:

Stock Rating <-- If I use outfile << my program would make this role to the database everything I input the list from a file.
AAPL AAA
DELL B
.
.
.
.
.
closed account (o3hC5Di1)
Hi there,

Could you please clarify what it is you're trying to do - I'm afraid I don't quite understand.
Maybe provide some pseudocode?

Thanks!

All the best,
NwN
he only wants one row of "Stock Rating" on the first line, but when he writes to the file he doesn't know if it is there or not, so he writes it multiple times.

I think that's the problem, and he is asking if there is a way of knowing.

not very experienced with file I/O so can't really help.
I am very experienced in file operations (because i cant use 3rd party stuff, i end up having to write it all myself).

First lesson in file ops: There is a STRICT algorithm. I have written functions specifically to fill this algorithm.

To check whether a file is there or not, we will have to open it. Here's the basic algorithm for checking whether a file exists:

1. open it for INput
2. is it open? if yes, close the file and return true; if no, return false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/** both file_there() and data_there()
return false if the file/data is not there.
*/
bool file_there(string file)
{
    ifstream in;
    in.open(file.c_str(), ios::in);
    if(!in.is_open())
    {
        return false;
    }
    if(in.is_open())
    {
        in.close();
        return true;
    }
    return false;
}


***********************************************************
we return false, because if it isn't open, but it still exists (in other words, it isn't not open), then... well.... we can't do anything. Chances are that condition is impossible to meet, though, because a file either exists, or does not exist. The return is just for stability.

Notice that instead of in.open("file.dat", ios::in), we use in.open(file.c_str(), ios::in);. This is optional. You can open a file using a string, instead of a string-constant by appening to the end of any string name .c_str(). This makes it so that i can call this function with any file name, and it will do all the work. I dont have to write the algorithm every time i want to check for file existence.
************************************************************

now we have checked it. But, lets say there file is there. What if the file is empty? There will be nothing to work with.

We will check to see if there is any data in the file. You may wonder why we do this separately. Here is why: A file can exist, and contain data. It could also exist and contain data. Because this returns false if 1: the file isnt there and 2: if there is no data there; we want to write this separately. If the file_there() function returns true, but this returns false, the file exists, but does not contain any data. Here is the algorithm:

1. open file for input (check if it exists too)
2. get each line in the file (because it is there)
3. count the number of lines which are greater than nothing
4. if the number of lines which are greater than nothing, is greater than 0, there is data, return true; if the number of lines which is greater than nothing is equal to 0, then there is no data in the file, return false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
bool data_there(string file)
{
    string line;
    int number_of_lines = 0;
    ifstream in;
    in.open(file.c_str(), ios::in);
    if(in.is_open())
    {
        number_of_lines = 0;
        while(!in.eof())
        {
            getline(in, line);
            if(line > "")
            {
                number_of_lines++;
            }
        }
        in.close();
    }
    if(number_of_lines > 0)
    {
        return true;
    }
    if(number_of_lines <= 0)
    {
        return false;
    }
    return false;
}


Now, all we have done is checked for data, and file existence. Now that we have, we will use an algorithm, to extract the data structure. Keep in mind that what you are doing is a bit complex (i dont want to say its advanced, because it really isn't, not at all). I recommend you study and try to grasp the concepts I'm about to give you.

First, we will set our data structure. Right now im working on a program which has a data structure of 5 pieces (5 pieces of information in a static order; static meaning it will never change). if we want to keep that data structure, but have 1 piece if data which is out of line (lets say we want to password protect our program, and the password is the first line in the file, then the rest is the data structure). Here is the steps we would take to get that piece of data, and return that piece of data (the piece of data, whether it has been modified, changed, etc...) to the file, without de-stabalizing the rest of the file.

1. get the entire file into a vector
2. vector[0] = our data
3. over-write the file with out vector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ifstream in;
ofstream out;
vector<string> file;
string line, first_line;
in.open("data.dat", ios::in);
while(!in.eof())
{
    getline(in, line);
    file.push_back(line);
}
in.close();
file[0] = first_line;
cout<< "Tell me what the first line will be!"<< endl;
getline(cin, first_line);
cin.sync();
file[0] = first_line;
out.open("data.dat", ios::out);
for(unsigned int x = 0; x < file.size(); x++)
{
    out<< file[x]<< endl;
}
out.close();
return 0;



what this does is get the whole file, put each line into a vector, and overwrite the whole file with the vector. Here is where our data goes: from file, to vector; -- use/modify data in vector--; from vector, to file.

since only 1 'slot' in the vector has changed, only 1 line in the file will.
Last edited on
Hope this helped! :)
closed account (Sh59216C)
Thank you very much for your detailed explanation. It is really helpful. I think I am really trying to do something annoying not technically difficult.

However, I don't get the vector part because I never work on any exercise on vector. But its okay, I will deal with it later on during the summer.

in.open("data.dat", ios::in); <-- why do i always see people using ios::in after file name while I see no such thing in the textbook? Is there any reason why people are doing this?

second, is there any difference between while (infile) & while (!infile.eof())?
closed account (Sh59216C)
Zephilinox: That's excatly my problem, if I just use outfile << Title ... Price
Every time I input a file, the database will be written a line of Title ... Price
It would not be good to the program, because I want to bubble sort it later one. Having more than one Title line would make it impossible to assess the data correctly
@leechunwa1990

in.open("data.dat", ios::in); <-- why do i always see people using ios::in after file name while I see no such thing in the textbook? Is there any reason why people are doing this?


Yes, there is a reason for it. The correct syntax (in C++, not C i dont know C) goes like this:

[handle].open(["filename"], ios::[open_for])

The open_for specifies HOW to open it. In ifstream there are 2 options that I know of to open a file as: Binary, and just standard "in". We can open a file for binary like this:

in.open("data.dat", ios::bin);

Now, this is the same for output as well. There are more than 1 way to open a file for output. There are 3 options: out, Truncate, and app. I have never used truncate. Append appends data being outputted to the end of the file, and out will erase all the data in the file, and write the data being outputted to the file (or over-write the data).

I don't get the vector part because I never work on any exercise on vector.


You should study up on them. They are useful. Basically, vectors are "lists" of data. That is why I use them in my file operations. It is easy to visualize each 'slot' of a vector as a line of the file. Think of it this way: each line in a file is numbered from 0-(eof) and the line's assigned number is it's 'slot' in the vector. This is really useful if you want to pick out 1 line of a file, like the first one, modify it, and put the whole file back.

second, is there any difference between while (infile) & while (!infile.eof())?


There is a HUGE difference. The "!" synbol in C++ means 'not'. So, literally it mean 'not at end of file'. So, we put it together into a while statement: "while not at the end of the file". We use this so that we get the whole file, until the end: "While not at the end of the file {get the next line of the file; put that line into a vector}" That is just (i huess what you would call) a traslation of the C++ code. We want to get each line up until the end of the file is reached.

if we were to use while(infile.eof()), it would mean "while at the end of the file" which pretty much skips all the data in the file until the last line. Technically, it would never actually be triggered, unless the end of the file was reached before the loop was declared.

Well, I hope I helped! GL! :)
Last edited on
what does infile return? true if it is open? so the difference is "while it is open" vs "while we haven't reached the end of file"

also, doesn't ifstream provide default parameters for ios::? are they different from ios::in?
@Zephilinox
Infile doesnt "return" anything. Infile is just a handle.

I hope I'm not going to have to lecture you on the nuances of programming. It is what it is. If it means 'end of file', it doesn't mean 'if the file is open'. Enough said.

Yes they do, but it is good to specify what you want, because somtimes you might find yourself with a different compiler, which assumes a different default (i doubt it, but w.e). Its just good practice is all.
Calling a vector a list is confusing. The data in a vector is contiguous, while a "list" is not. A better analogy is that a vector is an array that you can resize at any time.

is there any difference between while (infile) & while (!infile.eof())?
while(infile) loops while any part of the fstream is good. You're checking a condition that is not a straight true/false. while(!infile.eof()) loops until the EOF is found. So your infile could fail in some other way and your loop keeps looking anyway.

Better to use while(infile.good()) to insure a finite loop (assuming you're doing something with the file that might reach the EOF or break it in some way).
http://www.cplusplus.com/reference/iostream/ios/good/

You could also do:
1
2
int i
while (infile >> i) cout << i << endl;


The >> operator returns the fstream object itself, so it is also possible to do:
while ((infile >> i).good())

Just to say what I just said another way, that code: while (infile >> i) is different than:
while (!(infile >> i).eof()) because if your file doesn't have an integer in it, you will break the infile without getting to EOF, thus looping forever.

Last edited on
closed account (Sh59216C)
Thank you very much for IWishIKnew and LowestOne, you two gave me very clear explanation..

I will definitely work on vector,, but now I have my final project due tomorrow. The program does work, but I just wish to know more about why different codes seems to behave similarly. Thanks for LowestOne, now I know which one to use
Different codes behave similarly because of the way they are written. Every function in C++ was written to achieve a purpose. How those functions are used, however, is what makes a program operate.

Essentially, all C++ is, is a way to write a set of instructions to give a computer. But, there are many different instructions you can give, in any effective order, that will achieve a specific task/goal. .eof() and .good() are prime examples of this. Although they can be used to achive the same goal (to reach the end of the file), they specify different parameters. .good() only lets it loop while the file is not corrupt, which includes reaching the end of the file (hence their similar behavior), while .eof() loops until the end of the file is reached, no matter what.

Yes, i will admit, using .good() is safer than .eof(), especially if you dont want your program to freeze up because somthing happened to that file in mid-stream (highly unlikely but not impossible). But, I ahve never had problems with .eof(), and I emplement some very complicated data structures in a lot of my programs (to keep the nimber of files to a minimum, lol).

I'm sure you had been given this lecture the first day, but you did ask the question.

It is important to look up more than 1 function that can complete a task, because some functions may achieve them more effectively. It's whatever your personal preference is though.

Good luck! :)
I believe a good example of the .good method is while your file is writing, delete the file...typically a person can't do this unless there is a lot being wrote to the file at that moment, but I believe something similar would be to close inFile during the while loop. It'll never set the eofbit and your loop would then become infinite. Obviously, we never want to do this in practical code, but it's something to think about.

What if you have multiple programs all trying to read/write to one file (or even one program having multiple file stream objects just trying to read and write to it (think of threads))? There is a very good chance something will close the file and break the other file objects causing them to loop endlessly. This is again another scenario we never want to do...but it happens...

Another example is reading a file from a network location. What happens when the resource online suddenly goes offline...your program will be looping endlessly and have no idea why.

Just a few examples of why .good is better than just .eof (I use .eof when teaching others, it's easier to understand that eof is end of file while explaining good, isn't so easy).
Intresting. I haven't gotten to threads (I like to call "Threads" multi-tasking) because I'm actually teaching myself to write C++. I've written some pretty complicated programs, including a checkbook, and most recently a Budget Constructor. My checkbook uses a dynamic file system (which I pretty much just came up with when I was writing it) and my Busget Constructor uses a complicated data structure and 2 files, 1 which it syncs with the other.

I haven't gotten to threads though, because I never really needed them. I guess .eof() is only best used when executed by a lone program which doesn't "interact" with multiple threads on a file.

I will remember, though, this information for future reference. Thanks Volatile Pulse.
Topic archived. No new replies allowed.