fstream to array

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • freqzz
    New Member
    • Feb 2007
    • 11

    fstream to array

    i got a little proble to implement memory allocation using array. Here's the situation, i got a sample data stored in textfile:


    tri1 (1,7,1) (2,8,2) (3,7,3)
    tri2 (2,8,2) (5,7,5) (3,7,3)
    tri3 (5,7,5) (3,5,2) (3,7,3)
    tri4 (3,7,3) (3,5,2) (1,7,1)
    tri5 (5,7,5) (5,5,7) (3,5,2)

    it is a triangulation table.. so later i'll plot it as a triangle..

    i would like to read the text file and pass it into array.. consisting node1, node2 and node3..

    i started like this..

    int i;

    float node1[3];
    float node2[3];
    float node3[3];

    std::ifstream in("sample.txt" ,std::ios::in |std::ios::bina ry);

    if(!in)
    {
    std::cout<<"cou ld not open file"<<std::end l;
    return 1;
    }


    then i ran out of idea to pass the value...

    so, can anyone help me out?

    p/s: anyway.. this is not a school assignment.. i just want to try graphic programming - openGL..
  • horace1
    Recognized Expert Top Contributor
    • Nov 2006
    • 1510

    #2
    you could read a complete line of text into a character array and then use a string tokenizer to extract the numbers, e.g.
    Code:
          int i1, i2, i3, i4;
          char line[100]="tri1 (1,7,1) (2,8,2) (3,7,3)";
          char *tok = strtok(line, "(");     /* find first token */
          tok = strtok(NULL, ",");           /* get first number */
          i1=atoi(tok);
          tok = strtok(NULL, ",");           /* get second number */
          i2=atoi(tok);
          tok = strtok(NULL, ")");           /* get third number */
          i3=atoi(tok);
          tok = strtok(NULL, "(");           /* skip ) ( */
          tok = strtok(NULL, ",");           /* get first number */
          i4=atoi(tok);
          printf("%d %d %d %d\n", i1, i2, i3, i4);
    when run it gives
    1 7 1 2

    Comment

    • freqzz
      New Member
      • Feb 2007
      • 11

      #3
      Code:
      #include <windows.h> 
      #include <gl\gl.h>
      #include <gl\glut.h>
      #include <math.h>
      #include <iostream.h>
      #include <fstream.h>
      
      
      
      
      void read(void)
      {
      
      	int i;
      
      	float x1,y1,z1;
      	float x2,y2,z2;
      	float x3,y3,z3;
      	
      
      	ifstream inStream;
      	inStream.open ("sample.txt", ios::in);
      	if (inStream.fail())
      		return;
      
      	for (i=0; i<5; i++)
      	{
      
      		char line[50] = "tri1 (1,7,1) (2,8,2) (3,7,3)";
      		char *tok =strtok (line, "(");
      
      		tok = strtok(NULL, ",");
      		x1 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		y1 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		z1 = atoi(tok);
      	
      		tok = strtok(NULL, "(");
      
      		tok = strtok(NULL, ",");
      		x2 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		y2 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		z2 = atoi(tok);		
      
      		tok = strtok(NULL, "(");
      		
      		tok = strtok(NULL, ",");
      		x3 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		y3 = atoi(tok);
      
      		tok = strtok(NULL, ",");
      		z3 = atoi(tok);
      	
      		cout << x1 << y1 << endl;
      	}
      }
      it doesnt come out with any result.. one more.. is this token hold the value in memory like array? so whenever i called x value, it will give me the value...

      Comment

      • horace1
        Recognized Expert Top Contributor
        • Nov 2006
        • 1510

        #4
        you had a couple of your delimiters wrong, try
        Code:
        	{
        
        		char line[50] = "tri1 (1,7,1) (2,8,2) (3,7,3)";
        		char *tok =strtok (line, "(");
        
        		tok = strtok(NULL, ",");
        		x1 = atoi(tok);
        
        		tok = strtok(NULL, ",");
        		y1 = atoi(tok);
        
        		tok = strtok(NULL, ")");  // ** changed
        		z1 = atoi(tok);
        	
        		tok = strtok(NULL, "(");
        
        		tok = strtok(NULL, ",");
        		x2 = atoi(tok);
        
        		tok = strtok(NULL, ",");
        		y2 = atoi(tok);
        
        		tok = strtok(NULL, ")");// ** changed
        		z2 = atoi(tok);		
        
        		tok = strtok(NULL, "(");
        		
        		tok = strtok(NULL, ",");
        		x3 = atoi(tok);
        
        		tok = strtok(NULL, ",");
        		y3 = atoi(tok);
        
        		tok = strtok(NULL, ")");// ** changed
        		z3 = atoi(tok);
        	
        		cout << x1 << " " << y1   << " " << z1 << endl;
        		cout << x2 << " " << y2   << " " << z2 << endl;
        		cout << x3 << " " << y3   << " " << z3 << endl;
        if I run this i get
        1 7 1
        2 8 2
        3 7 3

        when strtok() finds a token it replaces the delimiter with \0 and returns a char * pointer to the start of the token, i.e. in this code tok points to the string and atoi() then converts this to an int so x1, y1, etc coontains the numeric values you require

        Comment

        • cting76
          New Member
          • Mar 2007
          • 10

          #5
          What about reading a line like below from a file, say, "input.txt" :

          (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)

          I am trying to put the first parameters, i.e. arule,brule,etc into an array, say, [I]rules, and the numbers into another array, say numbers[j].

          I assume the first array would have to be string type. When I use strtok it tells me it cannot convert string to char. Is there a function in C++ that I could use in this case, or, how do I separate string from int?

          Any info appreciated. Thanks!

          Comment

          • Ganon11
            Recognized Expert Specialist
            • Oct 2006
            • 3651

            #6
            strtok probably returns a character array (char *) that you will somehow have to convert to a string. I'm not sure if you can cast the result by placing (string) before it, or if you will have to manually construct a string using the char* by getting the result as a char[], then adding each element of the char[] to the string with a for loop.

            Comment

            • cting76
              New Member
              • Mar 2007
              • 10

              #7
              Maybe my flow of thought isn't correct. What I'm trying to do is to write codes that would read lines of data from a txt file, then run a heapsort on them. For example, given the following data:

              (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)
              (frule, 3)
              (grule, 20), (srule, 100)

              The program should read and sort the first line of data in an array, then insert the 2nd line, sort the whole array, and then the 3rd. And I thought the best way to do it is to put the first parameters into a string array, the numbers into an int array and let the program sort the int array and update the order of the elements in the string array according to the int's. Currently I'm stuck at seperating string from int data under ifstream. Is this a good way to do it at all?

              Thanks.

              Comment

              • Ganon11
                Recognized Expert Specialist
                • Oct 2006
                • 3651

                #8
                When you are sorting, it might be a good idea to use a struct or class to store both the int and the string in one member (class is probably better as you can overload the < and > operators).

                Since you know what the format of each entry will be, you can get the entire line and split it by the '(' characters. At that point, you will have an array containing strings like "(arule, 10) " (with a space at the end), and from here you can look for the ',' to see where the string is (everything from the second character to the comma) and where the int is (everything after the comma and before the ')'). See if you can get it from there.

                Comment

                • cting76
                  New Member
                  • Mar 2007
                  • 10

                  #9
                  Originally posted by Ganon11
                  Since you know what the format of each entry will be, you can get the entire line and split it by the '(' characters. At that point, you will have an array containing strings like "(arule, 10) " (with a space at the end), and from here you can look for the ',' to see where the string is (everything from the second character to the comma) and where the int is (everything after the comma and before the ')'). See if you can get it from there.
                  ok... I understand the concept. Basically I have to write code that would treat everything after '(' and before ',' as string, and everything after ',' and before ')' as int, and if there's a ',' after ')', repeat until there's no ',' after ')'. My question is, what fuction should I use? I mean, how do you tell the program to "read" each character and determine if it's a '(', ',', ')', a letter or a number?

                  Thanks!

                  Comment

                  • horace1
                    Recognized Expert Top Contributor
                    • Nov 2006
                    • 1510

                    #10
                    Originally posted by cting76
                    What about reading a line like below from a file, say, "input.txt" :

                    (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)

                    I am trying to put the first parameters, i.e. arule,brule,etc into an array, say, [I]rules, and the numbers into another array, say numbers[j].

                    I assume the first array would have to be string type. When I use strtok it tells me it cannot convert string to char. Is there a function in C++ that I could use in this case, or, how do I separate string from int?

                    Any info appreciated. Thanks!
                    you can tokenise
                    (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)
                    so
                    Code:
                            char *names[50];
                            int values[50];
                            int namesIndex=0;
                    	char line[100] = " (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)";
                    	char *tok =strtok (line, "(");
                    
                    	names[namesIndex]= strtok(NULL, ",");   // first name
                    
                    	tok = strtok(NULL, ")");                // first int
                    	values[namesIndex++] = atoi(tok);
                            
                            while((tok=strtok(NULL, "(")) != NULL)  // look for next (
                                {
                    		    names[namesIndex]= strtok(NULL, ",");  // next name
                                tok = strtok(NULL, ")");  
                    		    values[namesIndex++] = atoi(tok);       // next int
                               }
                        for (int i=0;i<namesIndex;i++)
                             cout << names[i] << " " << values[i]<<endl;
                    when run gives
                    arule 12
                    brule 21
                    zrule 70
                    drule 25
                    erule 10

                    Comment

                    • cting76
                      New Member
                      • Mar 2007
                      • 10

                      #11
                      I kept getting this error when running the program under Visual C++:

                      Debug Assertion Failed!
                      Program: ...
                      File: strtol.c
                      Line: 94

                      Expression: nptr != NULL

                      What did I do wrong? :(

                      The code:

                      Code:
                      #include <iostream>
                      #include <fstream>
                      using namespace std;
                      
                      void main()
                      {
                      
                      	ifstream infile;
                      	char c[256], str[256];
                      	char *rules[10];
                      	int rulesindex=0;
                      	int i=0;
                      	int priority[25];
                      
                      	cout<<"Enter the name of the file: ";
                      	cin.get(str, 256);
                      
                      	infile.open(str);
                      	
                      	for(i=0;i<256;i++)
                      	{
                      		c[i]=infile.get();
                      		
                      		cout<<c[i];
                      	}
                      	cout<<endl;
                      
                      	char *tok=strtok(c,"(");
                      	rules[rulesindex]=strtok(NULL,",");
                      	tok=strtok(NULL, ")");
                      	priority[rulesindex++]=atoi(tok);
                      
                      	while((tok=strtok(NULL,"("))!=NULL)
                      	{
                      		rules[rulesindex]=strtok(NULL,",");
                      		tok=strtok(NULL,")");
                      		priority[rulesindex++]=atoi(tok);
                      
                      
                      	}
                      
                      	for(i=0;i<rulesindex;i++)
                      	{
                      		cout<<rules[i]<<endl;
                      		cout<<priority[i]<<endl;
                      	}
                      	
                      	infile.close();
                      }
                      Another question:

                      Let's say my input.txt file has 3 lines:

                      (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)
                      (frule, 3)
                      (grule, 20), (srule, 100)

                      and I want the program to do something after reading the first line before reading the second line (say, read the first line of data into a struct, then do the same for 2nd, then 3rd line), what delimiter should I use to pause the program from reading the subsequent line, and continue after performing certain operation? I tried using "\n" and " " but with the error above I couldn't tell if they worked.

                      Thank you.

                      Comment

                      • horace1
                        Recognized Expert Top Contributor
                        • Nov 2006
                        • 1510

                        #12
                        you code looks fine and I guess it is the debug mode causing problems - can you run without debug?

                        I suggest you read a line at a time
                        Code:
                        #include <iostream>
                        #include <fstream>
                        using namespace std;
                        
                        int main()
                        {
                        
                        	ifstream infile;
                        	char c[256], str[256];
                        	char *rules[10];
                        	int rulesindex=0;
                        	int i=0;
                        	int priority[25];
                        
                        	cout<<"Enter the name of the file: ";
                        	cin.get(str, 256);
                        
                        	infile.open(str);
                        	while(1)
                        	{
                        	infile.getline(c, 256);
                        	if(!infile)break;
                        	cout << "string " << c << endl;
                        /*	for(i=0;i<256;i++)
                        	{
                        		c[i]=infile.get();
                        		
                        		cout<<c[i];
                        	}
                        	cout<<endl;*/
                            rulesindex=0; 
                        	char *tok=strtok(c,"(");
                        	rules[rulesindex]=strtok(NULL,",");
                        	tok=strtok(NULL, ")");
                        	priority[rulesindex++]=atoi(tok);
                        
                        	while((tok=strtok(NULL,"("))!=NULL)
                        	{
                        		rules[rulesindex]=strtok(NULL,",");
                        		tok=strtok(NULL,")");
                        		priority[rulesindex++]=atoi(tok);
                        
                        
                        	}
                        
                        	for(i=0;i<rulesindex;i++)
                        	{
                        		cout<<rules[i]<<endl;
                        		cout<<priority[i]<<endl;
                        	}
                        	cout << "end of line" << endl;
                        	
                        }
                        	system("pause");
                        	infile.close();
                        }
                        if you give it a file containing
                        (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)
                        (frule, 3)
                        (grule, 20), (srule, 100)

                        the output is
                        Enter the name of the file: tok.dat
                        string (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)
                        arule
                        12
                        brule
                        21
                        zrule
                        70
                        drule
                        25
                        erule
                        10
                        end of line
                        string (frule, 3)
                        frule
                        3
                        end of line
                        string (grule, 20), (srule, 100)
                        grule
                        20
                        srule
                        100
                        end of line

                        Comment

                        • freqzz
                          New Member
                          • Feb 2007
                          • 11

                          #13
                          A new problem arrive. I have two files. One files in this format:

                          10.23 5.63 4.12
                          14.2 -5.1 1.33
                          1.22 1.25 1.5
                          7.56 8.15 -5.25
                          5.23 7.11 4.0

                          The other one is:

                          1 2 3
                          3 5 4
                          2 4 1
                          5 1 3
                          3 1 2


                          Same concept as the earlier question. But I need to link both file so it will end up as one.

                          The first file is a coordinate file while the other one is a TIN file. I want to read the TIN file and refer it to the coordinate so the output will be like this.

                          If I want to plot the first point, i will read the first line - 1, 2 and 3. Those number will refer to the coordinate file - I will refer to line no 1 consisting 10.23, 5.63 and 4.12. 2 will refer to 14.2, -5.1 and 1.33 and so one. So at the end, it will result like this.

                          (10.23, 5.63, 4.12) (14.2, -5.1, 1.33)(1.22, 1.25, 1.5)

                          and so on depens on the TIN file.

                          The curret code i'm working with is

                          Code:
                          #include <iostream.h>
                          #include <vector>
                          #include <fstream.h>
                          
                          
                          struct Point
                          {
                          	float x, y, z;
                          };
                          
                          struct Tin
                          {
                          	Point point[3];
                          
                          	float node1, node2, node3;
                          };
                          
                          struct Triangle
                          {
                          	node1 point;
                          	node2 point;
                          	node3 point;
                          };
                          
                          istream & operator >> (istream & in, Point & pt)
                          {
                          	in >> pt.x >> pt.y >> pt.z;
                          
                          	return in;
                          }
                          
                          istream & operator >> (istream & in, Tin & tin)
                          {
                          	in >> tin.node1[0] >> tin.node2[1] >> tin.node3[2];
                          
                          	return in;
                          }
                          
                          istream & operator >> (istream & in Triangle & tri)
                          {
                          	in >> tri.node1 >> tri.node2 >> tri.node3;
                          
                          	return in;
                          }
                          
                          
                          ostream & operator << (ostream & out , const Triangle & tri)
                          {
                              out << tri.node1[0] << " " << tri.node2[1] << " " << tri.node3[2];
                          
                              return out;
                          }
                          
                          int main()
                          {
                          	std::vector<Point> p;
                          
                          	ifstream in ("cuba.xyz", ios::in);
                          
                          	if (!in)
                          	{
                          		cout << "could not open" << endl;
                                  return 1;
                          	}
                          
                          	Point point;
                          
                          	while (in >> point)
                              {
                                  p.push_back(point);
                              }
                          
                          
                          	std::vector<Tin> t;
                          	
                          	ifstream in ("cuba.tin", ios::in);
                          
                          	if (!in)
                          	{
                          		cout << "could not open" << endl;
                                  return 1;
                          	}
                          
                          	Tin tin;
                          
                          	while (in >> tin)
                              {
                                  t.push_back(tin);
                              }
                          
                          	for (int i=0; i<p.size(); i++)
                              {
                                  cout << p[i] << endl;
                              }
                          So any idea on dealing with the matters? Or should i use pointer?

                          Any help will be appreciated.

                          Comment

                          Working...