C++ Read File into an Array

Discussion in 'Mac Programming' started by corywoolf, Mar 29, 2010.

  1. corywoolf macrumors 65816

    corywoolf

    Joined:
    Jun 28, 2004
    #1
    Hello MR members,

    I have spent three hours trying to figure out how to read in the data of a group of people and store the information into an array of structures (struct Node) and then print out the array. I was given the following structure definition to work with:

    Code:
    struct Node { char name[20];
    int ID; int distance;
    }; 
    I understand the concept of arrays and structures (a group of arrays), but I can't find a good example that is similar enough to my problem to study.

    I am trying to read the following text from file "a6.txt" into an array of structures:

    Here is the C++ I have so far:

    Code:
    #include <cstdlib>
    #include <iostream>
    #include <fstream>
    
    using namespace std;
    
    int READ(char txtfile[10]; int numarray[10]; int counter;)
    {
        ifstream filename;
        filename.open (txtfile);
        while (!filename.eof())
        {
            filename >> numarray [counter];
            cout << numarray [counter] << endl;
            counter++;
        };
    };
            
    
    int main()
    {
        char txtfile[]="a6.txt";
        int size=10;
        int numarray [size];
        int r;
        r= READ();
        cout<< r;
        
        system("PAUSE");
        return EXIT_SUCCESS;
    }
    Any tips or guidance is appreciated.

    Thanks in advance,

    - Cory
     
  2. CylonGlitch macrumors 68030

    CylonGlitch

    Joined:
    Jul 7, 2009
    Location:
    SoCal
    #2
    Ok, bare with me here, I'm winging this. :D

    Code:
    struct Node { char name[20];
    int ID; int distance;
    };
    
    int main(int argc, char *argv[])
    {
        FILE *Input_File;
        Node Names[100];
        int Count = 0;
    
        Input_File = fopen("a6.txt", "r");
        if (Input_File != null)
            Count = fread(&Names[0], sizeof(Node), 100, Input_File);
        fclose(Input_File);
    
        // Count = Number of items read, up to 100.
    }
    
    NOTE: This example will not work right for your data file, this would require a record data file. To handle the a6.txt file as you wrote it try the following :
    Code:
    struct Node {
    char last_name[20]; 
    char first_name[20];
    int ID; 
    int distance;
    };
    
    int main(int argc, char *argv[])
    {
        FILE *Input_File;
        Node Names[100];
        int Count = 0;
    
        Input_File = fopen("a6.txt", "r");
        if (Input_File != null)
            while (!feof(Input_File) && (Count < 100))
            {
                scanf(Input_File, "%s,%s", &Names[Count].last_name, &Names[Count].first_name);
                scanf(Input_File, "%u", &Names[Count].ID);
                scanf(Input_File, "%u", &Names[Count++].distance);
            }
        fclose(Input_File);
        // Count = Number of items read, up to 100.
    }
    
    This second one isn't perfectly coded, but it is the general gist. It doesn't have any error checking or recovery if things happen that are unexpected. but should get you rolling on the right path.

    Good Luck . . . and if this doesn't work perfect, again, I'm winging it. :D
     
  3. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #3
    First a few questions.

    Is this homework for a class?
    If so what is the name of the course?
    What book?
    What have you covered so far?

    I'm assuming from the definition of 'Node' that C++ string objects haven't been covered in whatever has been presented (or study material your working from) yet.

    What I/O routines have have you been made aware of?

    And it looks like you're working in C++. Is that correct?
     
  4. corywoolf thread starter macrumors 65816

    corywoolf

    Joined:
    Jun 28, 2004
    #4
    It is an assignment for a class. Computer Methods I. Programming and Problem Solving with C++. We have just started to get into arrays and structures. The professor just reads off a powerpoint and doesn't provide enough examples to study from. I have had trouble finding a similar example to this assignment. I don't recall hearing much about nodes yet.
     
  5. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
  6. corywoolf thread starter macrumors 65816

    corywoolf

    Joined:
    Jun 28, 2004
    #6
    Thanks for your effort, it didn't work though. Isn't "scanf" used in C and not C++?
     

    Attached Files:

  7. Matthew Yohe macrumors 68020

    Joined:
    Oct 12, 2006
    #7
  8. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #8
    As he said it's a Standard C library function.

    Please post the exact wording of the homework assignment.
     
  9. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #9
    THe problem shown is that it should be NULL, note the case.
     
  10. CylonGlitch macrumors 68030

    CylonGlitch

    Joined:
    Jul 7, 2009
    Location:
    SoCal
    #10
    As I said.... don't expect it to work correctly, I was making it up as I go along. I'm more of an embedded C programmer, but have moved on to other languages, thus C++ isn't my native language. :D
     
  11. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #11
    That's not the only problem. It shouldn't be calling scanf(), since scanf() reads stdin. I suspect fscanf() is more plausible. Some limits on string-length would also be wise, lest buffers be overflowed.


    To the OP, I'm not seeing how this could work as the declaration for READ():
    And that's my tip for the OP: When you have errors, always post the exact text of the errors. And if you don't have errors, then you haven't tried compiling. And if you haven't tried compiling, you haven't really tried.

    I also suggest providing an explanation of what this is intended to do:
    Code:
        system("PAUSE");
    
     
  12. CylonGlitch macrumors 68030

    CylonGlitch

    Joined:
    Jul 7, 2009
    Location:
    SoCal
    #12
    Doh, yeah, fscanf. That's a big snafu. :D I guess I should have run it through a compiler; lol. It was last night, I was tired and rushing. :D
     
  13. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #13
    Yes, I'm well aware of that.

    Not wanting to get side tracked to much I wanted to know what the exact wording of the assignment was so as offer helpful advice. He seems to have been given a starting point with a definition for 'Node'.

    Also his homework seems to be very close, if not the same, as this one. So much so that I wanted to know if he was given the the declarations of other functions he was to use.
     
  14. notjustjay macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #14
    Indeed, that's either a notation I've never seen before or there is definitely something wrong here.

    My suggestion is to always start small and work your way to bigger things. That way you can build on smaller successes rather than try to write out something bigger and have it fail and not know where to begin.

    If I was doing this assignment, I might start by doing the following:

    - Write a simple program that just reads the text file and prints out everything it reads. You can hard-code the filename to start.

    - Write a program that creates a single Node object and fills it with data about a person. You can hard-code the variable assignments for this first round.

    - Now change the program to create an array of these Nodes, fill them with data (you can hard code this), and prints out the array. Now is the time to practice looping through arrays and stuff like that.

    - Now put it all the pieces together so that you read your list of names from the file and populate the node objects, as the assignment requires.

    Are you required to use separate functions (e.g. your READ() function) or are you allowed to accomplish it all in the main() function? If you are using a separate READ() function to read values into the array, you're either going to need to declare the array as a global variable or pass a pointer to the function, neither of which you've mentioned if you know how to do or not.
     
  15. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #15
    The following is meant to give you an idea of how to continue your homework assignment.

    It also points out a few potential gotcha's.

    Code:
    #include <cstdlib>
    
    #include <iostream>
    #include <fstream>
    
    struct Node
    {
        char    name[20];
        int     ID;
        int     dist;
    };
    
    int main (int argc, char* const argv[])
    {
        const size_t    MAX_NODE_ENTRIES            = 4;
        Node            nodes_array[MAX_NODE_ENTRIES];
    
        std::ifstream   ifs("A6.txt");
        if ( ifs.is_open() )
        {
            // read records from 'ifs'
            size_t  nodes_index = -1;
            do
            {
                if ( ++nodes_index >= MAX_NODE_ENTRIES )
                {
                    std::cout   << "Not enough entries in 'nodes_array' to read next record!\n"
                                << "Adjust value of 'MAX_NODE_ENTRIES'";
                    return EXIT_FAILURE;
                }
    
                // WARNING!!!  unknown length read into 'name' field which is of fixed length
                if ( ifs )  ifs >> nodes_array[nodes_index].name;
                if ( ifs )  ifs >> nodes_array[nodes_index].ID;
                if ( ifs )  ifs >> nodes_array[nodes_index].dist;
            } while ( ifs );
            
            // --- display all entries in array 'nodes_array'
            for ( size_t i = 0; i < nodes_index; i++ )
            {
                Node    node = nodes_array[i];
                std::cout << node.name << "\n" << node.ID << "\n" << node.dist << "\n\n";
            }
    
            return EXIT_SUCCESS;
        }
        
        return EXIT_FAILURE;
    }
    
     
  16. TREERAT macrumors newbie

    Joined:
    Apr 6, 2010
    #16
    The following is meant to give you an idea of how to continue your homework assignmen

    Hi lloyddean.

    Thanks for posting an example. I do not have a homework assignment to do, however I would really like to be able to read in some parameters from a file (any file will do) to a c++ file. I have a one question:

    1) Is the example you posted above supposed to work? (I have pasted it into Xcode and tried it with the A6.txt included in the project folder and included in the project explicitly.

    According to my console it seems that it cannot open the file. I added an output of BLANKET and PANCAKE to indicate if the file is notopen/open. I also tried it with ifs.open("A6.txt"); and without.

    ////////////////////////////////////////////////////////////////////////////////////
    Code:
    #include <iostream>
    #include <fstream>
    
    struct Node
    {
        char    name[20];
        int     ID;
        int     dist;
    };
    
    int main (int argc, char* const argv[])
    {
    	
    	std::cout << "BLANKET" << std::endl;
        const size_t    MAX_NODE_ENTRIES            = 4;
        Node            nodes_array[MAX_NODE_ENTRIES];
    	
        std::ifstream   ifs("A6.txt");
    	
    	ifs.open("A6.txt");
    	
        if ( ifs.is_open() )
        {
    		
    		std::cout << "PANCAKE" << std::endl;
            // read records from 'ifs'
            size_t  nodes_index = -1;
            do
            {
                if ( ++nodes_index >= MAX_NODE_ENTRIES )
                {
                    std::cout   << "Not enough entries in 'nodes_array' to read next record!\n"
    				<< "Adjust value of 'MAX_NODE_ENTRIES'";
                    return EXIT_FAILURE;
                }
    			
                // WARNING!!!  unknown length read into 'name' field which is of fixed length
                if ( ifs )  ifs >> nodes_array[nodes_index].name;
                if ( ifs )  ifs >> nodes_array[nodes_index].ID;
                if ( ifs )  ifs >> nodes_array[nodes_index].dist;
            } while ( ifs );
            
            // --- display all entries in array 'nodes_array'
            for ( size_t i = 0; i < nodes_index; i++ )
            {
                Node    node = nodes_array[i];
                std::cout << node.name << "\n" << node.ID << "\n" << node.dist << "\n\n";
            }
    		ifs.close();
            return EXIT_SUCCESS;
        }
        
        return EXIT_FAILURE;
    }
    
    ///////////////////////////////////////////////////////////////////////////////////

    And here is the output:

    ///////////////////////////////////////////////////////////////////////////////////

    [Session started at 2010-04-06 14:30:03 +0100.]
    GNU gdb 6.3.50-20050815 (Apple version gdb-1346) (Fri Sep 18 20:40:51 UTC 2009)
    Copyright 2004 Free Software Foundation, Inc.
    GDB is free software, covered by the GNU General Public License, and you are
    welcome to change it and/or distribute copies of it under certain conditions.
    Type "show copying" to see the conditions.
    There is absolutely no warranty for GDB. Type "show warranty" for details.
    This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000
    Loading program into debugger…
    Program loaded.
    run
    [Switching to process 70711]
    Running…
    BLANKET

    Debugger stopped.
    Program exited with status value:1.kill
    (gdb)
    /////////////////////////////////////////////////////////////////////////////////////

    I just want to read in some parameters. Any help would be much appreciated even if it is a reference to a book. I have already spent a day and a half searching the web and testing examples.

    Thanks very much!
    :eek:
     
  17. notjustjay macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #17
    The example code worked for me, compiled under g++ and run from a Linux command line, however I had to explicitly include <cstring> to get size_t and define my own EXIT_SUCCESS and EXIT_FAILURE as my compiler declared them undefined.

    TREERAT, are you running this from a command line? If so, is the A6.txt file in the same directory as your program binary?
     
  18. TREERAT macrumors newbie

    Joined:
    Apr 6, 2010
    #18
    Thanks notjustjay

    Well originally I was running the file in Xcode (the software developer). So taking your advice I tried running from the command line like so:

    /////////////////////////////////////////////////////////////////////////
    mwoods-macbook:Reading Data From File maewoods$ ls
    A6.txt MForums.cpp
    mwoods-macbook:Reading Data From File maewoods$ g++ MForums.cpp -o MForums
    mwoods-macbook:Reading Data From File maewoods$$
    /////////////////////////////////////////////////////////////////////////

    and got the same output again.

    /////////////////////////////////////////////////////////////////////////
    Last login: Tue Apr 6 16:41:18 on ttys003
    mwoods-macbook:~ maewoods$ /Users/maewoods/Desktop/Reading\ Data\ From\ File/MForums ; exit;
    BLANKET
    logout

    [Process completed]
    /////////////////////////////////////////////////////////////////////////

    The A6.txt is in the same folder as the cpp file.

    Thanks :) :confused:
     
  19. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #19
    After the g++ command has completed, enter exactly this command:
    Do not quit Terminal. Do not close the window. Do not use another window. Do not 'cd' to another directory. Simply copy and paste the exact command-line directly into Terminal after your compiling command has completed.

    The problem is that the file "A6.txt" is opened using a relative pathname (read the source, note the pathname). Relative pathnames are always interpreted relative to the working directory. If the file isn't located in the working directory, then it won't work.

    http://en.wikipedia.org/wiki/Working_directory
    http://en.wikipedia.org/wiki/Path_(computing)

    The concept of a pathname, either relative or absolute, is fundamental to understanding file-systems.


    Code:
    mwoods-macbook:[U]~[/U] maewoods$ /Users/maewoods/Desktop/Reading\ Data\ From\ File/MForums ; exit;
    
    In this trial run, the working directory is your home folder, represented by "~". I've underlined it above in your shell prompt.

    I underlined it in your compiling command-line, too:
    Code:
    mwoods-macbook: [U]Reading Data From File[/U] maewoods$ g++ MForums.cpp -o MForums 
    
    There is a C function to get the working directory's pathname as a C string: getcwd(). You might want to change your program to print that string, then use it as a diagnostic aid to help you figure out what's happening. Online man page:
    http://developer.apple.com/Mac/library/documentation/Darwin/Reference/ManPages/man3/getcwd.3.html
     
  20. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #20
    Yes it compiles and works on this end. Although it was missing the inclusion of 'cstdio" from what I posted here. I must've missed in when copying into the code tags.

    As to not finding the file "A6.txt" go to your "Project" menu select "Edit Active Execuatable <your executable name>". A setting dialog to set up the runtime executable environement will appear.

    Make sure the "General" viw-tab is selected.

    In the lower left quadrant locate the radio-botton labeled "Set the working directory to:" to what ever is appropriate for your use. If the "A6.txt" is sitting next to your Xcode project file select "Project Directory".

    Close the Dialog.

    Run.
     
  21. TREERAT macrumors newbie

    Joined:
    Apr 6, 2010
    #21
    Thank you for some answers. The file is now being read, although I have no display of the entries in nodes_array. If I change the value of nodes_index I get a display of either zero or another integer. No values from A6.txt are displayed.

    chown33: It makes perfect sense but I did not know that about the relative pathnames so thanks.
     
  22. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #22
    If you're using the code "as is" against the "A6.txt" as you posted above you should see this output:

    Not enough entries in 'nodes_array' to read next record!
    Adjust value of 'MAX_NODE_ENTRIES'

    It seems to me you've made little attempt to understand the example.

    A simple modification at the very first line of 'main' will be required in order for the code to 'read' the complete file before it can display what was read. This was done on purpose on my part as one of the things that you'll need to understand to keep you from over running the end of your arrays.
     
  23. TREERAT macrumors newbie

    Joined:
    Apr 6, 2010
    #23
    Well thanks lloyddean but you are gravely wrong. I do not know about nodes and I have made an effort to understand the example, around about 17 hours is a lot of time to invest. I have not had any training in computer science and I would like to learn.

    Every so often someone gives you correct information "as is" with the hope that the information will be understood properly and will not be used to for a selfish purpose. Those are the people who will never be famous but will help us cure diseases and increase our quality of life.

    Note: I do not get the error:

    Not enough entries in 'nodes_array' to read next record!
    Adjust value of 'MAX_NODE_ENTRIES'
     
  24. notjustjay macrumors 603

    notjustjay

    Joined:
    Sep 19, 2003
    Location:
    Canada, eh?
    #24
    OK, let's back things up a bit. To make things easier, instead of a set of Node structures, let's just work with numbers: let's assume we have a file, full of numbers, one number per line, like so:

    Code:
    2
    6
    112
    -135
    45465
    12
    
    So your array to store these numbers in memory might look like this:

    Code:
    const size_t    MAX_ARRAY_SIZE = 10;
    int array_of_numbers[MAX_ARRAY_SIZE];
    
    This defines an array with 10 elements, so you can have up to 10 numbers stored in the file. If you try to read a file with more than 10 numbers, you'll have to increase the value of MAX_ARRAY_SIZE to suit.

    And your code, based on the above example, would be simplified a bit and look like this:

    Code:
    #include <cstdlib>
    
    #include <iostream>
    #include <fstream>
    
    int main (int argc, char* const argv[])
    {
        const size_t    MAX_ARRAY_SIZE  =  10;
        int array_of_numbers[MAX_ARRAY_SIZE];
    
        std::ifstream   ifs("numbers.txt");
        if ( ifs.is_open() )
        {
            // begin reading numbers from 'ifs' file stream
            size_t  index = -1;
            do
            {
                if ( ++index >= MAX_ARRAY_SIZE )
                {
                    // ran out of space in the array!
                    std::cout   << "Not enough entries in 'array_of_numbers' to read next record! Adjust value of 'MAX_ARRAY_SIZE'" << std::endl;
                    return EXIT_FAILURE;
                }
                // read the number into the next available index in the array
                if ( ifs )  ifs >> array_of_numbers[index];
            } while ( ifs );
            
    
            // now loop through the array so we can print each value
            for ( size_t i = 0; i < index; i++ )
            {
                std::cout << array_of_numbers[i] << std::endl;
            }
    
            return EXIT_SUCCESS;
        }
        
        return EXIT_FAILURE;
    }
    
    Hopefully this simplifies things enough to help you understand what's going on.
     
  25. TREERAT macrumors newbie

    Joined:
    Apr 6, 2010
    #25
    OK for any people who are having similar problems with reading in data I now have the answer to my problem. I was trying to use a "file.txt" that I had copied from a different project.

    Maybe,

    This resulted in a newline character error.

    I attempted to resolve this issue by creating a file in terminal using the pico command.

    Then I had to rename the file using the mv command.

    Now I can read in the correct values from my file. I have not tested it with the example above, but I hope this will resolve the problem with that also.

    Again thanks for your help guys! :)
     

Share This Page