Discussion:
[Dev-C++] fread get stuck
Kristian Magnani
2007-07-19 21:08:55 UTC
Permalink
Hi, all!

I've been using gcc in linux for a while, but now I'm trying do compile some example codes I've under Dev-C++, and I'm facing some problems.

Below follow two programs: one opens a file where it write 1000 random numbers and the other open a file to read numbers and print them into the screen. Thet work perfectly under gcc/linux, but at Dev-C++/windows the program that reads the file get stuck at a particular number. For the same file, it always stops reading at the same line, although for different files, it stops at different lines.

I suspect it's something defined as open behaviour in C/C++ specification, because the same programs work fine at gcc/linux, but I don't know what. Does anyone have an idea what I'm doing wrong?

Thanks!



#include <iostream>
#include <stdlib.h>

using namespace std;

int main (int argc, char *argv[])
{
/* inicializa gerador de numeros aleatorios */
srand(time(NULL));

/* abre arquivo para escrita, criando se nao existir */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "w+");
if (file == NULL)
{
cout << "Erro ao criar arquivo." << endl;
}
else
{
for (int i = 0; i < 1000; i++)
{

/* pausa execucao */
if (i % 100 == 0 && i > 0) cin.get();

/* escreve um numero aleatorio no arquivo aberto */
int aleatorio = rand() % 1000;
cout << i + 1 << "\tEscrevendo '" << aleatorio
<< "' no arquivo '" << argv[1] << "'." << endl;
int elementosEscritos = fwrite(&aleatorio, 1, sizeof(int), file);
if (elementosEscritos < 0)
{
cout << "Erro ao escrever em arquivo.";
}
}
}

/* fecha arquivo */
fclose(file);

/* pausa execucao */
cin.get();

return 0;
}






#include <iostream.h>
#include <stdlib.h>

using namespace std;

int main (int argc, char *argv[])
{

/* abre arquivo para leitura */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "r+");
if (file == NULL)
{
cout << "Erro ao abrir arquivo '" << argv[1] << "'." << endl;
}
else
{
int i = 0;
int elementosLidos;
int aleatorio;

/* le um numero do arquivo aberto */
while (elementosLidos = fread(&aleatorio, sizeof(int), 1, file) > 0)
{
i++;
cout << i << "\tLeu '" << aleatorio
<< "' (" << elementosLidos << " elementos) do arquivo '"
<< argv[1] << "'." << endl;
}
}

/* fecha arquivo */
fclose(file);

/* pausa execucao */
cin.get();

return 0;
}






____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
http://sims.yahoo.com/
Per Westermark
2007-07-19 22:29:20 UTC
Permalink
It's a bit hurtfull to my eyes to see source code that mixes C and C++
file I/O. I would recommend that you use one or the other.

In your case, you have forgotten an important difference between Windows
and Unix. In Windows, there is a difference between binary and ASCII
files. When writing to a file opened in ASCII mode, any character "\n"
will be converted to "\r\n" (CR+LF), and when reading to a file opened in
ASCII mode, the caracters "\r\n" will be converted to a "\n".

In your case, you are using fread() and fwrite() to read and write as if
the integers are binary data. That requires you to add a "b" to the mode
string of fopen().

Note that you are using a non-portable way if reading and writing
integers. The data is read and written in the byte order of the machine
you are currently using. A better way to create binary data files is to
beforehand specify a byte order, and then write the integers as separate
bytes.

/pwm
Post by Kristian Magnani
Hi, all!
I've been using gcc in linux for a while, but now I'm trying do compile some example codes I've under Dev-C++, and I'm facing some problems.
Below follow two programs: one opens a file where it write 1000 random numbers and the other open a file to read numbers and print them into the screen. Thet work perfectly under gcc/linux, but at Dev-C++/windows the program that reads the file get stuck at a particular number. For the same file, it always stops reading at the same line, although for different files, it stops at different lines.
I suspect it's something defined as open behaviour in C/C++ specification, because the same programs work fine at gcc/linux, but I don't know what. Does anyone have an idea what I'm doing wrong?
Thanks!
#include <iostream>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* inicializa gerador de numeros aleatorios */
srand(time(NULL));
/* abre arquivo para escrita, criando se nao existir */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "w+");
if (file == NULL)
{
cout << "Erro ao criar arquivo." << endl;
}
else
{
for (int i = 0; i < 1000; i++)
{
/* pausa execucao */
if (i % 100 == 0 && i > 0) cin.get();
/* escreve um numero aleatorio no arquivo aberto */
int aleatorio = rand() % 1000;
cout << i + 1 << "\tEscrevendo '" << aleatorio
<< "' no arquivo '" << argv[1] << "'." << endl;
int elementosEscritos = fwrite(&aleatorio, 1, sizeof(int), file);
if (elementosEscritos < 0)
{
cout << "Erro ao escrever em arquivo.";
}
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
#include <iostream.h>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* abre arquivo para leitura */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "r+");
if (file == NULL)
{
cout << "Erro ao abrir arquivo '" << argv[1] << "'." << endl;
}
else
{
int i = 0;
int elementosLidos;
int aleatorio;
/* le um numero do arquivo aberto */
while (elementosLidos = fread(&aleatorio, sizeof(int), 1, file) > 0)
{
i++;
cout << i << "\tLeu '" << aleatorio
<< "' (" << elementosLidos << " elementos) do arquivo '"
<< argv[1] << "'." << endl;
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
http://sims.yahoo.com/
Peeyush Bishnoi
2007-07-20 09:25:27 UTC
Permalink
Hello All
I am facing one problem in code below. This code is for copy constructor.

Actaully when copy constructor gets called for get function with object b , the object value becomes 0. I think that that object b & object p are not pointing to same location as i explicitly declared the copy constructor.

Please explain why it is so... Why object b value become 0 . Also how to avoid this so that object value should print actual value.

#include<iostream>
using namespace std;
class A{
static int count;
int *num;
public:
A():num(new int(2)){
cout<<"Zero argument ctor called\n"<<endl;
count++;
}

A(int i):num(new int(i)){
cout<<"One arument ctor called\n"<<endl;
count++;
}

A(const A &i):num(i.num){
cout<<"Copy Ctor called\n"<<endl;
count++;
}

void print(){

cout<<"count"<<count<<"Value:"<<*num<<endl;
}

~A(){
cout<<"Dtor called\t"<<"count"<<count--<<endl;
delete num;
}
};

void get(A p){
cout<<"get function called\n"<<endl;
p.print();
}


int A::count;

int main(){

A a;
a.print();
A b(3);
b.print();
get(b);
b.print();
A c=a;
c.print();
return 0;
}


Regards
Peeyush B.
Per Westermark
2007-07-20 09:46:01 UTC
Permalink
Several problems with the code - below are a couple of them:

1) No fread() in this code, so obviously no fread can get stuck.

2) The copy-constructor copies a pointer, making multiple objects point to
the same int buffer. What do you think happen when the first object gets
destroyed, and the destructor releases this shared memory?

3) The get() function takes an object by value, i.e. it creates a new
temporary object. What happens when this temporary object is destroyed?
Will the get() function every be able to return back an object (if now
get() is expected to read an object from file or similar)?

4) Don't you think that the destructor should use predecrement of the
count static member, so that when the last object is destroyed, the count
value 0 is printed?

5) If you impelemnt a copy constructor, where is the assignment operator?

/pwm
Post by Peeyush Bishnoi
Hello All
I am facing one problem in code below. This code is for copy constructor.
Actaully when copy constructor gets called for get function with object b , the object value becomes 0. I think that that object b & object p are not pointing to same location as i explicitly declared the copy constructor.
Please explain why it is so... Why object b value become 0 . Also how to avoid this so that object value should print actual value.
#include<iostream>
using namespace std;
class A{
static int count;
int *num;
A():num(new int(2)){
cout<<"Zero argument ctor called\n"<<endl;
count++;
}
A(int i):num(new int(i)){
cout<<"One arument ctor called\n"<<endl;
count++;
}
A(const A &i):num(i.num){
cout<<"Copy Ctor called\n"<<endl;
count++;
}
void print(){
cout<<"count"<<count<<"Value:"<<*num<<endl;
}
~A(){
cout<<"Dtor called\t"<<"count"<<count--<<endl;
delete num;
}
};
void get(A p){
cout<<"get function called\n"<<endl;
p.print();
}
int A::count;
int main(){
A a;
a.print();
A b(3);
b.print();
get(b);
b.print();
A c=a;
c.print();
return 0;
}
Regards
Peeyush B.
Kristian Magnani
2007-07-20 16:21:51 UTC
Permalink
Yes, the fopen lacked the "b" flag. Now it's working fine, Thanks a lot!

I agree that the code mixes C and C++ I/O, but file I/O is done just with C-like file I/O, isn't it? C++ file I/O would imply in use of stream classes...

Regarding the reading / writing integers, is there a way to specify the byte order, or should my code itself decompose the integers into bytes (using shifting operations and bit masks)?

Thanks again.

----- Original Message ----
From: Per Westermark <***@iapetus.neab.net>
To: Kristian Magnani <***@yahoo.com>
Cc: dev-cpp-***@lists.sourceforge.net
Sent: Thursday, July 19, 2007 7:29:20 PM
Subject: Re: [Dev-C++] fread get stuck

It's a bit hurtfull to my eyes to see source code that mixes C and C++
file I/O. I would recommend that you use one or the other.

In your case, you have forgotten an important difference between Windows
and Unix. In Windows, there is a difference between binary and ASCII
files. When writing to a file opened in ASCII mode, any character "\n"
will be converted to "\r\n" (CR+LF), and when reading to a file opened in
ASCII mode, the caracters "\r\n" will be converted to a "\n".

In your case, you are using fread() and fwrite() to read and write as if
the integers are binary data. That requires you to add a "b" to the mode
string of fopen().

Note that you are using a non-portable way if reading and writing
integers. The data is read and written in the byte order of the machine
you are currently using. A better way to create binary data files is to
beforehand specify a byte order, and then write the integers as separate
bytes.

/pwm
Post by Kristian Magnani
Hi, all!
I've been using gcc in linux for a while, but now I'm trying do compile some example codes I've under Dev-C++, and I'm facing some problems.
Below follow two programs: one opens a file where it write 1000 random numbers and the other open a file to read numbers and print them into the screen. Thet work perfectly under gcc/linux, but at Dev-C++/windows the program that reads the file get stuck at a particular number. For the same file, it always stops reading at the same line, although for different files, it stops at different lines.
I suspect it's something defined as open behaviour in C/C++ specification, because the same programs work fine at gcc/linux, but I don't know what. Does anyone have an idea what I'm doing wrong?
Thanks!
#include <iostream>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* inicializa gerador de numeros aleatorios */
srand(time(NULL));
/* abre arquivo para escrita, criando se nao existir */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "w+");
if (file == NULL)
{
cout << "Erro ao criar arquivo." << endl;
}
else
{
for (int i = 0; i < 1000; i++)
{
/* pausa execucao */
if (i % 100 == 0 && i > 0) cin.get();
/* escreve um numero aleatorio no arquivo aberto */
int aleatorio = rand() % 1000;
cout << i + 1 << "\tEscrevendo '" << aleatorio
<< "' no arquivo '" << argv[1] << "'." << endl;
int elementosEscritos = fwrite(&aleatorio, 1, sizeof(int), file);
if (elementosEscritos < 0)
{
cout << "Erro ao escrever em arquivo.";
}
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
#include <iostream.h>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* abre arquivo para leitura */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "r+");
if (file == NULL)
{
cout << "Erro ao abrir arquivo '" << argv[1] << "'." << endl;
}
else
{
int i = 0;
int elementosLidos;
int aleatorio;
/* le um numero do arquivo aberto */
while (elementosLidos = fread(&aleatorio, sizeof(int), 1, file) > 0)
{
i++;
cout << i << "\tLeu '" << aleatorio
<< "' (" << elementosLidos << " elementos) do arquivo '"
<< argv[1] << "'." << endl;
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
http://sims.yahoo.com/
____________________________________________________________________________________Ready for the edge of your seat?
Check out tonight's top picks on Yahoo! TV.
http://tv.yahoo.com/
Per Westermark
2007-07-20 17:53:02 UTC
Permalink
Note that
std::cout << "Hello world" << std::endl;
is also file I/O. It's just that in this case, std::cout happens to be
a predefined stream that maps to the standard-out file stream.

No real difference from using
printf("Hello world\n");
or
fprintf(stdout,"Hello world\n");
or
fwrite("Hello world\n",1,12,stdout);

If you want to generate portable files, then you must yourself split the
integer into bytes and emit them byte for byte. You can do this with
something like:
buf[0] = a & 0xff;
buf[1] = (a >> 8) & 0xff;
buf[2] = (a >> 16) & 0xff;
buf[3] = (a >> 24) & 0xff;
and then use fwrite to write out buf.

/pwm
Post by Kristian Magnani
Yes, the fopen lacked the "b" flag. Now it's working fine, Thanks a lot!
I agree that the code mixes C and C++ I/O, but file I/O is done just with C-like file I/O, isn't it? C++ file I/O would imply in use of stream classes...
Regarding the reading / writing integers, is there a way to specify the byte order, or should my code itself decompose the integers into bytes (using shifting operations and bit masks)?
Thanks again.
----- Original Message ----
Sent: Thursday, July 19, 2007 7:29:20 PM
Subject: Re: [Dev-C++] fread get stuck
It's a bit hurtfull to my eyes to see source code that mixes C and C++
file I/O. I would recommend that you use one or the other.
In your case, you have forgotten an important difference between Windows
and Unix. In Windows, there is a difference between binary and ASCII
files. When writing to a file opened in ASCII mode, any character "\n"
will be converted to "\r\n" (CR+LF), and when reading to a file opened in
ASCII mode, the caracters "\r\n" will be converted to a "\n".
In your case, you are using fread() and fwrite() to read and write as if
the integers are binary data. That requires you to add a "b" to the mode
string of fopen().
Note that you are using a non-portable way if reading and writing
integers. The data is read and written in the byte order of the machine
you are currently using. A better way to create binary data files is to
beforehand specify a byte order, and then write the integers as separate
bytes.
/pwm
Post by Kristian Magnani
Hi, all!
I've been using gcc in linux for a while, but now I'm trying do compile some example codes I've under Dev-C++, and I'm facing some problems.
Below follow two programs: one opens a file where it write 1000 random numbers and the other open a file to read numbers and print them into the screen. Thet work perfectly under gcc/linux, but at Dev-C++/windows the program that reads the file get stuck at a particular number. For the same file, it always stops reading at the same line, although for different files, it stops at different lines.
I suspect it's something defined as open behaviour in C/C++ specification, because the same programs work fine at gcc/linux, but I don't know what. Does anyone have an idea what I'm doing wrong?
Thanks!
#include <iostream>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* inicializa gerador de numeros aleatorios */
srand(time(NULL));
/* abre arquivo para escrita, criando se nao existir */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "w+");
if (file == NULL)
{
cout << "Erro ao criar arquivo." << endl;
}
else
{
for (int i = 0; i < 1000; i++)
{
/* pausa execucao */
if (i % 100 == 0 && i > 0) cin.get();
/* escreve um numero aleatorio no arquivo aberto */
int aleatorio = rand() % 1000;
cout << i + 1 << "\tEscrevendo '" << aleatorio
<< "' no arquivo '" << argv[1] << "'." << endl;
int elementosEscritos = fwrite(&aleatorio, 1, sizeof(int), file);
if (elementosEscritos < 0)
{
cout << "Erro ao escrever em arquivo.";
}
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
#include <iostream.h>
#include <stdlib.h>
using namespace std;
int main (int argc, char *argv[])
{
/* abre arquivo para leitura */
/* cursos posicionado no inicio do arquivo */
FILE* file = fopen(argv[1], "r+");
if (file == NULL)
{
cout << "Erro ao abrir arquivo '" << argv[1] << "'." << endl;
}
else
{
int i = 0;
int elementosLidos;
int aleatorio;
/* le um numero do arquivo aberto */
while (elementosLidos = fread(&aleatorio, sizeof(int), 1, file) > 0)
{
i++;
cout << i << "\tLeu '" << aleatorio
<< "' (" << elementosLidos << " elementos) do arquivo '"
<< argv[1] << "'." << endl;
}
}
/* fecha arquivo */
fclose(file);
/* pausa execucao */
cin.get();
return 0;
}
____________________________________________________________________________________
Moody friends. Drama queens. Your life? Nope! - their life, your story. Play Sims Stories at Yahoo! Games.
http://sims.yahoo.com/
____________________________________________________________________________________Ready for the edge of your seat?
Check out tonight's top picks on Yahoo! TV.
http://tv.yahoo.com/
Loading...