Archived

This topic is now archived and is closed to further replies.

Text file parsing

This topic is 5301 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I need to open a text file (an .asc file actually) and parse out the vertex data and index data. However, I have zero experience with c++ file i/o or tokenizing. Could someone offer some insight, or offer a link to a good tutorial?

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Check this site out:
http://www.opengroup.org/onlinepubs/007908799/xsh/stdio.h.html

There I hope that helps a little you can also try using iostream.h just search for it on google.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Ok no sweat...check these two out:

http://www.cprogramming.com/tutorial/lesson10.html
http://www.cpp-home.com/FileIO_tutorial.php

Search for "file I/O tutorial" or something like that on google, you might find something there...Though the only page I found useful for file I/O was the first one I gave you. Anybody else got links to better tutorials?

Share this post


Link to post
Share on other sites
Okay, here''s what I have so far:


int loadASC(char *path) //load ASC model data

{
FILE *pASC;
int filesize;
char *buffer;

int vindex;

pASC = fopen(path, "rb");
if (pASC == NULL)
return 0;

fseek(pASC, 0, SEEK_END);
filesize = ftell(pASC);
fseek(pASC, 0, SEEK_SET);

buffer = (char*)malloc(filesize + 1);
fread(buffer, sizeof(char), filesize, pASC);
}


I''ve read the whole thing into the buffer, but how do I go about rooting around the text stored in the buffer?

Share this post


Link to post
Share on other sites
You''re reading that file in binary mode, not ASCII mode. You probably want to replace

pASC = fopen(path, "rb");
with
pASC = fopen(path, "r");

After you''ve read in the file (and doing it all at once isn''t the best idea since it might require a lot of memory for large files) the first character is in buffer[0], the second in buffer[1], and so on. So, determine the first character or substring you wish to find in buffer and use the string functions to find a pointer to that point in buffer. For example, say you want to find the first occurance of ''vertex'' in the buffer. You''d use the strstr function:

char* ptr;
ptr = strstr(buffer, "vertex");

Now, ptr point to the first occurance of the string ''vertex'' in buffer. ptr[0] = ''v'', ptr[1] = ''e'' and so on. If you want to look for the first character, such as an asterisk, use strchr.

ptr = strchr(buffer, ''*'');

And work through the buffer like that. I find it easier to parse a file as you read it in instead of parsing a buffer in memory, but that might just be me.

Share this post


Link to post
Share on other sites
So THAT's what the "rb" is! Thanks a lot guys!

I agree it would be easier to parse through the text as it's read in, but this will eventually be adapted to read binary model data rather than ascii model data. I understand where you're coming from though.

[edited because it included a stupid question that was already answered]

[edited by - tmoneyksu on June 5, 2003 10:57:53 AM]

[edited by - tmoneyksu on June 5, 2003 11:03:43 AM]

Share this post


Link to post
Share on other sites
quote:
Original post by tmoneyksu
I said c++, but c works. As long as it reads, it''s fine for me. Now that I can scan throught the file, how do I convert chars to integers and floats?


use atoi and atof respectively. Just pass them the address of the first character in the string that represents the number. The functions will return an int or a float.

Share this post


Link to post
Share on other sites
The proper C way of doing that is using fscanf to convert the characters as they're read, not afterwards with atoi and atof.

I strongly suggest you use C++ style I/O instead of C style, since C style comes with a lot of headaches. For example with C style every time you read a value from a file or from the keyboard you have to specify its type, like this:

// read an integer (%i) from fp into myVariable
fscanf(fp, "%i", &myVariable);

Now what if you change the type of myVariable to a float? You have to change "%i" all over the place or you're likely to get a nasty crash and/or incorrect values.

In C++ the syntax is just:

someFile >> myVariable;

The syntax is the same for any basic type like bool, int, float, double, etc. so you can change a variable's type transparently in your code.

The other big advantage is from reading data into structs/classes. You can override the >> operator for C++ style I/O and fill in a whole struct from a file in one swoop.


struct S
{
int var1;
float var2;
bool var3;

// I forget the exact function signature but it's something like this

istream & operator >> (istream & input)
{
return input >> var1 >> var2 >> var3;
}
};

S s;
someStream >> s;


Doing something like this with C style I/O is a complete pain, you have to read in each element individually. Even if you make a wrapper function that does it for you it will have a different syntax from the normal fscanf and it will suffer from the type problems I mentioned above.

I forgot to mention the C++ code I've been showing is part of what's typically called the C++ streams library. It's in standard headers like fstream, iostream. You should be able to find references all over the web if you want to learn.

[edited by - Dobbs on June 5, 2003 12:27:09 PM]

Share this post


Link to post
Share on other sites
Okay, now I''m totally lost again. Let me supply some data to let you all know what I''m trying to do.


Named object: "Box01"
Tri-mesh, Vertices: 8 Faces: 12
Vertex List:
Vertex 0: X:0.000000 Y:20.250000 Z:10.125000
Vertex 1: X:0.000000 Y:0.250000 Z:10.125000
Vertex 2: X:20.250000 Y:20.250000 Z:10.125000
Vertex 3: X:20.250000 Y:0.250000 Z:10.125000
Vertex 4: X:20.250000 Y:20.250000 Z:-10.125000
Vertex 5: X:20.250000 Y:0.250000 Z:-10.125000
Vertex 6: X:0.000000 Y:20.250000 Z:-10.125000
Vertex 7: X:0.000000 Y:0.250000 Z:-10.125000
Face list:
Face 0: A:0 B:1 C:2 AB:1 BC:1 CA:1
Smoothing: 1
Face 1: A:1 B:3 C:2 AB:1 BC:1 CA:1
Smoothing: 1
Face 2: A:2 B:3 C:4 AB:1 BC:1 CA:1
Smoothing: 2
Face 3: A:3 B:5 C:4 AB:1 BC:1 CA:1
Smoothing: 2
Face 4: A:4 B:5 C:6 AB:1 BC:1 CA:1
Smoothing: 1
Face 5: A:5 B:7 C:6 AB:1 BC:1 CA:1
Smoothing: 1
Face 6: A:6 B:7 C:0 AB:1 BC:1 CA:1
Smoothing: 2
Face 7: A:7 B:1 C:0 AB:1 BC:1 CA:1
Smoothing: 2
Face 8: A:6 B:0 C:4 AB:1 BC:1 CA:1
Smoothing: 4
Face 9: A:0 B:2 C:4 AB:1 BC:1 CA:1
Smoothing: 4
Face 10: A:1 B:7 C:3 AB:1 BC:1 CA:1
Smoothing: 4
Face 11: A:7 B:5 C:3 AB:1 BC:1 CA:1
Smoothing: 4


This is, of course, and .asc file. What I need to do is get the number of vertices, the vertex indices, the vertex coordinates, and the face data out of the file, and into structures in my program. What is the best way to go about doing this?

Share this post


Link to post
Share on other sites
To find the number of vertices:


//buffer must be null terminated or strstr won't work properly

char* ptr = buffer;
char temp_num[10];
int num_vert, i;

ptr = strstr(ptr, "Vertices:"); //not positive strstr will work if you assign the return value to the same pointer you pass in.

ptr += 10; // ptr now points to the first digit in the number of vertices.

i = 0;

while(ptr[i] != ' '){ // search for the space after the value

temp_num[i] = ptr[i];
i++;
}
num_vert = atoi(temp_num, 10);


The same technique can be done for every variable in your file. Again, this isn't the ideal way to solve the problem, but it will work.

Jedyte: The original poster was the one who first posted C code so i'm just going with it.

As mentioned, the C style input has some drawbacks. It does, however, tend to be a little quicker than the C++ i/o. Either way, it's almost always easier to parse the file as you read it from the disk. For example, as reading in the vertex data from the disk, you can use a command like

fscanf(pASC, "X:%f\tY:%f\t%f\n", &x, &y, &z); //or the equivalent C++ type code

to read in an entire line of variables and convert them to floating point numbers instead of the cumbersome way of extracting them from a giant buffer.

[edited by - kdogg on June 6, 2003 1:10:47 AM]

Share this post


Link to post
Share on other sites
This will be of no use to you at all probably, but does anyone know the Quake 3 Shader files? I wrote a few classes to parse something similar to that for my own projects and were an absolute god-send I tell you. The parsing routines aren''t that well written, but they work to great effect. Maybe it might be helpful to look at them?

The URL is http://www.gibbersoft.tk/ and it''s on the downloads page, titled Roller.

Share this post


Link to post
Share on other sites