473,738 Members | 8,848 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Bug with compiler or am I just doing something illegal

This program should copy one file onto the other. It works if I
compile it with gcc to a cygwin program. However, if I compile it
with the -mno-cygwin option, it doesn't work (this targets native
windows).

Anyway, I just want to check that the program is valid before I see if
I can find a way around a compiler bug.

It might be something simple that I am doing wrong.

-------------------------------------------------------------
#include <stdio.h>

main()
{
FILE *fp;

fp = fopen( "scan0001b. bmp" , "r" );
if( fp == NULL )
{
printf("File open failed for read\n");
exit(0);
}

FILE *fpo;

fpo = fopen( "scanout.bm p" , "w");

if( fpo == NULL )
{
printf("File open failed for write\n");
exit(0);
}
int c=1;

while(!feof(fp) )
{
c = fgetc(fp);
if( c>=0 )
fputc( c , fpo );
}

fclose(fp);
fclose(fpo);

}

---------------------------------------------

When I run it, it stops before it has read the entire file (it only
reads around 10%).
Jul 2 '08 #1
34 1802
In comp.lang.c, raphfrk wrote:
This program should copy one file onto the other. It works if I
compile it with gcc to a cygwin program. However, if I compile it
with the -mno-cygwin option, it doesn't work (this targets native
windows).

Anyway, I just want to check that the program is valid before I see if
I can find a way around a compiler bug.

It might be something simple that I am doing wrong.

-------------------------------------------------------------
#include <stdio.h>

main()
{
FILE *fp;

fp = fopen( "scan0001b. bmp" , "r" );
You've opened this file with the "read text" option. Presuming that the
filename represents a file in the Microsoft bitmap graphics format
(".BMP"), then this is the wrong mode to open the file in. You probably
want
fp = fopen( "scan0001b. bmp" , "rb" );
here.
if( fp == NULL )
{
printf("File open failed for read\n");
exit(0);
}

FILE *fpo;

fpo = fopen( "scanout.bm p" , "w");
Similarly, this is the wrong mode to open a (presumably binary) output file.
>
if( fpo == NULL )
{
printf("File open failed for write\n");
exit(0);
}
int c=1;

while(!feof(fp) )
Remember, feof() does not read the file, and returns true /after/ the true
read (in your case, fgetc()) returns an end-of-file condition.
{
c = fgetc(fp);
In Microsoft Windows, text files are permitted to contain a binary octet
marker (0x1a or ^Z), which will indicate a logical end-of-file prior to the
physical end of the file. While this is a leftover from the MSDOS 1 days,
it still is enforced and acted apon by the underlying Windows I/O model.

If you /did/ mean your input file to contain pure binary data (rather than
the text that you indicate by the file mode string), then there is a very
good chance that at least one character (octet) of this pure binary data
has the value of 0x1a. This would cause your fgetc() on the file to
prematurely return EOF, and subsequently cause feof() to return true. This
in turn causes you to abort the copy process prior to the actual physical
end-of-file of the (presumably binary) input file.
if( c>=0 )
fputc( c , fpo );
}

fclose(fp);
fclose(fpo);

}

---------------------------------------------

When I run it, it stops before it has read the entire file (it only
reads around 10%).
--
Lew Pitcher

Master Codewright & JOAT-in-training | Registered Linux User #112576
http://pitcher.digitalfreehold.ca/ | GPG public key available by request
---------- Slackware - Because I know what I'm doing. ------
Jul 2 '08 #2
raphfrk wrote:
) This program should copy one file onto the other. It works if I
) compile it with gcc to a cygwin program. However, if I compile it
) with the -mno-cygwin option, it doesn't work (this targets native
) windows).
)
) Anyway, I just want to check that the program is valid before I see if
) I can find a way around a compiler bug.
)
) It might be something simple that I am doing wrong.

It might be.
There are certainly several simple things wrong with the code.

) FILE *fp;
)
) fp = fopen( "scan0001b. bmp" , "r" );

Not binary mode "rb" ? It is a binary file, right ?
Perhaps if you read in text mode, certain characters
can flag end of file on windows. Ctrl-Z perhaps.

) int c=1;

Why initialize it ? And why to 1 ??

) while(!feof(fp) )

This mistake is so common that it has its own FAQ entry.
You see, the eof flag is set at the moment a read operation is done
when the file is at EOF. So after the last character is read, feof(fp)
will *not* return true. The next read will return an error code, and
*only then* will feof(fp) be true.

But theoretically, as is, it should work, because of the extra if (c>=0).

) {
) c = fgetc(fp);
) if( c>=0 )
) fputc( c , fpo );
) }

The correct idiom is this:

while ((c = fgetc(fp)) != EOF) {
fputc(c, fpo); /* Should check for errors here also, I think */
}
/* And here an if (ferror(fp)) would be nice */

) fclose(fp);
) fclose(fpo);
)
) }
)
) ---------------------------------------------
)
) When I run it, it stops before it has read the entire file (it only
) reads around 10%).

Offhand, I guess there is a ^Z character at 10% in the input file.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Jul 2 '08 #3
raphfrk wrote:
This program should copy one file onto the other. It works if I
compile it with gcc to a cygwin program. However, if I compile it
with the -mno-cygwin option, it doesn't work (this targets native
windows).

Anyway, I just want to check that the program is valid before I see if
I can find a way around a compiler bug.

It might be something simple that I am doing wrong.

-------------------------------------------------------------
#include <stdio.h>

main()
main() return an int. Say so when you write the function:
int main(void)
{
FILE *fp;

fp = fopen( "scan0001b. bmp" , "r" );
You're not opening the file in binary mode.
On some systems, that will cause some characters in the file to be
interpreted by the C library (or the Operating System??) and those
characters will not reach your program exactly as they are on disk. It
may even happen that some character tells the C library (or the
Operating System) to stop reading the file right there, even though
the number of characters read is only a small percentage of the file
length reported by the system through other means.
if( fp == NULL )
{
printf("File open failed for read\n");
exit(0);
}

FILE *fpo;

fpo = fopen( "scanout.bm p" , "w");
You're not opening the file in binary mode.
Translation of characters can occur in a similar way to what happens
when you read a file in not binary mode.
>
if( fpo == NULL )
{
printf("File open failed for write\n");
exit(0);
}
int c=1;
Why 1? What does it mean?
I see you're using C99 (you're mixing declarations and code). There's
nothing wrong with that as long as you understand that C99 compilers
aren't as readily available as C89 compilers, and you don't mind lose
some portability.
>
while(!feof(fp) )
{
c = fgetc(fp);
if( c>=0 )
fputc( c , fpo );
}
This loop is wrong.
feof() doesn't do what you think it does.
Read the answer to question 12.2 on the c-faq ( http://c-faq.com/ ),
and while you're there, bookmark the site and return there every now
and again.
fclose(fp);
Failed to test if the fclose() call succeded.
fclose(fpo);

}

---------------------------------------------

When I run it, it stops before it has read the entire file (it only
reads around 10%).
Jul 2 '08 #4
On Jul 2, 8:37 pm, Lew Pitcher <lpitc...@teksa vvy.comwrote:
It might be something simple that I am doing wrong.
-------------------------------------------------------------
#include <stdio.h>
main()
{
FILE *fp;
fp = fopen( "scan0001b. bmp" , "r" );

You've opened this file with the "read text" option. Presuming that the
filename represents a file in the Microsoft bitmap graphics format
(".BMP"), then this is the wrong mode to open the file in. You probably
want
fp = fopen( "scan0001b. bmp" , "rb" );
here.
Ahh, I didn't realise that there was a rb option.

Does it work exactly the same other than stopping at logic end of
file?

Can I still use things like fscanf( fp , "%c" , &variable )
Remember, feof() does not read the file, and returns true /after/ the true
read (in your case, fgetc()) returns an end-of-file condition.
Ahh, another piece of useful info.

Thanks to all that replied. This group is great for spotting non-
obvious coding errors.

A previous tip for ensuring malloc used the right size has really
reduced bugs when I use dynamic allocation.
Jul 2 '08 #5
raphfrk wrote:
On Jul 2, 8:37 pm, Lew Pitcher <lpitc...@teksa vvy.comwrote:
>>It might be something simple that I am doing wrong.
-------------------------------------------------------------
#include <stdio.h>
main()
{
FILE *fp;
fp = fopen( "scan0001b. bmp" , "r" );
You've opened this file with the "read text" option. Presuming that the
filename represents a file in the Microsoft bitmap graphics format
(".BMP"), then this is the wrong mode to open the file in. You probably
want
fp = fopen( "scan0001b. bmp" , "rb" );
here.

Ahh, I didn't realise that there was a rb option.

Does it work exactly the same other than stopping at logic end of
file?
A text stream will do whatever is necessary to translate
between C's notion of text ("lines of text-ish characters,
each terminated by a single '\n'") and the platform's own
conventions for text, whatever they might be. On Windows,
this means that a ^Z is treated as an end-of-data marker on
input (and may be generated automatically on output, for all
I know), and that line ends are marked by the pair '\r' '\n'
instead of by '\n'. Other conventions apply on other systems.
It's the stream's business to understand the conventions and
to translate them to and from C's view.

A binary stream, on the other hand, operates in a "raw
bytes" mode, without translation. What you read is what you
wrote (except that there may be extra '\0' bytes at the end).
Can I still use things like fscanf( fp , "%c" , &variable )
Yes, but it's queasy-making. Many fscanf() directives
have the text-friendly but binary-fatal habit of skipping any
leading white space characters. "%c" is not one of those, but
if you try to use "%s" or "%d" or something of that sort you
may be unpleasantly surprised.

Using `variable = getc(fp)' is simpler, harder to get wrong
(but see Question 12.1 in the FAQ), and may even be faster.
There's no need to commit canaricide by cannon.

--
Er*********@sun .com
Jul 2 '08 #6

"raphfrk" <ra*****@netsca pe.netwrote, among other things:

while(!feof(fp) )
{
c = fgetc(fp);
if( c>=0 )
fputc( c , fpo );
}

In addition to the excellent advice others here gave you,
there's one *HUGE* error here which everyone seems to have
missed somehow: the 0 byte, 0x00, is a perfectly
valid byte both for text files (ASCII, iso-8859-1, etc)
and binary (non-text) files. Many of the bytes in a
bmp file will be 0. If you omit those and close up the
gaps, you will severely corrupt the copy of the original
file. It will NOT render correctly in a graphics viewer
(Paintshop Pro, Internet Explorer, or whatever). It
probably can't even be opened, because the headers will
be screwed up.

So your while loop is wrong from several standpoints.

Try:

// Loop while file pointer is valid, until break:
while (fp)
{
c = fgetc(fp); // ATTEMPT TO READ A BYTE.
if (feof(fp)) break; // BREAK IF READ ATTEMPT FAILED.
else fputc(c, fpo); // COPY EVEN THE "0" BYTES.
}

--
Cheers,
Robbie Hatley
lonewolf aatt well dott com
www dott well dott com slant user slant lonewolf slant
Jul 2 '08 #7
"Robbie Hatley" <se************ **@for.my.email .addresswrites:
"raphfrk" <ra*****@netsca pe.netwrote, among other things:

while(!feof(fp) )
{
c = fgetc(fp);
if( c>=0 )
fputc( c , fpo );
}

In addition to the excellent advice others here gave you,
there's one *HUGE* error here which everyone seems to have
missed somehow: the 0 byte, 0x00, is a perfectly
valid byte both for text files (ASCII, iso-8859-1, etc)
and binary (non-text) files. Many of the bytes in a
bmp file will be 0. If you omit those and close up the
gaps, you will severely corrupt the copy of the original
file.
I presume you missed the = part of the >=?
It will NOT render correctly in a graphics viewer
(Paintshop Pro, Internet Explorer, or whatever). It
probably can't even be opened, because the headers will
be screwed up.

So your while loop is wrong from several standpoints.
Actually no (unless I've missed some subtlety). It is non-idiomatic
but looks to be entirely correct to me.
Try:

// Loop while file pointer is valid, until break:
while (fp)
{
c = fgetc(fp); // ATTEMPT TO READ A BYTE.
if (feof(fp)) break; // BREAK IF READ ATTEMPT FAILED.
else fputc(c, fpo); // COPY EVEN THE "0" BYTES.
}
The canonical version would be:

while ((c = fgetc(fp)) != EOF)
fputc(c, fpo);

--
Ben.
Jul 3 '08 #8
"Robbie Hatley" <se************ **@for.my.email .addresswrites:
"raphfrk" <ra*****@netsca pe.netwrote, among other things:
while(!feof(fp) )
{
c = fgetc(fp);
if( c>=0 )
fputc( c , fpo );
}

In addition to the excellent advice others here gave you,
there's one *HUGE* error here which everyone seems to have
missed somehow: the 0 byte, 0x00, is a perfectly
valid byte both for text files (ASCII, iso-8859-1, etc)
and binary (non-text) files. Many of the bytes in a
bmp file will be 0. If you omit those and close up the
gaps, you will severely corrupt the copy of the original
file. It will NOT render correctly in a graphics viewer
(Paintshop Pro, Internet Explorer, or whatever). It
probably can't even be opened, because the headers will
be screwed up.
[...]

Look again. The test is "c>=0", not "c>0". 0 bytes are treated the
same as any other valid bytes.

And I'd dispute that '\0' is a valid byte in a text file, at least for
most text formats. A text file *can* have '\0' characters, but
they'll cause problems for programs that use fgets() because they'll
be treated as string terminators.

--
Keith Thompson (The_Other_Keit h) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Jul 3 '08 #9
On Jul 3, 12:11 am, raphfrk <raph...@netsca pe.netwrote:
This program should copy one file onto the other. It works if I
compile it with gcc to a cygwin program. However, if I compile it
with the -mno-cygwin option, it doesn't work (this targets native
windows).
Just curious, do you mean that this code worked correctly in the
former case? Since the errors seems to be in your code, I don't
understand how it worked well as a cygwin program. One possible
explanation is that as cygwin emulates unix environment, it does not
distinguish between byte and text streams.
Jul 3 '08 #10

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

Similar topics

13
1867
by: Neil Zanella | last post by:
Hello, I wonder whether anyone has ever come across the following g++ compiler error message. I don't recall ever seeing it before. I solved my problem but I am still not sure about what this message is all about. Any ideas? error: invalid initialization of non-const reference of
20
1623
by: Scott Simons | last post by:
Why doesn't the compiler throw an error on a block of code like this: public string Email { get { return Email; } }
35
2176
by: Maxim Yegorushkin | last post by:
The following code: #include <iostream> class base { private: virtual ~base() { std::cout << "virtual ~base()\n";
29
2370
by: Ark | last post by:
A function int foo(struct T *x) { return (x+1)-x; } should always return a 1, no matter how T is defined. (And int could be replaced with ptrdiff_t for you pedants.) For one thing, it was amusing to watch how my compiler (the famed IAR EWARM for ARM) jumps through hoops to arrive at this answer.
8
1643
by: STG | last post by:
Greetings, My group has an SDK that was developed 5 years ago with VC++ 6. Over the last years, the requests for a VS.NET SDK has reached critical mass and I am now in the process of doing that. Actually, the first release of this 'port' is be a simple rebuild of the unmanaged C++ SDK in VS.NET. I have done this part already, using VS.NET 2003.
41
18212
by: Miroslaw Makowiecki | last post by:
Where can I download Comeau compiler as a trial version? Thanks in advice.
4
1489
by: karthikbalaguru | last post by:
Hi, Is there a possibility to fool the C compiler into believing that two data types are different by renaming one of them. I tried using typedef. But it did not work out. :(:( . C compiler was clever. Is there any other way ? Thx in advans, Karthik Balaguru
7
1645
by: eduzea | last post by:
I have some code that compiles with gcc but fails with MS VC 8. I would like to know which one is following the C++ standard. istream& istr = false ? cin : ( * new ifstream("test.txt")) ; Using g++ it compiles. Using MS VC 8 it fails with a message along the lines of: "cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>' "
0
9476
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9335
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 tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9208
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8210
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6751
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4570
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4825
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3279
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.