Thread: fgets only returns 3 characters

  1. #76
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    Quote Originally Posted by laserlight View Post
    Ah, but with no source files, all the implementation is in the header files, so how can your clients both not see the implementation and yet be able to use it unless you end up treating your other header file as a source file (and thus compile and link its respective object file), upon which you might as well admit that it is a source file and use a conventional file extension for it?
    I don't understand your objection, but here's how I would do it (condensed with comments). Only the first file would be distributed as plain text.

    list-decl.h
    Code:
    struct ListNode {
       /* ... */
    };
    
    struct List {
       /* ... */
    };
    
    /* ... function declarations ... */
    list.h
    Code:
    #include "list-decl.h"
    
    /* ... function definitions ... */
    main.c
    Code:
    #include "list.h"
    
    /* ... */

  2. #77
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I don't understand your objection, but here's how I would do it (condensed with comments). Only the first file would be distributed as plain text.
    Okay, I understand your idea now. Yes, assuming that you carefully avoid redefinition errors, that will work, but of course when your project gets large enough, you will get insanely long compile times despite making a small change (and this is one criticism of the use of C++ templates without import). What's the point of avoiding linking separate object files?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #78
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    Quote Originally Posted by laserlight View Post
    Okay, I understand your idea now. Yes, assuming that you carefully avoid redefinition errors, that will work, but of course when your project gets large enough, you will get insanely long compile times despite making a small change (and this is one criticism of the use of C++ templates without import).
    Doesn't the compiler stop at a function's redefinition? But that would prolong the compilation delay even more.

    Quote Originally Posted by laserlight View Post
    What's the point of avoiding linking separate object files?
    Just that I'm a newbie who adopted that method from the start. It doesn't matter much while I use an IDE, but I don't quite understand how to link the files myself yet. Yes, I understand the commands, but I will probably have questions if I ever try it on my own. But that was a mostly academic argument because, as someone who plays the answerer's role on another board, I know you're probably right anyway; I just wanted to understand everything.

  4. #79
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Doesn't the compiler stop at a function's redefinition?
    Yes, hence if you are not careful, it obviously won't work

    But that would prolong the compilation delay even more.
    I suppose so, but then you probably would check before adding a new struct and such.

    That said, squeezing out performance is a valid reason for not linking separate object files. SQLite's amalgamation takes that approach, with "performance improvements of between 5 and 10%" claimed. Note, however, that development proceeds normally with the header + source file approach, but the amalgamation is generated at build time via a makefile.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #80
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    Quote Originally Posted by laserlight View Post
    Yes, hence if you are not careful, it obviously won't work
    But that's the same as any compile-time error, right?

    I'm modifying arpsmack's code, and pointer arithmetic doesn't want to work:
    Code:
    main.c:44: warning: assignment makes pointer from integer without a cast
    (I use a reference to the char array's first index because the whole thing, when printed in GDB, displays as the actual string plus 1000-odd characters.) Because of that warning's cause, the whole while-loop busts.

    EDIT: Duh. I don't need the pointer arithmetic because I'm not finding the index of the character in the string like the example I went off of. Sorry!

    EDIT2: Now I wonder why puts isn't printing anything?
    Last edited by Jesdisciple; 08-31-2008 at 01:38 PM.

  6. #81
    Registered User
    Join Date
    Jan 2008
    Posts
    290
    Probably because your tree doesn't contain pointers to strings, it contains pointers to Line structs. I don't think puts() knows how to print a Line struct..

  7. #82
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    I somehow got the exact same warning as above for a different situation:
    Code:
    main.c:44: warning: assignment makes pointer from integer without a cast
    The argument to the constructor is a pointer, and a pointer is returned... Where's the integer?

    After I have an error/warning-free build again, I'm going to implement more of your suggestions.

  8. #83
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    This is line 44.

    Code:
                line = line_create(&buf[0]);
    There is no function "line_create" in line.h - I didn't download the other 4 files, I expect it to be in line.h.

    With no prototype, the compiler will "guess" that your function returns an integer, and line is not an integer but a pointer, so you get a warning for converting an integer to a pointer.

    --
    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.

  9. #84
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I picked a file at random -- tree.c -- and here are some of my comments about it.
    Code:
    #define eprintf(fmt, ...) fprintf(stderr, "%s() : line %d : " fmt, __func__, __LINE__, ##__VA_ARGS__)
    __func__ and __VA_ARGS__ are C99 only, so if you're hoping for C89 compatibility you might want to use something like this.
    Code:
    #if defined(__STDC_VERSION) && __STDC_VERSION__ >= 199901L
        #define eprintf(fmt, ...) fprintf(stderr, "%s() : line %d : " fmt, __func__, __LINE__, ##__VA_ARGS__)
    #else  /* not C99 */
        #define eprintf(fmt, ...) fprintf(stderr, "unknown : line %d : error\n", __LINE__)
    #endif
    Note: I'd suggest using __FILE__ as well, it can be very useful. main.c:23 tells you all you need to know, after all.

    Code:
    TreeNode *tree_add(Tree *this, void *value, TreeNode *before){
    "this" is a C++ keyword. You might want to avoid using identifiers of that name.

    Code:
    Tree *tree(int (*compare)(void *, void *)){
    I don't know about you, but I like using typedefs when I pass function pointers to functions.

    Now from line.c:
    Code:
    this->text = malloc(length * sizeof(char));
    sizeof(char) is always, always 1, so you can leave it out of that expression if you like.

    Code:
    char copy[length];
    Variable-length arrays are C99 too . . .

    Code:
    Line *line_create(const char const *string){
    Repeating const does nothing useful. I suspect you wanted
    Code:
    Line *line_create(const char *const string){
    It does do something different if it's on the other side of the asterisk.

    Oh, and &copy[0] is the same as copy.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  10. #85
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    It does do something different if it's on the other side of the asterisk.
    which prevent walking the string using the passed pointer - it has no much meaning and just causes inconvinience in the function body
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  11. #86
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    Quote Originally Posted by dwks View Post
    Note: I'd suggest using __FILE__ as well, it can be very useful. main.c:23 tells you all you need to know, after all.
    How would __FILE__ complete the notice that a file couldn't be read? Doesn't it hold the address of the file being executed?

    Quote Originally Posted by vart View Post
    which prevent walking the string using the passed pointer - it has no much meaning and just causes inconvinience in the function body
    But I don't plan on changing the pointer at all... Isn't this justification equal to that for using the first const?

  12. #87
    Technical Lead QuantumPete's Avatar
    Join Date
    Aug 2007
    Location
    London, UK
    Posts
    894
    Quote Originally Posted by Jesdisciple View Post
    How would __FILE__ complete the notice that a file couldn't be read? Doesn't it hold the address of the file being executed?
    No, you misunderstood, __FILE__ gets replaced by the name of your source file at compile time. So if you print it out when you have an error, you know exactly which file the error happened. Together with __LINE__ can be very useful in tracking down where an error occurred. Of course, unique error messages will do the same for you...

    QuantumPete
    "No-one else has reported this problem, you're either crazy or a liar" - Dogbert Technical Support
    "Have you tried turning it off and on again?" - The IT Crowd

  13. #88
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Isn't this justification equal to that for using the first const?
    changing data pointed by the pointer passed to the function will affect the calling function
    so the first const gives the calling function info about possible state of the data passed by pointer

    changing pointer inside the called function will not affect pointer in the calling function, so the second const makes nothing for the calling function and only adds meaningless restrictions to the code of the called funtion

    it is just as if you write
    int myfunc(const int x);

    what good it makes?
    All problems in computer science can be solved by another level of indirection,
    except for the problem of too many layers of indirection.
    – David J. Wheeler

  14. #89
    Registered User
    Join Date
    Aug 2008
    Posts
    129
    OK, so it's not equal. But if I don't plan on modifying the value, and then I accidentally do so, the second const reminds me that I'm not supposed to be doing that. If I need to modify the value that bad, I can remove the const.
    Last edited by Jesdisciple; 09-01-2008 at 01:35 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Lame null append cause buffer to crash
    By cmoo in forum C Programming
    Replies: 8
    Last Post: 12-29-2008, 03:27 AM
  2. HELP!!!!emergency Problem~expert please help
    By unknowppl in forum C++ Programming
    Replies: 9
    Last Post: 08-21-2008, 06:41 PM
  3. HELP!!!!emergency ~expert please help
    By unknowppl in forum C Programming
    Replies: 1
    Last Post: 08-19-2008, 07:35 AM
  4. gets vs fgets
    By strobo in forum C Programming
    Replies: 10
    Last Post: 03-27-2002, 05:28 PM