Thread: Why does it run differently?

  1. #16
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    I understand, and yes, the pow thing was part of the project that referred to the chapter on loops, so it was part of the practice. However we had to use about 6 to 8 more loops in the same project, so it wasn't clear to me that we had to do something so trivial using a loop until a friend told me.

    And although I see quite clearly why fgets is a much more safe apporach and good practice, we haven't been taught it yet, so I'm not going to risk a point off my project just for being more correct.

  2. #17
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Leftos View Post
    And although I see quite clearly why fgets is a much more safe apporach and good practice, we haven't been taught it yet, so I'm not going to risk a point off my project just for being more correct.
    Neither did I mean that you should, but rather suggesting that the teacher(s)/helper(s) should be able to "hide" the fact that you haven't got to fgets() in the book, and explain that "gets() is no good, use this for of fgets() instead" - without actually explaining all the ins and outs of how it works and why it's so much better. Get to WHY it's better when you get to that part of the book [and explaining how and why this is important, somewhere in the education too!].

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  3. #18
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    It would seem to me that you're on the wrong course then. Since you already know some stuff, and have the sense to go digging for information yourself, you're already a step above the noobs who have to be spoon-fed all the way.

    > Herbert Schildt's Teach Yourself C
    Well if this is the reference text, then everybody is on the wrong course.
    Schildt is famous for many many low-quality publications.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #19
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Leftos View Post
    Same goes with Elysia's complaint. Of course I have wondered why every C compiler I've used complains about "gets" being very dangerous, and of course I'd love to use fgets, however we've only been taught scanf and gets, Chapter 2 and Chapter 5, while fgets is on Chapter 9, thus, no can't do mister.
    Now THAT is madness. Gets is very dangerous because it can very easily create buffer overruns. Gets should never, ever be used. It should not even be teached!
    It never fails to amaze me how teacher and books learn people to use gets or other unsafe functions.
    As matsp mentioned there, fgets(buffer, size, stdin) is the same as doing gets(buffer) and it much, much safer. Gets is just a dumb version of fgets, basically.
    Complain at those who teach you if you want, but please, use fgets or at the very least learn how to use it. In a real application you should NEVER use gets.
    And btw, even for school projects, it can be dangerous as soon as you run the application. It can even crash. Doesn't look good, does it?
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  5. #20
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    I fully understand the risk of gets and the usefullness of fgets. And from what I've learned today, come the day I start programming in C for anything besides uni's projects, I'll use fgets. But for now, I don't want my grade lowered just because I'm using something I've not been taught.

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Complain at your teacher, though. Always a good thing. Tell them not to teach dangerous stuff.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  7. #22
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Leftos View Post
    I fully understand the risk of gets and the usefullness of fgets. And from what I've learned today, come the day I start programming in C for anything besides uni's projects, I'll use fgets. But for now, I don't want my grade lowered just because I'm using something I've not been taught.
    For some reason computer science is fraught with bad instructors. Some of the absolute worst designed code I've ever seen was written by CS Ph. D's. These people are well versed in arcane topics and understand computer science and mathematics really well, but they have very little engineering skill. I don't mean to make a blanket statement. I have also seen some incredibly good code.

    In my experience it is impossible to change these people's opinions no matter how wrong they are. Especially in the lower-numbered classes, the instructors sometimes don't even use the languages they are teaching. The best you can do is give them what they expect while keeping in mind that you are actually using bad techniques. Write a version for yourself that does it right. I wish it wasn't this way, but it's how it is. For now.

  8. #23
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Here's something I don't understand. Well, another thing. Given the input is 7.6...

    Code:
    float a;
    scanf("%f", &a);
    printf("%f", a * 10);
    ...gives 75.999999, while...

    Code:
    float a;
    scanf("%f", &a);
    a = a * 10;
    printf("%f", a);
    ...gives 76.000000. Why is that?

    A better all-around check:

    Code:
    	float a, b;
    	int inta;
    	scanf("%f", &a);
    	b = a * 10;
    	inta = (int)(a * 10);
    	printf("%f %f %f %d", a, a * 10, b, inta);
    Output: 7.600000 75.999999 76.000000 75
    Last edited by Leftos; 12-12-2007 at 04:37 AM.

  9. #24
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Leftos View Post
    Here's something I don't understand. Well, another thing. Given the input is 7.6...

    Code:
    float a;
    scanf("%f", &a);
    printf("%f", a * 10);
    ...gives 75.999999, while...

    Code:
      
    float a;
    scanf("%f", &a);
    a = a * 10;
    printf("%f", a);
    ...gives 76.000000. Why is that?
    because the calculation is done a little bit differently - or the conversion from float to double is done differently [all floating point parameters to printf are double] , perhaps. You probably will find other cases where there are differences.

    Actually, I reproduced the results you got on my machine, and there is a difference between the two code-sets is:
    Code:
    	fmulp	%st, %st(1)
    	fstps	-4(%ebp)
    	flds	-4(%ebp)
    	fstpl	4(%esp)
    This stores the value back in a, and then loads it and stores it as a double on the stack for printf. In the "just multiply a by ten", the red code is not present, meaning the more precise double value is stored onto the stack. Note that the precision of (x87) floating point calculations is decided at the store stage, not during the actual calculation.

    I do apologize if you don't fancy reading assembler code and understanding what it means - but there's no way to explain the behaviour in any other way.

    --
    Mats
    Last edited by matsp; 12-12-2007 at 04:51 AM.
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #25
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    Don't worry. I'm glad you're still answering to my issues and explaining so well.

    So the correct way to do floating point calculations would be outside functions such as printf. Here is the loop that made the program work on my computer too.

    Code:
    		do
    		{
    			printf("Dwse vathmo %dou ma8hth: ", i + 1);
    			scanf("%f", &vathmoi[i]);
    			vathmoi10 = vathmoi[i] * 10;
    		}
    		while ((int)(vathmoi10) != vathmoi10 | vathmoi[i] < 0 | vathmoi[i] > 10);
    Thanks for all the help and info anyway, it's been very helpful. A little testing always helps and in this case taught me something.

    I'm still wondering, though, about why the other exercise with the inverted string doesn't work on my computer but works on the server.

  11. #26
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Leftos View Post
    Don't worry. I'm glad you're still answering to my issues and explaining so well.

    So the correct way to do floating point calculations would be outside functions such as printf. Here is the loop that made the program work on my computer too.

    Code:
    		do
    		{
    			printf("Dwse vathmo %dou ma8hth: ", i + 1);
    			scanf("%f", &vathmoi[i]);
    			vathmoi10 = vathmoi[i] * 10;
    		}
    		while ((int)(vathmoi10) != vathmoi10 | vathmoi[i] < 0 | vathmoi[i] > 10);
    Thanks for all the help and info anyway, it's been very helpful. A little testing always helps and in this case taught me something.

    I'm still wondering, though, about why the other exercise with the inverted string doesn't work on my computer but works on the server.

    The red code above is broken in two senses:
    1. It's comparing an integer with a float, which is likely to fail under some circumstances [you just don't KNOW what those circumstances may be] due to floating point not being precise.
    Code:
    fabs((int)(vathmoi10) - vathmoi10) > 0.01
    would be a better solution.
    2. You are using bitwise or rather than logical or, which isn't quite the same thing - it sort of works OK for this case, but it's the wrong thing to do here. Use || instead of | and all will be fine.


    As someone else suggested:
    Code:
            char linet[strlen(line)];
            char linet2[strlen(line)];
    should probably be
    Code:
            char linet[strlen(line)+1];
            char linet2[strlen(line)+1];
    Although both are a bit dubious as they are extensions to gcc, so won't work on other compilers. Perhaps this is the best solution:
    Code:
            char linet[200];
            char linet2[200];
    You also should set the end-marker of linet2 to zero - currently you just leave it to whatever it happens to be. Since different machines have different "stuff" sitting around in stack-based locations, what actually ends up at the end of the string is completely random, and on one machine it may be zero, on another some other value, so you get "random failyures" - it may even be different for different length strings.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  12. #27
    Registered User
    Join Date
    Dec 2007
    Posts
    53
    I made it work. Thanks. I declared linet and line2 as 200 in size (can't declare after gets, obviously, and we haven't practiced subroutines yet), and made sure to add '\0' to linet2 on position strlen(linet). Now any string works.

    Thanks everyone, you've been really helpful!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Re-doing a C program to run in Win2000 or XP
    By fifi in forum C Programming
    Replies: 5
    Last Post: 08-17-2007, 05:32 PM
  2. how to run an exe command in c++ and get back the results?
    By mitilkhatoon in forum C++ Programming
    Replies: 5
    Last Post: 09-21-2006, 06:00 PM
  3. calculating the mode
    By bigggame in forum C Programming
    Replies: 10
    Last Post: 06-13-2006, 03:04 AM
  4. How I can Run exe file in C++
    By palang in forum C++ Programming
    Replies: 2
    Last Post: 05-10-2006, 11:55 AM
  5. Replies: 2
    Last Post: 10-29-2002, 04:56 PM