By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,388 Members | 1,762 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,388 IT Pros & Developers. It's quick & easy.

fstream to array

P: 11
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::binary);

if(!in)
{
std::cout<<"could not open file"<<std::endl;
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..
Feb 26 '07 #1
Share this Question
Share on Google+
12 Replies


Expert 100+
P: 1,510
you could read a complete line of text into a character array and then use a string tokenizer to extract the numbers, e.g.
Expand|Select|Wrap|Line Numbers
  1.       int i1, i2, i3, i4;
  2.       char line[100]="tri1 (1,7,1) (2,8,2) (3,7,3)";
  3.       char *tok = strtok(line, "(");     /* find first token */
  4.       tok = strtok(NULL, ",");           /* get first number */
  5.       i1=atoi(tok);
  6.       tok = strtok(NULL, ",");           /* get second number */
  7.       i2=atoi(tok);
  8.       tok = strtok(NULL, ")");           /* get third number */
  9.       i3=atoi(tok);
  10.       tok = strtok(NULL, "(");           /* skip ) ( */
  11.       tok = strtok(NULL, ",");           /* get first number */
  12.       i4=atoi(tok);
  13.       printf("%d %d %d %d\n", i1, i2, i3, i4);
  14.  
when run it gives
1 7 1 2
Feb 26 '07 #2

P: 11
Expand|Select|Wrap|Line Numbers
  1. #include <windows.h> 
  2. #include <gl\gl.h>
  3. #include <gl\glut.h>
  4. #include <math.h>
  5. #include <iostream.h>
  6. #include <fstream.h>
  7.  
  8.  
  9.  
  10.  
  11. void read(void)
  12. {
  13.  
  14.     int i;
  15.  
  16.     float x1,y1,z1;
  17.     float x2,y2,z2;
  18.     float x3,y3,z3;
  19.  
  20.  
  21.     ifstream inStream;
  22.     inStream.open ("sample.txt", ios::in);
  23.     if (inStream.fail())
  24.         return;
  25.  
  26.     for (i=0; i<5; i++)
  27.     {
  28.  
  29.         char line[50] = "tri1 (1,7,1) (2,8,2) (3,7,3)";
  30.         char *tok =strtok (line, "(");
  31.  
  32.         tok = strtok(NULL, ",");
  33.         x1 = atoi(tok);
  34.  
  35.         tok = strtok(NULL, ",");
  36.         y1 = atoi(tok);
  37.  
  38.         tok = strtok(NULL, ",");
  39.         z1 = atoi(tok);
  40.  
  41.         tok = strtok(NULL, "(");
  42.  
  43.         tok = strtok(NULL, ",");
  44.         x2 = atoi(tok);
  45.  
  46.         tok = strtok(NULL, ",");
  47.         y2 = atoi(tok);
  48.  
  49.         tok = strtok(NULL, ",");
  50.         z2 = atoi(tok);        
  51.  
  52.         tok = strtok(NULL, "(");
  53.  
  54.         tok = strtok(NULL, ",");
  55.         x3 = atoi(tok);
  56.  
  57.         tok = strtok(NULL, ",");
  58.         y3 = atoi(tok);
  59.  
  60.         tok = strtok(NULL, ",");
  61.         z3 = atoi(tok);
  62.  
  63.         cout << x1 << y1 << endl;
  64.     }
  65. }
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...
Feb 26 '07 #3

Expert 100+
P: 1,510
you had a couple of your delimiters wrong, try
Expand|Select|Wrap|Line Numbers
  1.     {
  2.  
  3.         char line[50] = "tri1 (1,7,1) (2,8,2) (3,7,3)";
  4.         char *tok =strtok (line, "(");
  5.  
  6.         tok = strtok(NULL, ",");
  7.         x1 = atoi(tok);
  8.  
  9.         tok = strtok(NULL, ",");
  10.         y1 = atoi(tok);
  11.  
  12.         tok = strtok(NULL, ")");  // ** changed
  13.         z1 = atoi(tok);
  14.  
  15.         tok = strtok(NULL, "(");
  16.  
  17.         tok = strtok(NULL, ",");
  18.         x2 = atoi(tok);
  19.  
  20.         tok = strtok(NULL, ",");
  21.         y2 = atoi(tok);
  22.  
  23.         tok = strtok(NULL, ")");// ** changed
  24.         z2 = atoi(tok);        
  25.  
  26.         tok = strtok(NULL, "(");
  27.  
  28.         tok = strtok(NULL, ",");
  29.         x3 = atoi(tok);
  30.  
  31.         tok = strtok(NULL, ",");
  32.         y3 = atoi(tok);
  33.  
  34.         tok = strtok(NULL, ")");// ** changed
  35.         z3 = atoi(tok);
  36.  
  37.         cout << x1 << " " << y1   << " " << z1 << endl;
  38.         cout << x2 << " " << y2   << " " << z2 << endl;
  39.         cout << x3 << " " << y3   << " " << z3 << endl;
  40.  
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
Feb 26 '07 #4

P: 10
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!
Mar 11 '07 #5

Ganon11
Expert 2.5K+
P: 3,652
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.
Mar 11 '07 #6

P: 10
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.
Mar 11 '07 #7

Ganon11
Expert 2.5K+
P: 3,652
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.
Mar 11 '07 #8

P: 10
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!
Mar 16 '07 #9

Expert 100+
P: 1,510
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
Expand|Select|Wrap|Line Numbers
  1.         char *names[50];
  2.         int values[50];
  3.         int namesIndex=0;
  4.     char line[100] = " (arule, 12), (brule, 21), (zrule, 70), (drule, 25), (erule, 10)";
  5.     char *tok =strtok (line, "(");
  6.  
  7.     names[namesIndex]= strtok(NULL, ",");   // first name
  8.  
  9.     tok = strtok(NULL, ")");                // first int
  10.     values[namesIndex++] = atoi(tok);
  11.  
  12.         while((tok=strtok(NULL, "(")) != NULL)  // look for next (
  13.             {
  14.             names[namesIndex]= strtok(NULL, ",");  // next name
  15.             tok = strtok(NULL, ")");  
  16.             values[namesIndex++] = atoi(tok);       // next int
  17.            }
  18.     for (int i=0;i<namesIndex;i++)
  19.          cout << names[i] << " " << values[i]<<endl;                       
  20.  
when run gives
arule 12
brule 21
zrule 70
drule 25
erule 10
Mar 16 '07 #10

P: 10
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:

Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. void main()
  6. {
  7.  
  8.     ifstream infile;
  9.     char c[256], str[256];
  10.     char *rules[10];
  11.     int rulesindex=0;
  12.     int i=0;
  13.     int priority[25];
  14.  
  15.     cout<<"Enter the name of the file: ";
  16.     cin.get(str, 256);
  17.  
  18.     infile.open(str);
  19.  
  20.     for(i=0;i<256;i++)
  21.     {
  22.         c[i]=infile.get();
  23.  
  24.         cout<<c[i];
  25.     }
  26.     cout<<endl;
  27.  
  28.     char *tok=strtok(c,"(");
  29.     rules[rulesindex]=strtok(NULL,",");
  30.     tok=strtok(NULL, ")");
  31.     priority[rulesindex++]=atoi(tok);
  32.  
  33.     while((tok=strtok(NULL,"("))!=NULL)
  34.     {
  35.         rules[rulesindex]=strtok(NULL,",");
  36.         tok=strtok(NULL,")");
  37.         priority[rulesindex++]=atoi(tok);
  38.  
  39.  
  40.     }
  41.  
  42.     for(i=0;i<rulesindex;i++)
  43.     {
  44.         cout<<rules[i]<<endl;
  45.         cout<<priority[i]<<endl;
  46.     }
  47.  
  48.     infile.close();
  49. }
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.
Mar 18 '07 #11

Expert 100+
P: 1,510
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
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <fstream>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7.  
  8.     ifstream infile;
  9.     char c[256], str[256];
  10.     char *rules[10];
  11.     int rulesindex=0;
  12.     int i=0;
  13.     int priority[25];
  14.  
  15.     cout<<"Enter the name of the file: ";
  16.     cin.get(str, 256);
  17.  
  18.     infile.open(str);
  19.     while(1)
  20.     {
  21.     infile.getline(c, 256);
  22.     if(!infile)break;
  23.     cout << "string " << c << endl;
  24. /*    for(i=0;i<256;i++)
  25.     {
  26.         c[i]=infile.get();
  27.  
  28.         cout<<c[i];
  29.     }
  30.     cout<<endl;*/
  31.     rulesindex=0; 
  32.     char *tok=strtok(c,"(");
  33.     rules[rulesindex]=strtok(NULL,",");
  34.     tok=strtok(NULL, ")");
  35.     priority[rulesindex++]=atoi(tok);
  36.  
  37.     while((tok=strtok(NULL,"("))!=NULL)
  38.     {
  39.         rules[rulesindex]=strtok(NULL,",");
  40.         tok=strtok(NULL,")");
  41.         priority[rulesindex++]=atoi(tok);
  42.  
  43.  
  44.     }
  45.  
  46.     for(i=0;i<rulesindex;i++)
  47.     {
  48.         cout<<rules[i]<<endl;
  49.         cout<<priority[i]<<endl;
  50.     }
  51.     cout << "end of line" << endl;
  52.  
  53. }
  54.     system("pause");
  55.     infile.close();
  56. }
  57.  
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
Mar 18 '07 #12

P: 11
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

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include <iostream.h>
  3. #include <vector>
  4. #include <fstream.h>
  5.  
  6.  
  7. struct Point
  8. {
  9.     float x, y, z;
  10. };
  11.  
  12. struct Tin
  13. {
  14.     Point point[3];
  15.  
  16.     float node1, node2, node3;
  17. };
  18.  
  19. struct Triangle
  20. {
  21.     node1 point;
  22.     node2 point;
  23.     node3 point;
  24. };
  25.  
  26. istream & operator >> (istream & in, Point & pt)
  27. {
  28.     in >> pt.x >> pt.y >> pt.z;
  29.  
  30.     return in;
  31. }
  32.  
  33. istream & operator >> (istream & in, Tin & tin)
  34. {
  35.     in >> tin.node1[0] >> tin.node2[1] >> tin.node3[2];
  36.  
  37.     return in;
  38. }
  39.  
  40. istream & operator >> (istream & in Triangle & tri)
  41. {
  42.     in >> tri.node1 >> tri.node2 >> tri.node3;
  43.  
  44.     return in;
  45. }
  46.  
  47.  
  48. ostream & operator << (ostream & out , const Triangle & tri)
  49. {
  50.     out << tri.node1[0] << " " << tri.node2[1] << " " << tri.node3[2];
  51.  
  52.     return out;
  53. }
  54.  
  55. int main()
  56. {
  57.     std::vector<Point> p;
  58.  
  59.     ifstream in ("cuba.xyz", ios::in);
  60.  
  61.     if (!in)
  62.     {
  63.         cout << "could not open" << endl;
  64.         return 1;
  65.     }
  66.  
  67.     Point point;
  68.  
  69.     while (in >> point)
  70.     {
  71.         p.push_back(point);
  72.     }
  73.  
  74.  
  75.     std::vector<Tin> t;
  76.  
  77.     ifstream in ("cuba.tin", ios::in);
  78.  
  79.     if (!in)
  80.     {
  81.         cout << "could not open" << endl;
  82.         return 1;
  83.     }
  84.  
  85.     Tin tin;
  86.  
  87.     while (in >> tin)
  88.     {
  89.         t.push_back(tin);
  90.     }
  91.  
  92.     for (int i=0; i<p.size(); i++)
  93.     {
  94.         cout << p[i] << endl;
  95.     }
  96.  
So any idea on dealing with the matters? Or should i use pointer?

Any help will be appreciated.
Mar 19 '07 #13

Post your reply

Sign in to post your reply or Sign up for a free account.