| | |
write and read to file
![]() |
•
•
Join Date: Oct 2007
Posts: 23
Reputation:
Solved Threads: 0
Hi,
I am writing an array data to a file. The data I am getting is from some sensor and need to be written in real time. I have manged to write it but I am having problem when I try to read it, as I cannot position the pointer to read 'read_ampl'. So three questions:
1. Is this the way I am writing is fast so that I do not drop frames.
2. Am I ok in writing part as I believe I am appending two arrays one after the other.
3. I can read the first array 'read_dist' but cannot read the 'read_ampl' as I am positioning properly.
Any help please.!!!
I am writing an array data to a file. The data I am getting is from some sensor and need to be written in real time. I have manged to write it but I am having problem when I try to read it, as I cannot position the pointer to read 'read_ampl'. So three questions:
1. Is this the way I am writing is fast so that I do not drop frames.
2. Am I ok in writing part as I believe I am appending two arrays one after the other.
3. I can read the first array 'read_dist' but cannot read the 'read_ampl' as I am positioning properly.
Any help please.!!!
C++ Syntax (Toggle Plain Text)
#include "stdafx.h" #include <iostream> #include <stdio.h> #include<fstream> #include "sdk.h" using namespace std; void WriteToFile(const char *filename,Handle hnd,int ArraySize); int _tmain(int argc, _TCHAR* argv[]) { static const char filename[] = "data.dat"; int ArraySize; Handle hnd; // connection handle ArraySize=3072; WriteToFile(filename, hnd, ArraySize); return 0; } void WriteToFile(const char *filename, Handle hnd, int ArraySize) { double read_dist[3072], read_ampl[3072]; int res,i; double *dist, *ampl; res = Update (hnd); if (res != OK) cout<<"No Update"; res = Distances (hnd, (void**)&dist); if (res != OK) cout<<"No Distance"; res = Amplitudes (hnd, (void**)&l); if (res != OK) cout<<"No Amplitude"; std::ofstream fileout(filename,ios::out | ios::binary ); if(!fileout) { cout << "Cannot open file to write.\n"; } fileout.write((char *) dist, 8*ArraySize); //size of double array fileout.write((char *) ampl, 8*ArraySize); fileout.close(); ifstream filein(filename, ios::in | ios::binary); if(!filein) { cout << "Cannot open file to read.\n"; } filein.read((char *) &read_dist, sizeof read_dist); filein.read((char *) &read_ampl, sizeof read_ampl); for(i = 0; i <ArraySize; i++) // show from file cout << "Distance: "<<read_dist[i] <<endl; cout << "Amplitude: "<<read_ampl[i] <<endl; filein.close(); }
Is this to be production code? I assume it is so my response might be a little more embarrassingly detailed than you would like...
First, for your main problem. I think you are clobbering memory somewhere --I'm actually surprised your program isn't crashing. Try this:
Remember, read_dist is a pointer to double. You are casting it to a pointer to char. Either way what it points to is the first double in the array, but you were giving the read function a pointer to the pointer to the first double in the array...
Second. the sizeof requires parentheses. It's nice you know a double is eight bytes long, but you should (if just for style) not count on it. Say:
and
Third, (and I realize that this is just testing), try to get rid of all the hard-coded stuff and stick to using ArraySize. In your production code use
or
to allocate memory for the array. Use free or delete when you are done with it.
Fourth, it is good that you are testing for errors, but there are currently no consequences. For example, if opening the file fails you print out that it did then try to read a huge array anyway. While this code works fine, it does so for the wrong reasons...
Finally, don't use using namespace std;. That should never appear in production code. Take the extra tenth of a second to write std::cout instead of just cout. You'll be avoiding horrible bug-hunting sessions in reruns.
Hope this helps.
First, for your main problem. I think you are clobbering memory somewhere --I'm actually surprised your program isn't crashing. Try this:
C++ Syntax (Toggle Plain Text)
filein.read((char *) read_dist, sizeof( read_dist )); filein.read((char *) read_ampl, sizeof( read_ampl ));
Second. the sizeof requires parentheses. It's nice you know a double is eight bytes long, but you should (if just for style) not count on it. Say:
sizeof( double ) * ArraySize and
sizeof( read_dist ) Third, (and I realize that this is just testing), try to get rid of all the hard-coded stuff and stick to using ArraySize. In your production code use
double *read_dist = malloc( sizeof( double ) * ArraySize );or
double *read_dist = new double[ ArraySize ];to allocate memory for the array. Use free or delete when you are done with it.
Fourth, it is good that you are testing for errors, but there are currently no consequences. For example, if opening the file fails you print out that it did then try to read a huge array anyway. While this code works fine, it does so for the wrong reasons...
Finally, don't use using namespace std;. That should never appear in production code. Take the extra tenth of a second to write std::cout instead of just cout. You'll be avoiding horrible bug-hunting sessions in reruns.
Hope this helps.
Last edited by Duoas; Oct 19th, 2007 at 5:40 am.
•
•
Join Date: Oct 2007
Posts: 23
Reputation:
Solved Threads: 0
Hi, Thanks for your reply. I have simplified my code and have put some dummy data. But by using your code I am not getting the right read values, probably I am getting the address of the pointer. Can you copy paste the code below and see yourself.
Thanks,
Thanks,
C++ Syntax (Toggle Plain Text)
#include <iostream> #include <stdio.h> #include<fstream> using namespace std; void WriteToFile(const char *filename, int ArraySize); int main() { static const char filename[] = "data.dat"; int ArraySize=10; WriteToFile(filename, ArraySize); return 0; } void WriteToFile(const char *filename, int ArraySize) { double *read_dist=new double[ArraySize]; double *read_ampl=new double[ArraySize]; int res,i; double c[10]={1,2,3,4,5,6,7,8,9,10}; double d[10]={5,6,7,8,9,4,3,2,3,4}; double *dist=c; double *ampl=d; std::ofstream fileout(filename,ios::out | ios::binary ); if(!fileout) { std::cout << "Cannot open file to write.\n"; } fileout.write((char *) dist, sizeof(double)*ArraySize); //size of double with array size fileout.write((char *) ampl, sizeof(double)*ArraySize); fileout.close(); ifstream filein(filename, ios::in | ios::binary); if(!filein) { std::cout << "Cannot open file to read.\n"; } filein.read((char *) read_dist, sizeof( read_dist)); filein.read((char *) read_ampl, sizeof( read_ampl)); //filein.read((char *) &read_dist, sizeof read_dist); //filein.read((char *) &read_ampl, sizeof read_ampl); for(i = 0; i <ArraySize; i++) // show values read from file { std::cout << "Distance: "<<read_dist[i] <<endl; std::cout << "Amplitude: "<<read_ampl[i] <<endl; } filein.close(); delete [] read_dist; delete [] read_ampl; }
> Remember, read_dist is a pointer to double.
Funny, it looked like an array to me.
> Second. the sizeof requires parentheses.
Wrong again, it only needs () when it's a variable name, not a type name.
Go back to your original code fmufti
> fileout.write((char *) dist, sizeof(dist[0])*ArraySize); //size of double array
> fileout.write((char *) ampl, sizeof(ampl[0])*ArraySize);
> filein.read((char *) &read_dist, sizeof read_dist);
> filein.read((char *) &read_ampl, sizeof read_ampl);
The reason you're not getting any read_ampl data is that read_dist doesn't know when to stop, so it reads as much as possible until the array is full.
If your data arrives in variable length arrays, then you should write out the length first.
Funny, it looked like an array to me.
> Second. the sizeof requires parentheses.
Wrong again, it only needs () when it's a variable name, not a type name.
Go back to your original code fmufti
> fileout.write((char *) dist, sizeof(dist[0])*ArraySize); //size of double array
> fileout.write((char *) ampl, sizeof(ampl[0])*ArraySize);
> filein.read((char *) &read_dist, sizeof read_dist);
> filein.read((char *) &read_ampl, sizeof read_ampl);
The reason you're not getting any read_ampl data is that read_dist doesn't know when to stop, so it reads as much as possible until the array is full.
If your data arrives in variable length arrays, then you should write out the length first.
C++ Syntax (Toggle Plain Text)
fileout.write((char *)&ArraySize, sizeof(ArraySize)); fileout.write((char *) dist, 8*ArraySize); //size of double array fileout.write((char *) ampl, 8*ArraySize); filein.read((char *) &newSize, sizeof(newSize) ); filein.read((char *) read_dist, newSize * sizeof double ); filein.read((char *) read_ampl, newSize * sizeof(read_ampl[0]) );
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
--
If your code lacks code tags, you will be IGNORED
--
If your code lacks code tags, you will be IGNORED
Wow, you're awake too...
The problem is when you changed read_dist and read_ampl from static arrays to pointers. The sizeof() operator always gives the size of the object indicated. The size of an array is much larger than the size of a pointer.
So, you'll have to change things thus:
Sorry for the confusion. I should have warned you about that...
The problem is when you changed read_dist and read_ampl from static arrays to pointers. The sizeof() operator always gives the size of the object indicated. The size of an array is much larger than the size of a pointer.
So, you'll have to change things thus:
C++ Syntax (Toggle Plain Text)
filein.read((char *) read_dist, sizeof( double ) * ArraySize ); filein.read((char *) read_ampl, sizeof( double ) * ArraySize );
Sorry for the confusion. I should have warned you about that...
Salem, so far I've only seen you give good advice. So don't be stupid now.
1. Arrays in C/C++ are managed by having a variable that points to the first element in the array. The only difference between a[0] and *a is compiler magic.
2. He was saying sizeof read_dist. In case you didn't notice, read_dist is a variable, not a type.
3. His original code didn't work, hence his taking the time to post here.
4. That is not the reason he is not getting ampl data. If it were just a matter of buffer overflow he'd still get his ampl data since the array is declared in memory immediately following the dist data. It would overflow straight into the correct place.
The reason was that he was giving the address of the pointer to the array data, rather than the address of the array data. Hence, he was reading into his code segment, which Win32 prohibits. Hence, there are two reasons his program should have crashed: Win32 would complain; barring that he would destroy his code before it got to the read_ampl part. Lucky he didn't have some bad opcodes in his dist data.
Good thing: yes, writing out the size of the array is a good idea.
1. Arrays in C/C++ are managed by having a variable that points to the first element in the array. The only difference between a[0] and *a is compiler magic.
2. He was saying sizeof read_dist. In case you didn't notice, read_dist is a variable, not a type.
3. His original code didn't work, hence his taking the time to post here.
4. That is not the reason he is not getting ampl data. If it were just a matter of buffer overflow he'd still get his ampl data since the array is declared in memory immediately following the dist data. It would overflow straight into the correct place.
The reason was that he was giving the address of the pointer to the array data, rather than the address of the array data. Hence, he was reading into his code segment, which Win32 prohibits. Hence, there are two reasons his program should have crashed: Win32 would complain; barring that he would destroy his code before it got to the read_ampl part. Lucky he didn't have some bad opcodes in his dist data.
Good thing: yes, writing out the size of the array is a good idea.
Boy are you ever wrong.
> Arrays in C/C++ are managed by having a variable that points to the first element in the array.
Read THIS VERY CAREFULLY.
If your argument were true, both sizeof results would be the same.
> His original code didn't work, hence his taking the time to post here.
True, but not for any of the reasons you spouted.
The only problem I could see was that he was trying to write out 10 doubles, then read in 3072 doubles into the first array, thus leaving none for the 2nd array.
> Arrays in C/C++ are managed by having a variable that points to the first element in the array.
Read THIS VERY CAREFULLY.
C++ Syntax (Toggle Plain Text)
void foo ( ) { int arr[100]; int *parr = new int[100]; // these are VERY different std::cout << sizeof(arr) << std::endl; std::cout << sizeof(parr) << std::endl; // these are functionally the same std::cout << (void*)arr << " " << (void*)&arr[0] << std::endl; std::cout << (void*)parr << " " << (void*)&parr[0] << std::endl; } $ ./a.exe 400 4 0x22cb30 0x22cb30 0x6a0250 0x6a0250
> His original code didn't work, hence his taking the time to post here.
True, but not for any of the reasons you spouted.
The only problem I could see was that he was trying to write out 10 doubles, then read in 3072 doubles into the first array, thus leaving none for the 2nd array.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
--
If your code lacks code tags, you will be IGNORED
--
If your code lacks code tags, you will be IGNORED
>> Second. the sizeof requires parentheses.
>Wrong again, it only needs () when it's a variable name, not a type name.
It's the other way around. sizeof requires parentheses with a type name, but not a variable name.
>1. Arrays in C/C++ are managed by having a variable that points to the first element in the array.
How they're managed is none of your business (ie. it's an implementation detail that isn't specified). What matters is how arrays behave when you use them. And the behavior is that except in three situations, an array name is converted to a pointer to the first element. But that's conceptually very different from an array name being a pointer. The three situations are:
1) As the operand to sizeof
2) As the operand to &
3) As a string literal initializer
>The reason was that he was giving the address of the pointer
>to the array data, rather than the address of the array data.
Both of which are equivalent with his compiler. Given an array a, (a) and (&a) both evaluate to the same address. The only difference is the data type, which is corrected with the cast to char*. The address-of operator is still incorrect, but it produces the correct result. All of that writing to the code segment garbage is wrong.
>Wrong again, it only needs () when it's a variable name, not a type name.
It's the other way around. sizeof requires parentheses with a type name, but not a variable name.
>1. Arrays in C/C++ are managed by having a variable that points to the first element in the array.
How they're managed is none of your business (ie. it's an implementation detail that isn't specified). What matters is how arrays behave when you use them. And the behavior is that except in three situations, an array name is converted to a pointer to the first element. But that's conceptually very different from an array name being a pointer. The three situations are:
1) As the operand to sizeof
2) As the operand to &
3) As a string literal initializer
>The reason was that he was giving the address of the pointer
>to the array data, rather than the address of the array data.
Both of which are equivalent with his compiler. Given an array a, (a) and (&a) both evaluate to the same address. The only difference is the data type, which is corrected with the cast to char*. The address-of operator is still incorrect, but it produces the correct result. All of that writing to the code segment garbage is wrong.
In case you were wondering, yes, I do hate you.
•
•
Join Date: Oct 2007
Posts: 23
Reputation:
Solved Threads: 0
Thanks to all of you. However, the problem is not fully over, as I mentioned that actual data will from sensor so I need to keep writing the frames till the user press some key e.g 's'.
1. How to do that ?
2. How to put the frame no before each dist and ampl arrays are written.
3. And to read them
I have put my my code as
Thanks
1. How to do that ?
2. How to put the frame no before each dist and ampl arrays are written.
3. And to read them
I have put my my code as
C++ Syntax (Toggle Plain Text)
#include "stdafx.h" #include<iostream> #include<stdio.h> #include <conio.h> #include<fstream> using namespace std; void WriteToFile(const char *filename, int ArraySize); void ReadFromFile(const char *filename, int ArraySize); int _tmain(int argc, _TCHAR* argv[]) { char what; static const char filename[] = "data.dat"; int ArraySize=10; std::cout<<"To Write: 'w' and press 's' to stop, To Read 'r'"<<endl; std::cin>>what; if (what=='w'){ WriteToFile(filename, ArraySize);} else if (what=='r'){ ReadFromFile(filename, ArraySize);} else exit(1); return 0; } void WriteToFile(const char *filename, int ArraySize) { double c[10]={1,2,3,4,5,6,7,8,9,10}; double d[10]={5,6,7,8,9,4,3,2,3,4}; double *dist=c; double *ampl=d; char stop; std::ofstream fileout(filename,ios::out | ios::binary ); if(!fileout) {std::cout << "Cannot open file to write.\n"; } //Some function will provide dist and ampl value for each frame; while(kbhit()) { fileout.write((char *) dist, sizeof(double)*ArraySize); fileout.write((char *) ampl, sizeof(double)*ArraySize); } fileout.close(); } void ReadFromFile(const char *filename, int ArraySize) { int i; double *read_dist=new double[ArraySize]; double *read_ampl=new double[ArraySize]; ifstream filein(filename, ios::in | ios::binary); if(!filein) { std::cout << "Cannot open file to read.\n"; } filein.read((char *) read_dist, sizeof( double ) * ArraySize ); filein.read((char *) read_ampl, sizeof( double ) * ArraySize ); for(i = 0; i <ArraySize; i++) { std::cout << "Distance: "<<read_dist[i] <<endl; std::cout << "Amplitude: "<<read_ampl[i] <<endl; } filein.close(); delete [] read_dist; delete [] read_ampl; }
Last edited by fmufti; Oct 19th, 2007 at 10:22 am.
Well, you people win. Whether or not you like it I generally have a pretty good idea what I am talking about and don't like being chopped at for helping someone out. I can live with honest mistakes (such as with sizeof --I just always used parens). But being contradicted to satisfy your own arrogant egos is too much. If you all had spent any time reading the contents of this thread you'd find a lot less to fault me with.
I hate snot.
Btw. Any C compiler that considers a or &a[0] the same as &a is just waiting to punish people. Understanding how pointers work is very much the business of the programmer --as without that knowledge they'll wind up regurgitating circular crap on some random forum. Go grabbing the address of some pointer variable on the stack and treating it the same as the address the pointer variable contains at your own peril. You might want to study how linkers arrange data into a PE32, and how the windows loader puts it into memory, as well.
@fmufti
How you arrange your data is up to you. If you want to write the frame number as an integer before writing all those doubles then that would work. Just read the data back in in the same order you wrote it out.
Also, put
Bye.
I hate snot.
Btw. Any C compiler that considers a or &a[0] the same as &a is just waiting to punish people. Understanding how pointers work is very much the business of the programmer --as without that knowledge they'll wind up regurgitating circular crap on some random forum. Go grabbing the address of some pointer variable on the stack and treating it the same as the address the pointer variable contains at your own peril. You might want to study how linkers arrange data into a PE32, and how the windows loader puts it into memory, as well.
@fmufti
How you arrange your data is up to you. If you want to write the frame number as an integer before writing all those doubles then that would work. Just read the data back in in the same order you wrote it out.
Also, put
while (!kbhit()) to continue while a key has not been pressed.Bye.
![]() |
Similar Threads
- Binary File Parser (C++)
- Read a web page and write the contents to a file (ASP)
- create, write & read file to/from folder (C++)
- write value of pointer into file (C)
- write to text file using fprintf() (C)
- Error trying to write to existing file (C)
- Read in a file and store in char array (C)
- Using the STL LIst Container, how do I create, write,read, and store in file. (C++)
- How to write a header file (C++)
Other Threads in the C++ Forum
- Previous Thread: Problem with switch statement
- Next Thread: Need Help Solving a Complex Class
Views: 3994 | Replies: 25
| Thread Tools | Search this Thread |
Tag cloud for C++
algorithm array arrays assignment beginner binary c++ c/c++ calculator char class classes client code command compile compiler constructor conversion convert count data delete display dll dynamic encryption error exception file files fstream function functions game givemetehcodez graph gui helpwithhomework homework http iamthwee ifstream input int integer lazy linker list loop loops math matrix member memory multidimensional newbie number object objects opengl output parameter pointer pointers problem program programming project random read recursion recursive reference simple sockets sort spoonfeeding string strings struct student studio system template templates text time tree variable vc++ vector video visual void win32 window windows winsock xml






