Thread: Need help with altering info on a txt file

  1. #16
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    That's why we need user-editable FAQs!

    Indeed, it doesn't work. I was thinking of printf(), in which an asterisk indicates the width or whatever of a field.

    You should (I know you can't edit it, but keep it in mind for the Wiki) add a note about error checking. Number of format specifiers for scanf(), NULL for fgets().
    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.

  2. #17
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    I'm thinking of adding/changing into this:

    MSDN has an article on scanf and how you specify the size: http://msdn2.microsoft.com/en-us/lib...x1(VS.80).aspx
    Remember that scanf also stops reading at the first blank space ( ), so if you type something like "Hello World" - it will only read "Hello". Both of these problems can be fixed using fgets.
    But wait! There's a third problem with scanf! If scanf encounters some characters it doesn't want to read, it simply leaves them in the buffer - so in the example above with "Hello World", there will still be " World" left in the buffer after scanf returns! That means the next time you call scanf to read something from the user, it will read this " World" and not prompt the user for anything.
    Further, even if the user does enter something and scanf reads it, it will usually leave the newline ('\n') in the buffer so the next call to scanf will return immediately just like the above example!
    To fix this, usually you would do a loop with getchar until get clear the input buffer of all remaining characters (see examples). Then scanf will behave as expected again.
    But you can also just use fgets, which takes an argument for buffer size. Here's documentation for fgets on MSDN: http://msdn2.microsoft.com/en-us/lib...kf(VS.71).aspx
    Remember that fgets reads an entire line and also stores the '\n' (the newline) in your buffer.

    And lastly, I will differentiate between '\0', 0 and NULL.
    Essentially, they all translate to the same thing to the compiler - 0. However, this does NOT mean that you should assign NULL to a character index.
    Code:
    char buffer[10];
    buffer[0] = NULL; /* Bad! */
    NULL is used to set pointers to point at 0 only, and with pointers only. Usually, 0 is an guaranteed to be invalid address (at least in Windows), so we typically set pointers to NULL when we don't need them so as to flag them, "these are not valid pointers anymore, don't use them."
    With strings, you should preferably use '\0' since it's the actual character for terminating strings. 0 is the same, so it's fine to assign 0, too, but it is recommended to use '\0'.
    Code:
    char buffer[] = "Hello World!";
    buffer[5] = 0; /* Buffer will now be "Hello" */
    buffer[5] = ' '; /* Buffer will now be "Hello World!" */
    buffer[5] = '\0'; /* Buffer will now be "Hello" */
    Take heed also that NULL is defined as ((void*)0) in C since it's supposed to be used with pointers only (it's quite valid in C). Although due to C's poor type safety, it's possible to assign NULL to a character array, though you may get a warning. Right, so the idea is to avoid compiler warnings, so don't do it. The idea with 0, '\0' and NULL are all to avoid confusion. Use them where appropriate or you might confuse someone else how reads your code.
    As a last note, NULL is defined as 0 in C++, so it's easier to get away with setting a character array to NULL, but again, don't do it.
    ...And...

    And lastly... an example of how to strip trailing newlines from your buffer:
    Code:
    char buffer[100];
    int size;
    fgets(buffer, sizeof(buffer), stdin);
    size_t size = strlen(buffer);
    if (buffer[size - 1] == '\n') buffer[size - 1] = '\0';
    This code will basically take the length of the string and loop so long as the last element in the array is '\n' (newline). If it is a newline, it will truncate the value with '\0' (which essentially sets this as the new end of the string).
    Please correct any mistakes
    Last edited by Elysia; 12-21-2007 at 03:26 AM.
    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.

  3. #18
    Beautiful to C Aia's Avatar
    Join Date
    Jun 2007
    Posts
    124
    Quote Originally Posted by Elysia View Post
    Please correct any mistakes
    Why a for loop to iterate the whole string when the only newline we care about is the last one before the null terminator?
    Why the calling of strlen() so many times?

    Code:
       fgets( user_input, sizeof user_input, stdin );
        
        len = strlen( user_input ) - 1; /* get the lenght of string before '\0' */
        if ( user_input[len] == '\n' )/* if there's a new line before '\0' */
        {
             user_input[len] = '\0'; /* eliminate the '\n' */
        }
    Last edited by Aia; 12-20-2007 at 06:45 PM.

  4. #19
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    I like assigning the return value of strlen() to variables of type size_t, because that's strictly what it should be -- although many people just use ints. size_t is unsigned, so assigning it to an int gives you some warnings when you enable them. In addition, with REALLY long strings, an int might not have enough range.

    NULL is used to truncate pointers, and with pointers only.
    "Truncate"? Not exactly. More like, "assigning NULL to a pointer makes the pointer point at nothing". Also consider linking to http://faq.cprogramming.com/cgi-bin/...&id=1043284376

    Code:
    buffer[5] = '\0'; /* Buffer will not be "Hello" */
    You mean "now", right?

    I'm telling you, we need a Wiki FAQ . . . .
    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.

  5. #20
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Aia View Post
    Why a for loop to iterate the whole string when the only newline we care about is the last one before the null terminator?
    Why the calling of strlen() so many times?

    Code:
       fgets( user_input, sizeof user_input, stdin );
        
        len = strlen( user_input ) - 1; /* get the lenght of string before '\0' */
        if ( user_input[len] == '\n' )/* if there's a new line before '\0' */
        {
             user_input[len] = '\0'; /* eliminate the '\n' */
        }
    Because of dwks samples! Blame dwks, not me!
    So I changed it to remove a single newline instead.

    Quote Originally Posted by dwks View Post
    I like assigning the return value of strlen() to variables of type size_t, because that's strictly what it should be -- although many people just use ints. size_t is unsigned, so assigning it to an int gives you some warnings when you enable them. In addition, with REALLY long strings, an int might not have enough range.
    You're right. I don't really remember what all these functions return, so I just check compiler warnings about truncating and change variable type appropriately. Anyway, it's size_t now.

    "Truncate"? Not exactly. More like, "assigning NULL to a pointer makes the pointer point at nothing". Also consider linking to http://faq.cprogramming.com/cgi-bin/...&id=1043284376
    Bad wording, perhaps? I changed the explanation a little - so maybe it's better this time?

    Code:
    buffer[5] = '\0'; /* Buffer will not be "Hello" */
    You mean "now", right?

    I'm telling you, we need a Wiki FAQ . . . .
    I do! Mistake!
    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.

  6. #21
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Elysia:

    "And where is why!" ??

    How can where be why? And just where is "why", anyway?

  7. #22
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Because why is a place
    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.

  8. #23
    Registered User
    Join Date
    Dec 2007
    Posts
    9

    Thumbs up Thanks Guys!!!

    Man this forum rocks ;-).....
    You guys really went through a whole lot of trouble to write all the info for me....

    Thanks it will really come in handy

    Bye the way how long will this thread be here for.... Cause if it isn't here for a long time I will copy the info into a doc or txt :-D... cause there are some really handy tips here.

  9. #24
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    It will eventually be pushed down by the flood of all other threads.
    Yes, we wrote that so you (and all other newbies making the same mistake!) can understand the dangers of doing 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.

  10. #25
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Bye the way how long will this thread be here for.... Cause if it isn't here for a long time I will copy the info into a doc or txt :-D... cause there are some really handy tips here.
    OOOO dont worry about it, it should be here for quite a long time, may be morer than you expect, unless mod deletes this thread.

    ssharish

  11. #26
    Registered User
    Join Date
    Feb 2008
    Location
    Bangalore, India
    Posts
    16

    Thumbs up Thanks

    [QUOTE=Elysia;699337]
    --- Dangers of scanf and fscanf ---


    Thanks Eltsia .. It is great topic for Beginners as well as for Experts .. because we often think it is a easy one to print something on screen or scan some data but I think it is most important thing that what is going behind that small thing. So again Thanks .. and please give some other valuable Tips like this

  12. #27
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    You're not supposed to bump threads older than two weeks.

    @Elysia: now that there really is a Wiki FAQ, why not make this into a page for it?
    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.

  13. #28
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Indeed. I dunno where my draft I had stored somewhere disappeared to, however.
    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.

  14. #29
    uint64_t...think positive xuftugulus's Avatar
    Join Date
    Feb 2008
    Location
    Pacem
    Posts
    355
    If only we could destroy all the C-book parts that introduce scanf() to the C-student...
    It actually is more straightforward to use the other input functions.
    Code:
    ...
        goto johny_walker_red_label;
    johny_walker_blue_label: exit(-149$);
    johny_walker_red_label : exit( -22$);
    A typical example of ...cheap programming practices.

  15. #30
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    And also typically more error prone, sadly.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Formatting the contents of a text file
    By dagorsul in forum C++ Programming
    Replies: 2
    Last Post: 04-29-2008, 12:36 PM
  2. Basic text file encoder
    By Abda92 in forum C Programming
    Replies: 15
    Last Post: 05-22-2007, 01:19 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Replies: 3
    Last Post: 03-04-2005, 02:46 PM
  5. System
    By drdroid in forum C++ Programming
    Replies: 3
    Last Post: 06-28-2002, 10:12 PM