473,395 Members | 1,622 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

Gcc doesn't seem to get my scanf right, but Visual Studio does, what's wrong?

Bangonkali
First I actually thought there was something wrong with my programming skills. But after I compiled the same code using Visual Studio, it worked. So here's the code that doesn't seem to be working right with gcc compilers, but they do compile. Note I'm using the Cygwin 3.4.4 version of gcc and 4.5.1 version of gcc from MinGW.

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main()
  4. {
  5.     long double r = 0;
  6.     long double p = 0;
  7.  
  8.     printf ("Enter a number: ");
  9.     scanf ("%lf", &r);
  10.     printf ("Enter its power: ");
  11.     scanf ("%lf", &p);
  12.     printf ("%lf to the power of %lf = %lf\n", r, p, pow(r, p));
  13.  
  14.     printf ("7 ^ 3 = %lf\n", pow (7.0,3.0));
  15.     printf ("4.73 ^ 12 = %lf\n", pow (4.73,12.0));
  16.     printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
  17.     return 0;
  18. }
This is the first one. It compiles with GCC but the output doesn't seem to be what I'm expecting. (MinGW gcc (GCC) 4.5.1)
Expand|Select|Wrap|Line Numbers
  1. Enter a number: 5
  2. Enter its power: 3
  3. 5.000000 to the power of 0.000000 = 0.000000
  4. 7 ^ 3 = 343.000000
  5. 4.73 ^ 12 = 125410439.217423
  6. 32.01 ^ 1.54 = 208.036691
The part "5.000000 to the power of 0.000000 = 0.000000" doesn't seem to be right. But on the other hand, when I compiled it using Visual Studio, it worked very well.
Expand|Select|Wrap|Line Numbers
  1. Enter a number: 5
  2. Enter its power: 3
  3. 5.000000 to the power of 3.000000 = 125.000000
  4. 7 ^ 3 = 343.000000
  5. 4.73 ^ 12 = 125410439.217423
  6. 32.01 ^ 1.54 = 208.036691
I looked for a solution in the internet and I found sscanf. I tried to modified the code, it still compiles with gcc but yielding the same results.
Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main()
  4. {
  5.     char line[100];
  6.     long double r = 0;
  7.     long double p = 0;
  8.  
  9.     printf ("Enter a number: ");
  10.     fgets(line,sizeof(line),stdin);
  11.     sscanf(line,"%lf",&r);
  12.  
  13.     printf ("Enter its power: ");
  14.     fgets(line,sizeof(line),stdin);
  15.     sscanf(line,"%lf",&p);
  16.  
  17.     printf ("%lf to the power of %lf = %lf\n", r, p, pow(r, p));
  18.  
  19.     printf ("7 ^ 3 = %lf\n", pow (7.0,3.0));
  20.     printf ("4.73 ^ 12 = %lf\n", pow (4.73,12.0));
  21.     printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
  22.     return 0;
  23. }
Using the gcc compiler of MinGW this is the result: (MinGW gcc (GCC) 4.5.1)
Expand|Select|Wrap|Line Numbers
  1. Enter a number: 5
  2. Enter its power: 3
  3. 5.000000 to the power of 0.000000 = 0.000000
  4. 7 ^ 3 = 343.000000
  5. 4.73 ^ 12 = 125410439.217423
  6. 32.01 ^ 1.54 = 208.036691
The previous yields the same result as before where the part "5.000000 to the power of 0.000000 = 0.000000" is not working as intended. If I use the compiler from Visual Studio 2008 C++, this is the result:
Expand|Select|Wrap|Line Numbers
  1. Enter a number: 5
  2. Enter its power: 3
  3. 5.000000 to the power of 3.000000 = 125.000000
  4. 7 ^ 3 = 343.000000
  5. 4.73 ^ 12 = 125410439.217423
  6. 32.01 ^ 1.54 = 208.036691
Dec 11 '10 #1

✓ answered by AdrianH

Cool, so what sort of scientific research are you doing that requires this sort of precision?


A

12 7478
donbock
2,426 Expert 2GB
Perhaps the difference in line termination (LF vs CR-LF) between unix [Cygwin] and DOS [Visual Studio] is catching you. You should be testing the return code from scanf.
Dec 12 '10 #2
AdrianH
1,251 Expert 1GB
No, looks like a bug. Submitting to gcc bugzilla. Bug 46908


A
Dec 12 '10 #3
Thanks guys! But I think I have found the answer to my problem now. According to someone who replied to my email it was because gcc was keeping a space in the keyboard buffer. And you can tell if the same thing's happening again if the second input is always 0. He said I should try to use the following code separated by a space instead:

Expand|Select|Wrap|Line Numbers
  1. scanf( "%lf %lf", &r, &p );
I edited my original code to work like this:

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main()
  4. {
  5.     // my personal troubles with long double
  6.     // while using gcc under cygwin and mingw
  7.     long double r = 0;
  8.     long double p = 0;
  9.     long double a = 0;
  10.  
  11.     printf ("Enter a number <space> power: ");
  12.     scanf( "%Lf %Lf", &r, &p );
  13.  
  14.     // r to the power of p
  15.     a = pow(r,p);
  16.  
  17.     printf ("%.2Lf to the power of %.2Lf = %.2Lf\n", r, p, a);
  18.     printf ("7 ^ 3 = %.2Lf\n", (long double)pow(7.0,3.0));
  19.     printf ("4.73 ^ 12 = %.2Lf\n", (long double)pow(4.73,12.0));
  20.     printf ("32.01 ^ 1.54 = %.2Lf\n", (long double)pow(32.01,1.54));
  21.     return 0;
  22. }
Now it works perfectly fine with the following output when compiled with gcc both from MinGW and Cygwin.

Expand|Select|Wrap|Line Numbers
  1. 5.00 to the power of 3.00 = 125.00
  2. 7 ^ 3 = 343.00
  3. 4.73 ^ 12 = 125410439.22
  4. 32.01 ^ 1.54 = 208.04
I still don't know how accept value from a second scanf though. If anyone of you who knows how to circumvent this issue please help. I need to accept the second input only after the return has been pressed from the first input and not separated by space.
Dec 12 '10 #4
THIS PROBLEM IS SOLVED! Thank you for everyone who replied. Not only from this forum but also from all the other forums which I sent this problem to.

First let me summarize the problem. I'm using scanf to accept a long double value from the user. I used %Lf to accept this and used %.2Lf to printf it. The problem is that I can't do more than 2 scanf's because I can only read the first one if I used Cygwin's gcc compiler and MinGW's gcc compiler. The same code works with VSC++ though.

However, if I use only double, and use %lf to scanf and printf data, the programs works quite well even if I have many scanf's.

A person from one forum gave me an idea about keyboard caching. Which basically means, after I enter a value from the first %Lf (long double) another character is also received which totally messes up the next scanf. And thus when I run my initial code, I receive a 0 value for the next scanf.

I found out that by putting getchar() from between the two scanf's I can circumvent the issue. Let me repeat, the problem only works on long double scanf's using %Lf, it doesn't occur on only doubles using %lf. The following is my final code that really works on gcc.

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. #include <math.h>
  3. int main()
  4. {
  5.     // my personal troubles with long double
  6.     // while using gcc under cygwin and mingw
  7.     long double r = 0;
  8.     long double p = 0;
  9.     long double a = 0;
  10.  
  11.     //printf ("Enter a number <space> power: ");
  12.     //scanf( "%lf %lf", &r, &p );
  13.  
  14.     printf ("Enter a number: ");
  15.     scanf( "%Lf", &r);
  16.  
  17.     printf ("Enter a number: ");
  18. getchar();    
  19.     scanf( "%Lf", &p );
  20.  
  21.     // r to the powler of p
  22.     a = pow(r,p);
  23.  
  24.     // put (long double) typecast before pow if you're
  25.     // printing pow directly on printf and you're using
  26.     // Cygwin's gcc (GCC) 3.4.4. You may not edit this 
  27.     // code if you're compiling on VSC++ or MinGW's gcc 
  28.     // (GCC) 4.5.1
  29.     printf ("%.2Lf to the power of %.2Lf = %.2Lf\n", r, p, a);
  30.     printf ("7 ^ 3 = %.2Lf\n", pow(7.0,3.0)); 
  31.     printf ("4.73 ^ 12 = %.2Lf\n", pow(4.73,12.0));
  32.     printf ("32.01 ^ 1.54 = %.2Lf\n", pow(32.01,1.54));
  33.     return 0;
  34. }
And also, because of the problem I learned something odd. If you are going to compile with Cygwin's gcc (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) make sure to add (long double) type casting before pow(4.73,12.0) if you are going to directly printf it using %Lf. But if you're going to use MinGW's gcc (GCC) 4.5.1, you must not put (long double) type casting before pow(4.73,12.0) if you are going to directly printf it using %Lf. But both ways work with VSC++. :D

I'm just a newbie here and without the help of the many people who replied I could not have found the idea about the getchar() to solve this problem. I didn't know there really are a lot of good people around the internet. And seriously, I'm really sorry for those who I have annoyed because i sent the same thread to many forums. Thank you guys. THIS THREAD IS SOLVED. :D
Dec 12 '10 #5
AdrianH
1,251 Expert 1GB
Please look at the bug report with the test code I submitted. It is a bug. It should not be responding that way.


A
Dec 12 '10 #6
THIS THREAD IS SOLVED You were using %lf for long double. It should be %Lf. As noted, the status of your bug report is RESOLVED INVALID, which basically means, it was a false report. Once again, for long double, use %Lf and not %lf. I commited that mistake in my first post, which lead me to believe it was a bug. I've learned a lot since then though. And bte, thank you so much for clarifying your point, I missed it out in the first post. THIS THREAD IS SOLVED
Dec 12 '10 #7
AdrianH
1,251 Expert 1GB
Well, I've retested with %Lf with the same results and resubmitted the bug. Looks like gcc 4.5.0 doesn't recognise %Lf for scanf, so it is either a bug or it hasn't been implemented yet. Also, to get printf to recognise %Lf, you need to change the standard settings with compiler flag -std=c99.

Something else I forgot to do, but always did when I was using gcc is to use the -Wall switch. This will pick up many inadvertent errors in the code.


A

[edit]bug has been resubmitted.
Dec 12 '10 #8
AdrianH
1,251 Expert 1GB
Also, IIRC, white spaces are ignored unless expressly stated not to be. I.e. use %[ a-zA-Z_0-9] as a format string. So, your solution is a workaround, not a code correct solution.


A
Dec 12 '10 #9
Yes you do have a point there.
Dec 12 '10 #10
This thread is solved. Yes, I think this article explains things very clearly. Following is a quote from the article

After months of experimentation, I have settled on MinGW/MSYS as the best development environment for my purposes. Its advantages include the following:
Full support (for internal calculations) of 80-bit long doubles (including transcendentals) and 64-bit integers; note, however, that the printf/scanf family produces erroneous results for long doubles, and uses peculiar syntax for 64-bit integers.
Disadvantages of the MinGW/MSYS environment include the following:
The printf/scanf family of functions is unable to correctly handle the 80-bit long double floating point variables native to the x86 Intel processors and FPUs (and compatible processors, such as AMD). Either the value must be cast to double and printed, with resulting loss of precision (16 digits rather than 19), or a custom function must be employed for the purpose.
I am only experiencing these problems because I'm using Cygwin and MinGW gcc versions when testing my code. And yes I think this is a bug, and very clearly needs fixing. Since they're offering long double datatype, they should at least make scanf and printf work with it. Anyway, thanks for the follow up.

And also, I found out the most efficient solution for my problem which is requiring very high precision mathematical calculations as suggested by the article. By using GMP 4.3.1 and MPFR 2.4.1 I was able to use very high precision datatypes from its libraries without problems with printf() and scanf(). I am posting an example below.

The following codes will be solving this series:
Expand|Select|Wrap|Line Numbers
  1. 1 + (1 / 1!) + (1 / 2!) + ... + (1 /100!) 
Solving the problem with stdio.h only:
Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2. int main (void)
  3. {
  4.   unsigned int i;
  5.   double s, t, u;
  6.  
  7.   t = 1;
  8.   s = 1;
  9.   u = 1;
  10.  
  11.   for (i = 1; i <= 100; i++)
  12.     {
  13.         t = t * i;
  14.         u = 1;
  15.         u = u / t;
  16.         s = s + u;
  17.     }
  18.  
  19.   printf ("Sum is %lf \n", s);
  20.   return 0;
  21. }
Solving the series using GMP 4.3.1 and MPFR 2.4.1 (CYGWIN):

Expand|Select|Wrap|Line Numbers
  1. #include <stdio.h>
  2.  
  3. #include <gmp.h>
  4. #include <mpfr.h>
  5.  
  6. int main (void)
  7. {
  8.   unsigned int i;
  9.   mpfr_t s, t, u;
  10.  
  11.   mpfr_init2 (t, 200);
  12.   mpfr_set_d (t, 1.0, GMP_RNDD);
  13.   mpfr_init2 (s, 200);
  14.   mpfr_set_d (s, 1.0, GMP_RNDD);
  15.   mpfr_init2 (u, 200);
  16.   for (i = 1; i <= 100; i++)
  17.     {
  18.       mpfr_mul_ui (t, t, i, GMP_RNDU);
  19.       mpfr_set_d (u, 1.0, GMP_RNDD);
  20.       mpfr_div (u, u, t, GMP_RNDD);
  21.       mpfr_add (s, s, u, GMP_RNDD);
  22.     }
  23.   printf ("Sum is ");
  24.   mpfr_out_str (stdout, 10, 0, s, GMP_RNDD);
  25.   putchar ('\n');
  26.   mpfr_clear (s);
  27.   mpfr_clear (t);
  28.   mpfr_clear (u);
  29.   return 0;
  30. }
Output after compiling first code with gcc 3.4.4:
Expand|Select|Wrap|Line Numbers
  1. Sum is 2.718282
The second code:
Expand|Select|Wrap|Line Numbers
  1. Sum is 2.7182818284590452353602874713526624977572470936999595749669131
We can observe the sheer precision with 200 bit representation of double in this case compared to the standard double as shown in the first result from the first code.

I tried everything under Cygwin. But do note that you'll need to have the GMP ang MPFR libraries added during setup. Finally in order to compile the second code (the one using GMP and MPFR), if you've already installed GMP and MPFR use the following command:
Expand|Select|Wrap|Line Numbers
  1. gcc mpfr_sample.c -o mprfr_sample.exe -lmpfr -lgmp
For more information regarding the libraries visit MPFR Main Website and for the sample. I hope this will help everyone who are doing precision arithmetic for scientific research.
Dec 13 '10 #11
AdrianH
1,251 Expert 1GB
Cool, so what sort of scientific research are you doing that requires this sort of precision?


A
Dec 13 '10 #12
This is for my Math research. Mostly pure math. Calculating series and sequences. Taylor's, Maclaurin's and Binomial series. I need some way to verify calculation to the n'th decimal place without loss of integrity. I'm still testing this though.
Dec 13 '10 #13

Sign in to post your reply or Sign up for a free account.

Similar topics

10
by: Greener | last post by:
Hi, I need help badly. Can you do client-side programming instead of server-side to capture the Browser type info? If this is the case, what's wrong with the following? <script...
33
by: John Timbers | last post by:
I'd like to purchase Visual C# .Net for learning purposes only since it's a lot cheaper than Visual Studio (note that I'm a very experienced C++ developer). Can someone simply clarify the basic...
5
by: Daniele | last post by:
Hi, how is it possible to create a project with a specific template, compile it and close it? All with a c# script. Thanks, Daniele
4
by: fyleow | last post by:
I create a new Python file with the following using Wing IDE. import feedparser d = feedparser.parse("http://feedparser.org/docs/examples/atom10.xml") print d.feed.title I get this error when...
5
by: Nathan Sokalski | last post by:
I recently upgraded from Visual Studio .NET 2003 to Visual Studio .NET 2005. Visual Studio .NET 2005 does not create the Global.asax files that Visual Studio .NET 2003 did, which I used for...
6
by: Jerad Rose | last post by:
I recently installed Visual Studio 2003, after having already installed VS 2005. Unfortunately, it took over all of the file associations. There is an option in Visual Studio 2005 to restore...
0
by: ShimmyShine | last post by:
My laptop is a HP Compaq nc6000. My OS is Windows XP Professional Service Pack 2. And I am not sure what is wrong but I can't seem to install visual studio 5.0. I bought it, came home on my older...
2
by: lamanvic | last post by:
i am trying to create a list of array with random numbers and use the colour sort to sort them to let the negative number on LHS zero in middle and positive number on RHS and print out the sorted...
0
by: Sin Jeong-hun | last post by:
http://misako.co.kr/externaldata/Test.aspx I've created a very simple user control which just has a label on it. I followed the instruction but it doesn't show up. I don't know what's wrong...
0
jwwicks
by: jwwicks | last post by:
Introduction This tutorial describes how to use Visual Studio to create a new C++ program, compile/run a program, resume work on an existing program and debug a program. It is aimed at the...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
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,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.