473,387 Members | 1,391 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,387 software developers and data experts.

Reading From Files in c++

Hi,
I moved to c++ from c, and wanted to know what the best way to read data
from files is in c++. Any thoughts? fscanf() is possible but fairly painful!

Regards

Michael
Jul 22 '05 #1
18 2197
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

//File Start:

*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000

Jul 22 '05 #2
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

//File Start:

*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000

Jul 22 '05 #3
Michael wrote:
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

<snip>


Check out iostreams, especially std::ifstream.
They can be used just like std::cout.

- Pete
Jul 22 '05 #4
Michael wrote:
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

<snip>


Check out iostreams, especially std::ifstream.
They can be used just like std::cout.

- Pete
Jul 22 '05 #5

"Michael" <sl***********@hotmail.com> wrote in message
news:c4**********@hercules.btinternet.com...
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

//File Start:

*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000


#include <algorithm>
using std::copy;

#include <cstdlib>

#include <fstream>
using std::ifstream;

#include <iostream>
using std::cerr;
using std::cout;

#include <iterator>
using std::back_inserter;
using std::istream_iterator;
using std::ostream_iterator;

#include <string>
using std::string;

#include <vector>
using std::vector;
int main()
{
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};

std::string filename("data.txt");
ifstream input(filename.c_str());
bool err(!input);

if(!err)
{
vector<string> data;

copy(istream_iterator<string>(input),
istream_iterator<string>(),
back_inserter(data));

if(err = (!input && !input.eof()))
cerr << "Error reading input file " << filename << '\n';

cout << "Data read:\n";

copy(data.begin(), data.end(),
ostream_iterator<string>(cout, "\n"));
}
else
cerr << "Cannot open input file " << filename << '\n';

return status[err];
}
-Mike
Jul 22 '05 #6

"Michael" <sl***********@hotmail.com> wrote in message
news:c4**********@hercules.btinternet.com...
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);

it just looks very messy!

TIA

Michael.

//File Start:

*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000


#include <algorithm>
using std::copy;

#include <cstdlib>

#include <fstream>
using std::ifstream;

#include <iostream>
using std::cerr;
using std::cout;

#include <iterator>
using std::back_inserter;
using std::istream_iterator;
using std::ostream_iterator;

#include <string>
using std::string;

#include <vector>
using std::vector;
int main()
{
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};

std::string filename("data.txt");
ifstream input(filename.c_str());
bool err(!input);

if(!err)
{
vector<string> data;

copy(istream_iterator<string>(input),
istream_iterator<string>(),
back_inserter(data));

if(err = (!input && !input.eof()))
cerr << "Error reading input file " << filename << '\n';

cout << "Data read:\n";

copy(data.begin(), data.end(),
ostream_iterator<string>(cout, "\n"));
}
else
cerr << "Cannot open input file " << filename << '\n';

return status[err];
}
-Mike
Jul 22 '05 #7
Michael wrote:
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);


You should never use *any* of these! This is a terrible bug, and a
likely security hole. Never, never use %s or %[ without a (correct)
field width. There's nothing to prevent someone from overflowing the
buffer, in which case the best you can hope for is a program crash. The
comp.lang.c FAQ has some good information on this, and reasons why you
should avoid the scanf() functions even in C. In C++ there's usually no
reason to even consider scanf(), printf(), and friends. The stream
classes are more flexible and much safer.

However, the problem with the code above is (unfortunately) also easy to
introduce when using streams:

char buff[some_size];
std::cin >> buff; // SERIOUS ERROR!

Again, there's nothing to prevent the buffer from being overflowed. Such
an overflow can have all kind of terrible consequences -- in particular,
it can often be exploited by a malicious person (or program) to gain
control of the system. Problems similar to this are probably the single
biggest cause of security holes that allow worms to infect systems.

This is why "strings" should never be represented as character arrays,
unless you know what you are doing and are very, very careful. In C++,
use std::string instead:

std::string buff;
std::cin >> buff; // Go ahead, TRY to overflow it!

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #8
Michael wrote:
so for example reading in the file...

without many
fscanf(fp,"%s",variableAddr);


You should never use *any* of these! This is a terrible bug, and a
likely security hole. Never, never use %s or %[ without a (correct)
field width. There's nothing to prevent someone from overflowing the
buffer, in which case the best you can hope for is a program crash. The
comp.lang.c FAQ has some good information on this, and reasons why you
should avoid the scanf() functions even in C. In C++ there's usually no
reason to even consider scanf(), printf(), and friends. The stream
classes are more flexible and much safer.

However, the problem with the code above is (unfortunately) also easy to
introduce when using streams:

char buff[some_size];
std::cin >> buff; // SERIOUS ERROR!

Again, there's nothing to prevent the buffer from being overflowed. Such
an overflow can have all kind of terrible consequences -- in particular,
it can often be exploited by a malicious person (or program) to gain
control of the system. Problems similar to this are probably the single
biggest cause of security holes that allow worms to infect systems.

This is why "strings" should never be represented as character arrays,
unless you know what you are doing and are very, very careful. In C++,
use std::string instead:

std::string buff;
std::cin >> buff; // Go ahead, TRY to overflow it!

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #9
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000
*MATERIAL_SELFILLUM 0.0000
*MATERIAL_FALLOFF In
*MATERIAL_XP_TYPE Filter
}
*SUBMATERIAL 1 {
*MATERIAL_NAME "Bottom"
*MATERIAL_CLASS "Standard"

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??
I'm not yet a great fan of streams :-)

Thanks & Regards

Michael
Jul 22 '05 #10
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000
*MATERIAL_SELFILLUM 0.0000
*MATERIAL_FALLOFF In
*MATERIAL_XP_TYPE Filter
}
*SUBMATERIAL 1 {
*MATERIAL_NAME "Bottom"
*MATERIAL_CLASS "Standard"

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??
I'm not yet a great fan of streams :-)

Thanks & Regards

Michael
Jul 22 '05 #11
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)
Removing relevant code never adds clarity.

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
<snip>

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What about printing the string? Debuggers don't always show things
correctly.
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??


You can do that. >> is usually used for single input items, not
collections, so it's a bit unconventional, but it should work. You could
also just have a Read() member that does the same thing that the
operator >> would do.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #12
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)
Removing relevant code never adds clarity.

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
<snip>

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What about printing the string? Debuggers don't always show things
correctly.
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??


You can do that. >> is usually used for single input items, not
collections, so it's a bit unconventional, but it should work. You could
also just have a Read() member that does the same thing that the
operator >> would do.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.
Jul 22 '05 #13

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:0b****************@newsread2.news.pas.earthli nk.net...
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo: (Header includes removed for clarity)


Removing relevant code never adds clarity.

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0


<snip>

Now the code compiles fine, but when I step through it in the debugger, the first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger gives its value as ???


What about printing the string? Debuggers don't always show things
correctly.
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??


You can do that. >> is usually used for single input items, not
collections, so it's a bit unconventional, but it should work. You could
also just have a Read() member that does the same thing that the
operator >> would do.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.



Hi,
It seems that

ifstream input(FileName.c_str());
string str;

input >> str;
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
* Step to Here: str is ??? */

gives problems but
ifstream input(FileName.c_str());
string str1,str2;

input >> str1
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str2
* Step to Here: str is 200

works as expected. Is it nessesary to flush the str before entering new
data?

Michael
Jul 22 '05 #14

"Kevin Goodsell" <us*********************@neverbox.com> wrote in message
news:0b****************@newsread2.news.pas.earthli nk.net...
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo: (Header includes removed for clarity)


Removing relevant code never adds clarity.

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0


<snip>

Now the code compiles fine, but when I step through it in the debugger, the first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger gives its value as ???


What about printing the string? Debuggers don't always show things
correctly.
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??


You can do that. >> is usually used for single input items, not
collections, so it's a bit unconventional, but it should work. You could
also just have a Read() member that does the same thing that the
operator >> would do.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.



Hi,
It seems that

ifstream input(FileName.c_str());
string str;

input >> str;
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
* Step to Here: str is ??? */

gives problems but
ifstream input(FileName.c_str());
string str1,str2;

input >> str1
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str2
* Step to Here: str is 200

works as expected. Is it nessesary to flush the str before entering new
data?

Michael
Jul 22 '05 #15
>
Hi,
It seems that

ifstream input(FileName.c_str());
string str;

input >> str;
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
* Step to Here: str is ??? */

gives problems but
ifstream input(FileName.c_str());
string str1,str2;

input >> str1
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str2
* Step to Here: str is 200

works as expected. Is it nessesary to flush the str before entering new
data?

Michael


No it is not necessary. Either you have a bugged implementation of the
standard library, or you are making some other mistake. Most likely is that
what Kevin told you is true, your debugger is not displaying the string
values correctly. I found exactly the same with my debugger (also MSVC++).

john

Jul 22 '05 #16
>
Hi,
It seems that

ifstream input(FileName.c_str());
string str;

input >> str;
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
* Step to Here: str is ??? */

gives problems but
ifstream input(FileName.c_str());
string str1,str2;

input >> str1
/*Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str2
* Step to Here: str is 200

works as expected. Is it nessesary to flush the str before entering new
data?

Michael


No it is not necessary. Either you have a bugged implementation of the
standard library, or you are making some other mistake. Most likely is that
what Kevin told you is true, your debugger is not displaying the string
values correctly. I found exactly the same with my debugger (also MSVC++).

john

Jul 22 '05 #17
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000
*MATERIAL_SELFILLUM 0.0000
*MATERIAL_FALLOFF In
*MATERIAL_XP_TYPE Filter
}
*SUBMATERIAL 1 {
*MATERIAL_NAME "Bottom"
*MATERIAL_CLASS "Standard"

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??
I'm not yet a great fan of streams :-)

Thanks & Regards

Michael


Sorry about posting so late, but I've had other work to do.

You are parsing a file that is made up of text lines. The text lines
are delineated by a newline character ('\n'). In these scenarios,
the easier approach would be to read in the whole text line into
a string, then extract the information from a string. The std::string
has better facilities for searching than the I/O streams do.

Here is a sample to get you started:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using std::ifstream;
using std::string;
using std::cout;
using std::endl;
using std::cerr;
int main(void)
{
ifstream source_file("Source_File.txt");

if (!source_file)
{
cerr << "Error opening \"Source_File.txt\"" << endl;
return EXIT_FAILURE;
}

string text;
string::size_type posn;
while (getline(source_file, text))
{
posn = text.find("3DSMAX_ASCIIEXPORT");
if (posn == string::npos)
{
continue; // Skip lines until that one is found.
}
posn = text.find_first_of(" \t"); // skip past the identifier.
istringstream temp_string_stream(text.substr(posn));
int value;
temp_string_stream >> value; // extract the value.
cout << "Value found is: " << value << endl;
}

return EXIT_SUCCESS;
}
A next step in this evolution would be to have a std::map
container of <string, function pointer>. The strings would
be the identifiers in the data file. The function pointer
would point to a function that processed the identifier.

Example:
#include <map>
using std::map;
typedef void (*Function_Ptr)(const string& s,
const string::size_type& posn);

void AsciiExport(const string& s, const size_type& posn)
{
istringstream temp_string_stream(s.substr(posn));
int value;
temp_string_stream >> value; // extract the value.
cout << "Value found is: " << value << endl;
return;
}

typedef std::map<string, Function_Ptr> Processing_Map;

Processing_Map function_map;

int main(void)
{
function_map["3DSMAX_ASCIIEXPORT"] = AsciiExport;
ifstream source_file("Source_File.txt");

if (!source_file)
{
cerr << "Error opening \"Source_File.txt\"" << endl;
return EXIT_FAILURE;
}

string text;
string::size_type posn;
while (getline(source_file, text))
{
posn = text.find("3DSMAX_ASCIIEXPORT");
if (posn == string::npos)
{
continue; // Skip lines until that one is found.
}
string::size_type end_posn = text.find_first_of(" \t", posn);
Processing_Map::iterator iter;
iter = function_map.find(text.substr(posn, end_posn - posn));
if (iter != function_map.end())
{
(iter->second)(text, end_posn); // execute the processing
// function.
}
}
return EXIT_SUCCESS;
}

After this step, you may want to research the Factory design
pattern (search the web for "Design Pattern Factory").

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #18
Michael wrote:
Hi,
I have tried to implement it but get a problem, thuis is my code at the mo:
(Header includes removed for clarity)

{
string str
char junk[100];
int MaxLineLength =100;
const int status[] = {EXIT_SUCCESS, EXIT_FAILURE};
ifstream input(FileName.c_str());
bool err(!input);

input >> str;
/* Step to Here: str is *3DSMAX_ASCIIEXPORT */
input >> str;
/* Step to Here: str is ??? */
input >> str;
}

start of Source File:
*3DSMAX_ASCIIEXPORT 200
*COMMENT "AsciiExport Version 2.00 - Tue Apr 06 19:00:45 2004"
*SCENE {
*SCENE_FILENAME "City_vertex_paint.max"
*SCENE_FIRSTFRAME 0
*SCENE_LASTFRAME 500
*SCENE_FRAMESPEED 30
*SCENE_TICKSPERFRAME 160
*SCENE_BACKGROUND_STATIC 0.0000 0.0000 0.0000
*SCENE_AMBIENT_STATIC 0.9804 0.9804 0.9804
}
*MATERIAL_LIST {
*MATERIAL_COUNT 13
*MATERIAL 0 {
*MATERIAL_NAME "SF Building"
*MATERIAL_CLASS "Multi/Sub-Object"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*NUMSUBMTLS 6
*SUBMATERIAL 0 {
*MATERIAL_NAME "Top"
*MATERIAL_CLASS "Standard"
*MATERIAL_AMBIENT 0.1000 0.1000 0.1000
*MATERIAL_DIFFUSE 0.0392 0.0392 0.0392
*MATERIAL_SPECULAR 0.9000 0.9000 0.9000
*MATERIAL_SHINE 0.2500
*MATERIAL_SHINESTRENGTH 0.0500
*MATERIAL_TRANSPARENCY 0.0000
*MATERIAL_WIRESIZE 1.0000
*MATERIAL_SHADING Blinn
*MATERIAL_XP_FALLOFF 0.0000
*MATERIAL_SELFILLUM 0.0000
*MATERIAL_FALLOFF In
*MATERIAL_XP_TYPE Filter
}
*SUBMATERIAL 1 {
*MATERIAL_NAME "Bottom"
*MATERIAL_CLASS "Standard"

Now the code compiles fine, but when I step through it in the debugger, the
first string reads: *3DSMAX_ASCIIEXPORT, but the next time MSVC++ debugger
gives its value as ???
What am i doing wrong?
Also what is the best way to read this into relevant structures, If i define
a class material for instance, can i overload the >> operator for it and
call that after the reading function had read "*MATERIAL 0"??
I'm not yet a great fan of streams :-)

Thanks & Regards

Michael


Sorry about posting so late, but I've had other work to do.

You are parsing a file that is made up of text lines. The text lines
are delineated by a newline character ('\n'). In these scenarios,
the easier approach would be to read in the whole text line into
a string, then extract the information from a string. The std::string
has better facilities for searching than the I/O streams do.

Here is a sample to get you started:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using std::ifstream;
using std::string;
using std::cout;
using std::endl;
using std::cerr;
int main(void)
{
ifstream source_file("Source_File.txt");

if (!source_file)
{
cerr << "Error opening \"Source_File.txt\"" << endl;
return EXIT_FAILURE;
}

string text;
string::size_type posn;
while (getline(source_file, text))
{
posn = text.find("3DSMAX_ASCIIEXPORT");
if (posn == string::npos)
{
continue; // Skip lines until that one is found.
}
posn = text.find_first_of(" \t"); // skip past the identifier.
istringstream temp_string_stream(text.substr(posn));
int value;
temp_string_stream >> value; // extract the value.
cout << "Value found is: " << value << endl;
}

return EXIT_SUCCESS;
}
A next step in this evolution would be to have a std::map
container of <string, function pointer>. The strings would
be the identifiers in the data file. The function pointer
would point to a function that processed the identifier.

Example:
#include <map>
using std::map;
typedef void (*Function_Ptr)(const string& s,
const string::size_type& posn);

void AsciiExport(const string& s, const size_type& posn)
{
istringstream temp_string_stream(s.substr(posn));
int value;
temp_string_stream >> value; // extract the value.
cout << "Value found is: " << value << endl;
return;
}

typedef std::map<string, Function_Ptr> Processing_Map;

Processing_Map function_map;

int main(void)
{
function_map["3DSMAX_ASCIIEXPORT"] = AsciiExport;
ifstream source_file("Source_File.txt");

if (!source_file)
{
cerr << "Error opening \"Source_File.txt\"" << endl;
return EXIT_FAILURE;
}

string text;
string::size_type posn;
while (getline(source_file, text))
{
posn = text.find("3DSMAX_ASCIIEXPORT");
if (posn == string::npos)
{
continue; // Skip lines until that one is found.
}
string::size_type end_posn = text.find_first_of(" \t", posn);
Processing_Map::iterator iter;
iter = function_map.find(text.substr(posn, end_posn - posn));
if (iter != function_map.end())
{
(iter->second)(text, end_posn); // execute the processing
// function.
}
}
return EXIT_SUCCESS;
}

After this step, you may want to research the Factory design
pattern (search the web for "Design Pattern Factory").

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #19

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Olivier Maurice | last post by:
Hi all, I suppose some of you know the program Redmon (type redmon in google, first result). This neat little tool allows to hook up any functionality to a printer by putting the file printed...
19
by: Lionel B | last post by:
Greetings, I need to read (unformatted text) from stdin up to EOF into a char buffer; of course I cannot allocate my buffer until I know how much text is available, and I do not know how much...
1
by: Magnus | last post by:
allrite folks, got some questions here... 1) LAY-OUT OF REPORTS How is it possible to fundamentaly change the lay-out/form of a report in access? I dont really know it that "difficult", but...
6
by: Rajorshi Biswas | last post by:
Hi folks, Suppose I have a large (1 GB) text file which I want to read in reverse. The number of characters I want to read at a time is insignificant. I'm confused as to how best to do it. Upon...
2
by: nnimod | last post by:
Hi. I'm having trouble reading some unicode files. Basically, I have to parse certain files. Some of those files are being input in Japanese, Chinese etc. The easiest way, I figured, to distinguish...
7
by: jccorreu | last post by:
I've got to read info from multiple files that will be given to me. I know the format and what the data is. The thing is each time we run the program we may be using a differnt number of files,...
6
by: arne.muller | last post by:
Hello, I've come across some problems reading strucutres from binary files. Basically I've some strutures typedef struct { int i; double x; int n; double *mz;
10
by: Tyler | last post by:
Hello All: After trying to find an open source alternative to Matlab (or IDL), I am currently getting acquainted with Python and, in particular SciPy, NumPy, and Matplotlib. While I await the...
5
blazedaces
by: blazedaces | last post by:
Ok, so you know my problem, java is running out of memory reading with SAX, the event-based xml parser intended more-so than DOM for extremely large files. I'll try to explain what I've been doing...
4
by: Miner Jeff | last post by:
Hello, I have a basic question about reading files. I have several data files where the filenames are identical except for a short (3 character) prefix. I inherited this code and the person who...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.