User Name Password Register
DaniWeb IT Discussion Community
All
What is DaniWeb IT Discussion Community?
You're currently browsing the C++ section within the Software Development category of DaniWeb, a massive community of 456,555 software developers, web developers, Internet marketers, and tech gurus who are all enthusiastic about making contacts, networking, and learning from each other. In fact, there are 3,483 IT professionals currently interacting right now! Registration is free, only takes a minute and lets you enjoy all of the interactive features of the site.
Please support our C++ advertiser: Programming Forums
Views: 2431 | Replies: 25
Reply
Join Date: Oct 2007
Posts: 23
Reputation: fmufti is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
fmufti fmufti is offline Offline
Newbie Poster

Question write and read to file

  #1  
Oct 19th, 2007
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.!!!
#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**)&ampl);
	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();

}
 
AddThis Social Bookmark Button
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: write and read to file

  #2  
Oct 19th, 2007
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:
   filein.read((char *) read_dist, sizeof( read_dist )); 
   filein.read((char *) read_ampl, sizeof( read_ampl )); 
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:

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 6:40 am.
Reply With Quote  
Join Date: Oct 2007
Posts: 23
Reputation: fmufti is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
fmufti fmufti is offline Offline
Newbie Poster

Question Re: write and read to file

  #3  
Oct 19th, 2007
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,
#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;
 }
 
Reply With Quote  
Join Date: Dec 2005
Posts: 3,834
Reputation: Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of 
Rep Power: 23
Solved Threads: 436
Colleague
Salem's Avatar
Salem Salem is offline Offline
banned

Re: write and read to file

  #4  
Oct 19th, 2007
> 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.

	   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]) ); 
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: write and read to file

  #5  
Oct 19th, 2007
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:
  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...
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: write and read to file

  #6  
Oct 19th, 2007
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.
Reply With Quote  
Join Date: Dec 2005
Posts: 3,834
Reputation: Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of Salem has much to be proud of 
Rep Power: 23
Solved Threads: 436
Colleague
Salem's Avatar
Salem Salem is offline Offline
banned

Re: write and read to file

  #7  
Oct 19th, 2007
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.

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
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.
Reply With Quote  
Join Date: Sep 2004
Posts: 6,515
Reputation: Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of Narue has much to be proud of 
Rep Power: 31
Solved Threads: 489
Super Moderator
Narue's Avatar
Narue Narue is offline Offline
Expert Meanie

Re: write and read to file

  #8  
Oct 19th, 2007
>> 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.
I'm here to prove you wrong.
Reply With Quote  
Join Date: Oct 2007
Posts: 23
Reputation: fmufti is an unknown quantity at this point 
Rep Power: 2
Solved Threads: 0
fmufti fmufti is offline Offline
Newbie Poster

Re: write and read to file

  #9  
Oct 19th, 2007
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
#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;
 }

Thanks
Last edited by fmufti : Oct 19th, 2007 at 11:22 am.
Reply With Quote  
Join Date: Oct 2007
Location: Cherry Hill, NJ
Posts: 1,878
Reputation: Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold Duoas is a splendid one to behold 
Rep Power: 13
Solved Threads: 193
Featured Poster
Duoas's Avatar
Duoas Duoas is offline Offline
Posting Virtuoso

Re: write and read to file

  #10  
Oct 19th, 2007
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 while (!kbhit()) to continue while a key has not been pressed.

Bye.
Reply With Quote  
Reply

Only community members can participate in forum threads. You must register or log in to contribute.

DaniWeb C++ Marketplace
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)

 

Thread Tools Display Modes

Similar Threads
Other Threads in the C++ Forum

All times are GMT -4. The time now is 5:31 am.
Forum system based on vBulletin Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
©2003 - 2008 DaniWeb® LLC