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

C++ Simple File I/O

  1. Feb 18, 2006 #1
    I'm trying to come up with a C++ program that reads input from a text file. Each line of this text file has a different variable. I have different data types (int, string, char). I'm having difficulty to read strings with spaces and read char's. The rest seems to work fine. If possible, I'd like to hear some tips on how to improve my work. I've already searched the web several times, but I haven't been able to find a solution. The programs (one that creates 20 blocks of inputs and the other which reads each block) are attached.

    Any help is highly appreciated.

    Attached Files:

  2. jcsd
  3. Feb 18, 2006 #2


    User Avatar
    Staff Emeritus

    Do you have to use ifstream? Could you use fscanf?

    The syntax would be something like this:

    FILE *fp ;

    fscanf(fp "%d %s %s %f %s %s", &id, name, description, &cost, department, color);

    This is the way I like to do it. It is a much cleaner approach.
    Last edited: Feb 18, 2006
  4. Feb 18, 2006 #3
    yah fscanf/fprintf are so much better. but can you have those spaces in theredduardo? %d %s or is it %d%s?
  5. Feb 18, 2006 #4


    User Avatar
    Staff Emeritus

    You can have whatever you want. Tabs, newlines, spaces, characters, etc.
  6. Feb 18, 2006 #5
    It seems that the approach suggested is from C. I don't know whether or not that can be used as if it were C++ code. There are no compilation errors, but I don't get output from the program. I've uploaded a text file with what I have now. I'm a bit lost.

    Thanks for your help, folks.

    Attached Files:

  7. Feb 18, 2006 #6


    User Avatar
    Staff Emeritus

    You have to use C style strings, which means:

    char mystring[n] ; //Use this if you know the size of the field


    char **mystring ; //Use this if you don't know the size of the field
    Last edited: Feb 18, 2006
  8. Feb 18, 2006 #7
    Processing user input in both C and C++ can give you a headache because of little details. Reading a string with "scanf" or "cin <<" will only read one word at a time, stopping at any whitespace. C function "gets" reads a whole line but does not check for overflow so you get subtle errors that mysteriously happen once in a while, not always. Function "fgets" does not remove the trailing '\n' from the input buffer so you have to remember to do it manually. Reading pretty much anything with "cin <<" in C++ can cause the same problem: the '\n' remains in the buffer so when you read a test line with "getline" after an integer then all you get is an empty one (from the newline chatracter); then the next call to read an integer causes an input error. All sort of annoying little details like this.

    Here's my approach to resolve these annoyances. Whenever you have separate data items on separate lines, read each line as plain text first. In C++ you can use the "getline" function for this:

    string str;
    while (getline(cin, str)) {
    // Do something with str.

    You can replace "cin" with any other stream if you're reading from a file instead of the console. Once you have a line of data into a string, if you know what is in it then use an appropriate conversion function to convert it. It's not a sin to use some of the C functions for this (with str.c_str() to get a C char*), so use "atoi" to convert alpha to integer, use "atof" to convert alpha to float, leave the string as is if a string is what you need, use str[0] if all you want is the first character. It's simple and it works consistently.
  9. Feb 22, 2006 #8
    Sorry for the delay. I've been trying to figure out the code...

    Thank you so much, my program is beginning to function!

    I am just having a problem reading the char datatype. I cannot pass it to a c++ char variable without using a conversion trick. Is there a way to accomplish this?
  10. Feb 23, 2006 #9
    I've just found a way to incorporate Orefa's suggestion to the char problem. It does work!!! Now I just get a strange "0" in my last line of the final output file. Maybe it's just simpler to picture this by looking at the files attached. The first c++ code (see GenerateInputFile.txt) generates the input txt file whereas the other c++ code (see InOut.txt) reads it and writes an output txt of what has been read. That's where the '0' appears. :confused:

    Attached Files:

  11. Feb 23, 2006 #10
    If your data file ends with a redundant newline character then the loop will repeat one time too many and your first IF clause will convert an empty line (caused by this lone '\n' character) into an integer. This will generate the 0 you're seeing.

    What you should do is check for an empty line at the top of the loop. If the line length is zero then break out of the loop.

    By the way, you know that you can simplify your code a great deal. Now that you've done all the work... :smile: No need for an array of strings, you can reuse only one. You can also eliminate a lot of repetitious code. Consider this simplified version (which I didn't try to compile and run, I hope it isn't too buggy):
    Code (Text):

    int main() {
        int      count = 0;
        string   line;
        ifstream in("myProducts.txt");
        ofstream out("OUTPUT.txt");

        while (getline(in, line) && line.length() > 0) {
            switch (count % 5) {
                case 0: out << atoi(line.c_str());  break;  // ID
                case 1: out << line;                break;  // Name
                case 2: out << atof(line.c_str());  break;  // Cost
                case 3: out << line[0];             break;  // Department
                case 4: out << line;                break;  // Color
            cout << endl;
        out << "# LINES READ = " << count << endl;
        return 0;
    Edit: I realize that the above code does away with many variables you may need to keep. It is just to illustrate possible simplification methods.
    Last edited: Feb 23, 2006
  12. Feb 23, 2006 #11
    Thanks, Orefa!

    Indeed, your approach greatly simplifies the problem. I managed to get something working the way it was supposed to! The purpose of these programs is to simply ensure that the inputs I read from a text file are accurate. Now I can play with the data, and hopefully have some fun. :smile:

    I have a lot to learn. Thanks for your support, guys.
  13. Feb 23, 2006 #12
    dynamic objects

    I'm wondering if any of you know how to dynamically create instances of a class. I've been trying, but all that I can do is read one single block of input from a text file. I've attached my work.

    Any help is highly appreciated.


    Attached Files:

    Last edited: Feb 23, 2006
  14. Feb 23, 2006 #13
    You can dynamically create instances of a class using the new operator.

    However, i guess you would also like to keep access to all the objects that you have created, which is not that simple unfortunately, but its not very hard either.

    Since we need to keep reference to all the objects created, we will maintain them in a linked list. The nodes of the linked list will have the following members,

    1. A pointer of type <class>
    2. Next node pointer

    Basic node step creation would be as follows,
    1. Create an instance of linked list node
    newnode = new LinkedListNode()

    2. Connect the newly created node to previously maintained Linked List,
    tail->nextnode = newnode
    tail = newnode
    **tail is a pointer which is maintained so as to always point at the tail of the linked list. Correspondingly, we need also to maintain a head pointer which points to start of the linked list.

    3. Assign memory to the <class> pointer inside the new instance just created.
    tail->classptr = new <class>()

    Thus, you have dynamically created a new instance of class and at the same time you have maintained all the objects you have created so far. You can access each of these objects by traversing the list from head to tail.

    -- AI
    P.S -> Linked List is a form of data structure that helps you maintain "things" (in your case "things" were class objects) in the form of a list. This is not the only data structure that you can use. You can use anything from stack, queues, hashtables etc etc. to meet your needs and is most efficient as per your requirements.
Share this great discussion with others via Reddit, Google+, Twitter, or Facebook