Dismiss Notice
Join Physics Forums Today!
The friendliest, high quality science and math community on the planet! Everyone who loves science is here!

C++ File Program

  1. Apr 30, 2007 #1
    Im having a problem with a cpp program. It gives me 6 linker errors, which have something to do with buffer overflows. I used borland turbo cpp 3 to compile this. What should I do. Here's the code:

    #include<fstream.h>
    #include<conio.h>
    #include<stdio.h>



    ofstream write;
    ifstream read;

    int i;

    void main()
    {
    fflush(stdin);
    write.open("c:\windows\test.txt"); //open file for output
    char put1[80], get1[80];

    cout<<"Enter a sentence (<80): ";
    cin>>put1;
    for(i=0;i<80;i++)
    write.put(put1);
    write.put('\n');

    write.close();

    read.open("c:\windows\test.txt", ios::in);

    if(!read)
    {
    cout<<"File cannot be opened";
    }
    read.seekg(0);

    while(!read.eof())
    {
    read.getline(get1,80,'\n');
    cout<<get1<<"\n";
    }
    read.close();
    }
     
  2. jcsd
  3. Apr 30, 2007 #2
    I don't know why your linker fails. I note the following issues with your program.
    1. the line if(!read) should be if (!read.is_open ())
    2. if the file cannot be opened for reading, the programs goes ahead and reads it anyway.
    3. in the line read.open("c:\windows\test.txt", ios::in); the second parameter is redundant because read is declared as ifstream, not fstream. I note that you do not have a similar second parameter when you call the open method of write.

    In addition, I note that you have three global variables, but none of them need to be global. I recommend that you don't declare globals except when necessary. With experience you will find that globals are a mixed blessing at best and rarely necessary.
     
  4. Apr 30, 2007 #3
    I'm not sure what you're tryign to do but I see a few problems. If you use "cout" and "cin", you will need to have "#include<iostream>" at the top. I also think that the head "#incude<conio.h>" might not be necessary. Try compiling the following, and see if it is an improvement.

    #include<fstream>
    #include<iostream>

    using namespace std;

    int main()
    {
    int i;
    fflush(stdin);
    ofstream write("c:\\windows\\test.txt"); //open file for output
    char put1[80], get1[80];

    cout<<"Enter a sentence (<80): ";
    cin>>put1;
    for(i=0;i<80;i++)
    write.put(put1);
    write.put('\n');

    write.close();

    ifstream read("c:\\windows\\test.txt", ios::in);

    if(!read)
    {
    cout<<"File cannot be opened";
    }
    read.seekg(0);

    while(!read.eof())
    {
    read.getline(get1,80,'\n');
    cout<<get1<<"\n";
    }
    read.close();

    return 0;
    }
     
  5. Apr 30, 2007 #4
    Fstream is derived from iostream and hence already has cin and cout defined. However, when I changed ofstream and ifstream from global to local, then the program executed. Why is that? It seems to be really stupid that something small like that would affect the program. What could the reason be?
     
  6. Apr 30, 2007 #5

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    If opening the file fails, it sets the fail bit, and thus !read will return true.

    The header <fstream> is not required to include the header <iostream>. In fact, I rather expect it's not allowed to do so -- so if your version does, that's an error in the library.
     
    Last edited: Apr 30, 2007
  7. Apr 30, 2007 #6
    Im using turbo c++, and I've checked the help where it shows that iostream is also contained within fstream (iostream is inherited by fstream I guess).

    After I made the ofstream and ifstream class objects local rather than global, and made some other minor changes, the program executes, but I get two warnings, and it crashes after accepting the string. Here's the code:


    #include<fstream.h>
    #include<conio.h>
    #include<stdio.h>


    int i;

    void main()
    {
    ofstream write;
    ifstream read;

    fflush(stdin);
    write.open("c:\\test.txt"); //open file for output

    if(!write)
    cout<<"File cannot be opened";

    char put1[80], get1[80];

    cout<<"Enter a sentence (<80): ";
    cin>>put1;

    for(i=0;i<80;i++)
    write.put(put1);

    write.put('\n');

    write.close();

    read.open("c:\\test.txt");

    if(!read)
    cout<<"File cannot be opened";

    read.seekg(0);

    while(read)
    {
    read.getline(get1,80,'\n');
    cout<<get1<<"\n";
    }
    read.close();
    }
     
  8. May 1, 2007 #7
    Most compilers would tell you that the variable i in function main was never declared. The following seems to work in GCC in Windows


    #include<iostream>
    #include<fstream>
    using namespace std;

    int main()
    {
    int i;
    ofstream write;
    ifstream read;

    fflush(stdin);
    write.open("c:\\test.txt"); //open file for output

    if(!write)
    cout<<"File cannot be opened";

    char put1[80], get1[80];

    cout<<"Enter a sentence (<80): ";
    cin>>put1;

    for(i=0;i<80;i++)
    write.put(put1);

    write.put('\n');

    write.close();

    read.open("c:\\test.txt");

    if(!read)
    cout<<"File cannot be opened";

    read.seekg(0);

    while(read)
    {
    read.getline(get1,80,'\n');
    cout<<get1<<"\n";
    }
    read.close();

    return 0;
    }
     
  9. May 2, 2007 #8

    Whats the difference? The variable i was declared globally before, and now its local, and main is an integer function whereas it was a void function before. And most compilers would tell me that the variable i wasnt declared? Are you blind? Whats that in the beginning of the code? Just before main? Isnt i declared globally as an integer? Come on dude.

    I admit that declaring the classes ofstream and ifstream locally rather than globally solved the linker problem, but thats probably because global variables are given a different part of the memory and local variables a different part. For some reason, the code couldnt access one part of the memory allocated.

    I still cant get over the "most compilers would tell you the variable i wasnt declared". Gimme a break.
     
  10. May 2, 2007 #9

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    Just so you're aware, you're using an archaic compiler, which I suspect comes with an archaic standard library, and nonstandard extensions. (e.g. conio.h) So the results you get may be at odds with others' expectations.
     
    Last edited: May 2, 2007
  11. May 2, 2007 #10

    KTC

    User Avatar

    That was released in 1991. It's been 16 years, get a newer compiler (at least post 1998 standard).

    I'll go with what the standard actually says rather than some help file. Anyhow, according to the standard, including <fstream> does not mean the compiler have to make available to the end user what's in <iostream>. i.e. including <fstream> doesn't necessarily include <iostream>.

    Pre-standard header. It should now be
    Code (Text):
    #include <fstream>
    Old and non-standard header file. No need for it, bin it.

    Don't mix and match C and C++ IO's.

    Non-standard. main() have to returns int. That's the case whether you're programming in C or C++.

    1. You've just started the program, you don't need to flush anything. 2. You're mixing C and C++ IO's.

    0 + 0 = 0


    Code (Text):
    #include <iostream>
    #include <fstream>
    #include <string>

    int main()
    {
        std::ofstream write;
        write.open("C:/test.txt");

        if(!write)
            std::cout << "File cannot be opened";

        std::string put1, get1;

        std::cout << "Enter a sentence: ";
        std::getline( std::cin, put1 );

        write << put1;

        write.close();

        std::ifstream read;

        read.open("C:/test.txt");

        if(!read)
            std::cout << "File cannot be opened";

        while( read )
        {
            getline( read, get1 );
            std::cout << get1 << '\n';
        }
        read.close();

        return 0;
    }
     
  12. May 4, 2007 #11
    #include <iostream>
    #include <fstream>
    #include <string>

    int main()
    {
    std::eek:fstream write; //What does std stand for?
    write.open("C:/test.txt");

    if(!write)
    std::cout << "File cannot be opened";

    std::string put1, get1;

    std::cout << "Enter a sentence: ";
    std::getline( std::cin, put1 );

    write << put1;

    write.close();

    std::ifstream read;

    read.open("C:/test.txt");

    if(!read)
    std::cout << "File cannot be opened";

    while( read )
    {
    getline( read, get1 );
    std::cout << get1 << '\n';
    }
    read.close();

    return 0;
    }



    What does std stand for? Like, std::cout... why not just cout?

    Ok. If you guys say its out dated, Ill get Bloodshed Dev C++. Thank you all so far.
     
  13. May 4, 2007 #12
    Ok. Now, I've got Bloodshed cpp, but I'm having some problems. Where is the getch() (or similar) function defined in these libraries?

    There is a feature to find out what functions are in which header files but I dont know how to use it. Could someone tell me where the tab is?

    Im running this thing, but the output goes by too fast for me to see it (hence my asking for the getch() funtion). I know this is pretty basic stuff, but could someone please help me out?
     
  14. May 4, 2007 #13
    std is a namespace. Rather than explain what a namespace is, I prefer that you look this up somewhere as my explanation would probably be incomplete.

    You must either give full names to members in a namespace as follows:

    Code (Text):

    #include <iostream>

    int main()
    {
        std::cout << "Hello world!" << std::endl;
        return 0;
    }
     
    or announce that you want the namespace implied as follows:

    Code (Text):

    #include <iostream>

    using namespace std;

    int main()
    {
        cout << "Hello world!" << endl;
        return 0;
    }
     
    My custom is to have the using declaration in my .cpp files, but not in my header files because I don't want to impose the namespace on my clients.

    Because the use of namespaces allows name clashes, there may be times when you need to disambiguate. For instance, if you are including some files in the jimmy namespace and there is a member called endl in that namespace then the following code will have a problem:

    Code (Text):

    #include <iostream>
    #include <jimmy.h>

    using namespace std;
    using namespace jimmy;

    int main()
    {
        cout << "Hello world!" << endl;
        return 0;
    }
     
    The compiler doesn't know which endl to use. In that case, merely change one line:

    cout << "Hello world!" << std::endl;

    or

    cout << "Hello world!" << jimmy::endl;

    whichever is suitable.
     
    Last edited: May 4, 2007
  15. May 4, 2007 #14

    Hurkyl

    User Avatar
    Staff Emeritus
    Science Advisor
    Gold Member

    getch() is not part of C -- it was an extension that Borland provided. However, getchar() is a part of C. And, of course, cin.get() is part of C++.
     
  16. May 5, 2007 #15
    Quote:
    Originally Posted by chaoseverlasting View Post
    Ok. Now, I've got Bloodshed cpp, but I'm having some problems. Where is the getch() (or similar) function defined in these libraries?

    getch() is not part of C -- it was an extension that Borland provided. However, getchar() is a part of C. And, of course, cin.get() is part of C++.

    Thank you!!! I wish our school system would get updated so I'd learned this then. Its seems very stupid now to be using these old conventions, whats worse, I didnt even know they were old!

    std is a namespace. Rather than explain what a namespace is, I prefer that you look this up somewhere as my explanation would probably be incomplete.

    You must either give full names to members in a namespace as follows:

    Code:

    #include <iostream>

    int main()
    {
    std::cout << "Hello world!" << std::endl;
    return 0;
    }

    or announce that you want the namespace implied as follows:
    ...

    Thank you again. That makes it a lot clearer. So, cin, and cout are defined in the standard namespace, but not in iostream? Or is it that the working is defined in iostream and the names in std namespace?
     
  17. May 5, 2007 #16
    How would you get the program to stop long enough for me to see the output? In borland, there was also a delay() function, which doesnt work here. Can anyone suggest a decent book which I could buy?
     
  18. May 5, 2007 #17
    cin and cout are defined as std::cin and std::cout in iostream. The statement
    using namespace std;
    allows you to call them by their shorter names.
     
  19. May 5, 2007 #18
    Ok. But what about making the program stop/delay/hang on long enough so that i can see the output? I want to make sure that the read function i wrote actually reads the files and prints the contents.
     
  20. May 5, 2007 #19
    Can you redirect the output to a file?
     
  21. May 5, 2007 #20

    KTC

    User Avatar

    Or you can do what you're suppose to do with a console program, run it from within a console prompt.

    Alternatively, use a method, any method, that keep the program from finishing before the end user (i.e. you) have time to read the output.

    • Add the line system("PAUSE"); to the end of the program just before the return statement. The function std::system( const char* ) is declare in <cstdlib>, it takes a C-style character string and executes it as if it was entered into the command promt*. PAUSE is a windows program that writes a note to the console that the user should press a key to continue and then waits until the user presses a key. (Side effect: The string "Press any key to continue..." is localized, meaning for example on a French Windows version the string would be "Appuyez sur une touche pour continuer...")
    • Read some dummy variable. This only works if there's nothing in the input buffer because otherwise the buffer content is read before the user is asked for input.
    • Tell cin to ignore all input until Enter is pressed. (Again, only works if there's nothing already in the input buffer.) This can be done with
      cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); (std::numeric_limits is declared in <limits> [think])
    • Hope that the input buffer is empty and simply read a character. This works especially well for output only programs. This can be done with cin.get()
     
Know someone interested in this topic? Share this thread via Reddit, Google+, Twitter, or Facebook

Have something to add?