codetoad.com
  ASP Shopping CartForum & BBS
  - all for $20 from CodeToad Plus!
  
  Home || ASP | ASP.Net | C++/C# | DHTML | HTML | Java | Javascript | Perl | VB | XML || CodeToad Plus! || Forums || RAM 
Search Site:
Search Forums:
  How can I read ASCII data file in C++  long at 06:27 on Sunday, August 07, 2005
 

Hi everyone!

I am new to this forum. I got a stuck in my work. That is my question I am gonna raise in here. I got a data file in ASCII format (got from recorder for measuring 3 channels of volt vesus time). When I open = wordpad or notepad it shows a few header lines, followed by 4 colums expressing Time, Volt1, Volt2, Volt3 (in volt unit) like shown below:

Header (few lines)
Time Volt1 Volt2 Volt3
02:02:30.500 12.33 23.12 33.22
02:02:30.501 12.35 23.14 33.55
............ ..... ..... .....
............ ..... ..... .....
............ ..... ..... .....

going on untill the end. The Time colum is hh:mm:ss.milisecond. I wonder how I can bypass header lines (say 5 lines), then go to read all data in 4 colums into 4 arrays then I can process them in C++. Moreover I dont know how these number will be understood, say to be binary bits (0101.. format) or number (as seen) or string, when being input to the C++ program. Because the recorder was set to scan at 40KHz therefore the data file is so huge (above 15 MB) to read in excell. I raise an additional question here of which program should I use as the loader for the processed data.

Thank you very much and hope to get soon reply

Best regards


  Re: How can I read ASCII data file in C++  Samir at 14:02 on Saturday, August 20, 2005
 

OK, I felt really bored today so I wrote you a simple program to read your file. But you should be suprised anyone has replied because your question was very general and you did not post any code to correct or add to. But anyways, you're lucky I was bored. Here's the code I came up with. It's not very flexible, but can read the kinds of files you want. If you have any questions, just ask (make them more specific questions this time please :-) ). If you feel the code is too long, just remove the comments, the code is not that big.

--------START OF CODE--------------
#include <iostream>

// Needed for the ifstream class
#include <fstream>

// Needed for the setw stream manipulator
#include <iomanip>

#include <vector>

using namespace std;

// A structure used to store time
struct Time {
unsigned int hours;
unsigned int minutes;
float seconds;
};

int main()
{
// STEP1: OPEN THE FILE TO BE READ

// ifstream is an object reprenting an input file stream
// it can be used just like you use cin but reads a file instead of the standard input stream
// To open a file with it, specify the name of the file in the parenthesis
// alternatively, you could write:
// ifstream file_to_read;
// file_to_read.open("/forum/data.txt");
// The file does not have to be .txt, any file name will do, like "hello", as long as its ASCII
// (Binary file can also be accepted, it's just that the program I wrote does not process binary

ifstream file_to_read("/forum/data.txt");
const int max_num_of_char_in_a_line = 512,// Maximum number of characters expected in a single line in the header
num_of_header_lines = 2; // Number of header files to skip

// STEP2: SKIP ALL THE HEADER LINES

for(int i = 0; i < num_of_header_lines; ++i)

// The ignore member function ignores the number of characters in its first parameter
// or until the character in the 2nd paramter is reached. In this case, the newline character.

file_to_read.ignore(max_num_of_char_in_a_line, '\n');

// STEP3: READ THE FILE AND STORE THE DATA READ INTO ARRAYS

// These are arrays to store the processed data.
// vector objects are being used instead of the traditional array
// because vector objects can grow dynamically in size at runtime
// while traditional arrays have a fixed size.
// (ex: Time time_array[50] can hold 50 Time structures at max
// Note: The type of elements stored in a vector is specified in the
// template argument (that is between < and >)

vector<Time> time_array;
vector<float> volt1_array,
volt2_array,
volt3_array;

// Keep reading while the End Of File character is NOT reached

while(!file_to_read.eof()) {
Time time_read;

// Read 2 characters and store them in time_read.hours
// P.S.: the setw stream manupulator (stands for set width) tells the stream to read only 2 characters

file_to_read >> setw(2) >> time_read.hours;

// Ignore one character. In our case, the : character

file_to_read.ignore(1);
file_to_read >> setw(2) >> time_read.minutes;

file_to_read.ignore(1);
file_to_read >> time_read.seconds;

// Store the Time structure read, time_read, into the end of time_array

time_array.push_back(time_read);

float volt1,
volt2,
volt3;

// Read the volt values and store them in volt1, volt2 and volt3

// Remeber that the default behaviour of a stream is to read until the space character is reached

file_to_read >> volt1 >> volt2 >> volt3;

// Store each volt value into the appropriate array

volt1_array.push_back(volt1);
volt2_array.push_back(volt2);
volt3_array.push_back(volt3);
}

// STEP4: USE THE DATA READ AND STORED IN THE ARRAY HOW EVER YOU WANT
// I JUST PRINT THEM TO THE SCREEN

// Print all the Time structuers read

cout << "Times read are:\n";

// Notice how a vector object knows its size and can be retreived by and call to the size() member function

for(int i = 0; i < time_array.size(); ++i)
cout << time_array.hours << ':' << time_array.minutes << ':' << time_array.seconds << '\n';

// Print all the volts read

cout << "\nVolts1 are:\n";

for(int i = 0; i < volt1_array.size(); ++i)
cout << volt1_array << '\n';

cout << "\nVolts2 are:\n";

for(int i = 0; i < volt2_array.size(); ++i)
cout << volt2_array << '\n';

cout << "\nVolts1 are:\n";

for(int i = 0; i < volt3_array.size(); ++i)
cout << volt3_array << '\n';

return 0;
}

--------END OF CODE--------------

  Re: How can I read ASCII data file in C++  farnaz at 13:27 on Monday, October 17, 2005
 

Im new to C++ and cant seem to get your code to compile in .Net 2003. Is there any header files that are missing? Which compiler did you use to compile the code?

Thanks

  Re: How can I read ASCII data file in C++  Samir at 13:37 on Monday, October 17, 2005
 

I've used the freely available compiler from the Microsoft C++ toolkit 2003, which is basically the same compiler that ships with Visual Studio 2003 Professional Edition. So some characters must be missing when you copied and pasted it.

The code I've written is all compliant with the ISO C++ Standard, so no additional headers are needed, and any C++ compiler should compile it.

In any case, post the errors that you get from your compiler to see if I can help.

  Re: How can I read ASCII data file in C++  farnaz at 10:51 on Tuesday, October 18, 2005
 

Ok there are alot of errors but to list a few, here they are:

warning C4018: '<' : signed/unsigned mismatch

error C2039: 'hours' : is not a member of 'std::vector<_Ty>'
with
[
_Ty=Time
]

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::vector<_Ty>' (or there is no acceptable conversion)
with
[
_Ty=float
]

These 3 errors seem to be repeated about 3 times each and i dont know why as i just copied what you had.
Please help!

Thanks!

  Re: How can I read ASCII data file in C++  Samir at 16:48 on Tuesday, October 18, 2005
 

OK, I see what is wrong now.

Lines that are like so:

cout << time_array.hours << ':' << time_array.minutes << ':' << time_array.seconds << '\n';

are supposed to be like so:

cout << time_array[j].hours << ':' << time_array[j].minutes << ':' << time_array[j].seconds << '\n';


This happened because when I copied and pasted the code, the forum converted [z] into italic characters (notice them in my previous code) when the character between brackets is an i instead of the z. So now I replaced my i variables with j ones to bypass the way this forum parses text.

Also, the warning is not important, but if you want to get rid of it, you can replace the int type in each for loop by and unsigned int, or better yet, by vector<T>::size_type. But since you're new to C++, I'm gonna save you the headach of figuring out what all this means, and instead, give you my code again, but this time, pasted in quotes so no characters are interpreted wrongly (I hope).


#include <iostream>

// Needed for the ifstream class
#include <fstream>

// Needed for the setw stream manipulator
#include <iomanip>

#include <vector>

using namespace std;

// A structure used to store time
struct Time {
unsigned int hours;
unsigned int minutes;
float seconds;
};

int main()
{
// STEP1: OPEN THE FILE TO BE READ

// ifstream is an object reprenting an input file stream
// it can be used just like you use cin but reads a file instead of the standard input stream
// To open a file with it, specify the name of the file in the parenthesis
// alternatively, you could write:
// ifstream file_to_read;
// file_to_read.open("/forum/data.txt");
// The file does not have to be .txt, any file name will do, like "hello", as long as its ASCII
// (Binary file can also be accepted, it's just that the program I wrote does not process binary
ifstream file_to_read("/forum/data.txt");
const int max_num_of_char_in_a_line = 512,// Maximum number of characters expected in a single line in the header
num_of_header_lines = 2; // Number of header files to skip

// STEP2: SKIP ALL THE HEADER LINES

for(int j = 0; j < num_of_header_lines; ++j)
// The ignore member function ignores the number of characters in its first parameter
// or until the character in the 2nd paramter is reached. In this case, the newline character.
file_to_read.ignore(max_num_of_char_in_a_line, '\n');

// STEP3: READ THE FILE AND STORE THE DATA READ INTO ARRAYS

// These are arrays to store the processed data.
// vector objects are being used instead of the traditional array
// because vector objects can grow dynamically in size at runtime
// while traditional arrays have a fixed size.
// (ex: Time time_array[50] can hold 50 Time structures at max
// Note: The type of elements stored in a vector is specified in the
// template argument (that is between < and >)
vector<Time> time_array;
vector<float> volt1_array,
volt2_array,
volt3_array;
// Keep reading while the End Of File character is NOT reached
while(!file_to_read.eof()) {
Time time_read;
// Read 2 characters and store them in time_read.hours
// P.S.: the setw stream manupulator tells the stream to read only 2 characters
file_to_read >> setw(2) >> time_read.hours;

// Ignore one character. In our case, the : character
file_to_read.ignore(1);
file_to_read >> setw(2) >> time_read.minutes;

file_to_read.ignore(1);
file_to_read >> time_read.seconds;

// Store the Time structure read, time_read, into the end of time_array
time_array.push_back(time_read);

float volt1,
volt2,
volt3;

// Read the volt values and store them in volt1, volt2 and volt3
// Remeber that the default behaviour of a stream is to read until the space character is reached
file_to_read >> volt1 >> volt2 >> volt3;

// Store each volt value into the appropriate array
volt1_array.push_back(volt1);
volt2_array.push_back(volt2);
volt3_array.push_back(volt3);
}

// STEP4: USE THE DATA READ AND STORED IN THE ARRAY HOW EVER YOU WANT
// I JUST PRINT THEM TO THE SCREEN

// Print all the Time structuers read
cout << "Times read are:\n";

// Notice how a vector object knows its size and can be retreived by and call to the size() member function
for(vector<Time>::size_type j = 0; j < time_array.size(); ++j)
cout << time_array[j].hours << ':' << time_array[j].minutes << ':' << time_array[j].seconds << '\n';

// Print all the volts read
cout << "\nVolts1 are:\n";

for(vector<float>::size_type j = 0; j < volt1_array.size(); ++j)
cout << volt1_array[j] << '\n';

cout << "\nVolts2 are:\n";

for(vector<float>::size_type j = 0; j < volt2_array.size(); ++j)
cout << volt2_array[j] << '\n';

cout << "\nVolts1 are:\n";

for(vector<float>::size_type j = 0; j < volt3_array.size(); ++j)
cout << volt3_array[j] << '\n';

return 0;
}



  Re: How can I read ASCII data file in C++  farnaz at 14:17 on Wednesday, October 19, 2005
 

Hi
Yes it compiles, thanks, but i noticed a few things, it does not output everything as expected.

-when i created a data.txt file with 2 rows of data, 3 rows was being outputted, where the 2nd row of dta was duplicated for some reason. I wonder why?
For example, read the following txt file and notice the output, where the last data set is outputted twice:

Header (few lines)
Time Volt1 Volt2 Volt3
02:02:30.500 12.33 23.12 33.22
02:02:30.501 12.35 23.14 33.55
03:04:01.503 12.70 24.00 33.33
06:01:06.600 12.12 24.24 37.37


-why are zeros ignored from the output?

The answer might be trivial but its midnight, and my brain is just too worn out.
Thanks again.

  Re: How can I read ASCII data file in C++  Samir at 18:27 on Wednesday, October 19, 2005
 


-when i created a data.txt file with 2 rows of data, 3 rows was being outputted, where the 2nd row of dta was duplicated for some reason. I wonder why?

I have read the data you gave me, it works just fine. There is just one very little thing wrong with the ouput. Before it outputs the 3rd column, it says "Volts1 are:" where it should say "Volts3 are:", but the data it outputs is correctly taken from column 3. To fix that little output error, change the cout line that is before the last for loop from this:

cout << "\nVolts1 are:\n";

to this:

cout << "\nVolts3 are:\n";



-why are zeros ignored from the output?

The ouput is by default, the way we write numbers on paper. If you where to write the number two on paper, would you write 2 or 02?...So this is why, by default, zeros on the left are not output since they are meaningless.

But if you want to show them your way, add these lines (once) before the cout statements.


cout.fill('0');
cout.precision(3);
cout.setf(ios::fixed);


cout.fill('0'); will fill empty spaces with zeros whenever you specify the output field width with setw (set width). So if you set the width to 2, and you ouptut 3, there is still one place on the left which will be filled with the character '0' to arrive at a width of 2.
Now, replace the 2nd for loop with this one:


for(vector<Time>::size_type j = 0; j < time_array.size(); ++j)
cout << setw(2) << time_array[j].hours << ':'
<< setw(2) << time_array[j].minutes << ':'
<< setw(6) << time_array[j].seconds << '\n';


We set the width of the first two numbers to two since we know that at max, the hours and minutes can consits of 2 digits. As for seconds, we specified the width to 6 because above, we specified the precision after the point to be 3 by writing cout.precision(3); and we are sure that 3 characters are gonna get output after the point even if there are less then 3 characters after it because we set the flag fixed with the statement cout.setf(ios::fixed);


The answer might be trivial but its midnight, and my brain is just too worn out.


Hehe...that happens to the best of us.


Thanks again.


Anytime...I just hope that you're actually learning something from all this, and not just copy pasting them without any knowledge of what is going on.

  Re: How can I read ASCII data file in C++  farnaz at 02:40 on Thursday, October 20, 2005
 

Hi

You mean your last row of data is not being outputted twice? How can that be, when it happens to mine?
I even have a print screen of it, bit i dont know how to attach it here.
I didnt change your code, so i should get you output.
hhmmmm......

  Re: How can I read ASCII data file in C++  farnaz at 12:01 on Thursday, October 20, 2005
 

Hi again,

I finally figured out why it was reading the last line twice, it was because in my text file, after entering the data, i had pressed Enter, which mean the program moved to the next line, and didnt find anything to read, so it printed out what was in buffer last.
Am i correct to assume that?

well, atleast its not repeating itself like before,

Thanks for your help, so much for my uni tutors, who get paid to confuse us even more.

Thanks!!!
:)

  Re: How can I read ASCII data file in C++  Samir at 16:59 on Thursday, October 20, 2005
 


I finally figured out why it was reading the last line twice, it was because in my text file, after entering the data, i had pressed Enter, which mean the program moved to the next line, and didnt find anything to read, so it printed out what was in buffer last.
Am i correct to assume that?


Yes, I think you are correct. And if you want the program to be able to handle that, i.e. to ignore empty lines, add these lines to the beginning of the while loop:


if(!isdigit(file_to_read.peek())) {
file_to_read.ignore();
continue;
}


Member function peek looks at the next character to read without removing it from the stream and we make sure that its a digit with the function isdigit, and in case it is not, we ignore it and continue to loop, otherwise, we proceed reading as before since the character is still there and was not removed by peek. This will premit you to put any number of empty lines, even between the correct lines, and they will be correctly ignored by the program.


Thanks!!!
:)


You're welcome :-)

  Re: How can I read ASCII data file in C++  one_ at 15:44 on Tuesday, June 27, 2006
 

I was trying to sp;lve my problem by using the stuff that you wrote here, BUT
I have a problem with reading the data from ascii file and puting them into separate vectords. The thing is that i'm not sure, since all data are read out from ascii file, how to fill vectors just with values that i need.
My ascii file have description:

---------------------
Header Record Format:
---------------------


Variable Name Columns Description
----------------------- ------- -----------

Header Record Indicator 1- 1 # character

Station Number 2- 6 WMO station number

Year 7- 10

Month 11- 12

Day 13- 14

Observation Hour 15- 16 00-23 UTC

Release Time 17- 20 0000-2359 UTC, 9999 = missing

Number of levels 21- 24 number of subsequent data records



---------------------
Data Record Format:
---------------------


Variable Name Columns Description
----------------------- ------- -----------

Major Level Type 1- 1 1 = standard pressure level
2 = significant thermodynamic level
3 = additional wind level

Minor Level Type 2- 2 1 = surface, 2 = tropopause, 0 = other


Pressure 3- 8 units of Pa (mb * 100)

Pressure Flag 9- 9 A, B, or blank (see note 4 above)

Geopotential Height 10- 14 units of meters

Geopotential Height Flag 15- 15 A, B, or blank (see note 4 above)

Temperature 16- 20 units of degrees C * 10

Temperature Flag 21- 21 A, B, or blank (see note 4 above)

Dewpoint Depression 22- 26 units of degrees C * 10

Wind Direction 27- 31 units of degrees (0-360, inclusive)

Wind Speed 32- 36 units of (m/s)*10


I need just pressure, temperature and height (without flags) and this is (wrong) code that i wrote:


int main () {
// OPEN THE TEXT FILE
ifstream file_to_read("/forum/udine.txt");

// Maximum number of characters expected in a single line in the header
const int max_num_of_char_in_a_line = 24;
//Number of header files to skip
int num_of_header_lines = 1;


// SKIP ALL THE HEADER LINES

for(int i = 0; i < num_of_header_lines; ++i)
file_to_read.ignore(max_num_of_char_in_a_line, '\n');


vector<double> Pressure_array;
vector<double> Temperature_array;
vector<double> Altitude_array;


while(!file_to_read.eof()) {
if (!file_to_read.good()) break;

double Pressure;
double Altitude;
double Temperature;
//read the data
file_to_read.ignore(2);//dont read first 2 characters
file_to_read >> setw(5) >>Pressure ; //fill next 5 char
file_to_read.ignore(1);//dont read nex one char
file_to_read >> setw(5) >> Altitude;
file_to_read.ignore(1);
file_to_read >> setw(5) >> Temperature;
file_to_read.ignore(16);
//fill the data
Pressure_array.push_back(Pressure);
Altitude_array.push_back(Altitude);
Temperature_array.push_back(Temperature);
}

for(int i = 0; i < Pressure_array.size(); ++i){
cout << Pressure_array << '\n';
double Pressure = Pressure_array.size;
}


for(int i = 0; i < Altitude_array.size(); ++i){
cout << "\naltitude are:\n" <<altitude_array << '\n';
double Altitude = Altitude_array.size;
}


for(int i = 0; i < Temperature_array.size(); ++i){
cout << Temperature_array << '\n';
double Temperature = Temperature_array.size;
}


return 0;

}


Could someone help me with this and tell me where i'm wrong?
Sorry for such a long question








CodeToad Experts

Can't find the answer?
Our Site experts are answering questions for free in the CodeToad forums








Recent Forum Threads
•  Re: Function to check the pattern(i.e 1A-2B-3C)
•  Re: problem with Exception
•  Re: Turning java class into application
•  Re: this is weird
•  Server Name or Address could not be resolved?
•  Re: How can I read ASCII data file in C++
•  Sending automated emails
•  Re: How to kill framesets
•  What is This?


Recent Articles
What is a pointer in C?
Multiple submit buttons with form validation
Understanding Hibernate ORM for Java/J2EE
HTTP screen-scraping and caching
a javascript calculator
A simple way to JTable
Java Native Interface (JNI)
Parsing Dynamic Layouts
MagicGrid
Caching With ASP.Net


© Copyright codetoad.com 2001-2006