Thread: Accessing next entry in a queue.

  1. #61
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    I just went over the instructions and found out that I was not expected to handle a situation in which the user enters more than 100 chars (i.e. "cleaning" those supplementary chars from the buffer), but I am expected to ascertain that the string which is moved to the struct does not exceed 100 chars. Does that mean that I should simply limit the string itself to [100], or does that also entail a slightly different format of scanf() (for instance, something like "%s100", if such syntax even exists; if not, a variation thereof then)? I'd appreciate some advice.

  2. #62
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    the syntax is %100s or %100[^\n] if you want to include spaces

    buffer should be buf[101]

    and you still need to "flush" the rest of the input string that failed to be read from stdin

    FAQ > Flush the input buffer - Cprogramming.com
    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

  3. #63
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    Would it serve me better in this case to use strncpy() and strncmp() (instead of strcmp() and strcpy()), in addition to scanf("%100s")? If so, what should I put as the third argument? Would it be 101 or strlen(str1)?

  4. #64
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    No
    you need to use strncmp when you are not sure whether there is a null-terminator in the buffer.
    scanf always puts the nul-terminator while reading strings.

    strncpy would be useful if your temp buffer be bigger than the destination - this is also not your case.
    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

  5. #65
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    Instead of using scanf("%100s"), would it be safer then to read a char (perhaps via getch()) in a loop iterating to 100? Would that be a better way to approach this vis-a-vis the reuirement of assuring that the user did not enter more than one hundred chars?
    For the sake of clarity, the requirement reads thus (verbatim):
    "when reading a driver's name, you are asked to make sure the specific string will not exceed 100 chars. You are not expected to handle a case where the user entered more than 100 chars (for example, by cleaning the remaining chars from the buffer)".

  6. #66
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    If I'm understanding correctly, the requirements basically say "the string for the drivers name will be up to, but not exceeding, 100 chars". That means your string should be of size 101 (100 + 1 for the null terminator), but you don't need to worry about somebody typing 101 chars, so you don't really need length limits on your read functions, however they are a good idea anyway, and wont hurt in this case.

    You should learn to look up and read the full documentation for the standard functions, it will answer many of the questions you have posted in this thread, including whether scanf would assure user didn't exceed 100 chars. Here's a link: scanf(3): input format conversion - Linux man page. Read the part about maximum field width. It should answer your question about the 100 in scanf("%100s"). Note, if you read about the %s modifier, you will notice it stops on white space. That means reading a name like "Jon Doe" will not work, it will only scan "Jon". Hence the recommendation of %100[^\n] by vart in post #62.

    Your idea of a getch loop would work, but it is pointless, it would provide basically the same functionality as scanf("%100[^\n]"), but with more opportunities for bugs. It certainly wouldn't be any safer, possibly less so if you introduced a bug (e.g. potential buffer overflow).

  7. #67
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    Hi,
    I have one final question concerning my program. How should I free my main struct TaxiSystem at the end of the program? It was initialized thus:
    Code:
    TaxiSystem* initSystem(void){
        TaxiSystem *new_node = NULL;
        new_node = (TaxiSystem*) malloc(sizeof(TaxiSystem));
        if (!new_node){
            printf("Fatal error: memory allocation failed!\n");
            return NULL;
        }
        new_node->numOrder = 0;
        new_node->driversQueue = NULL;
        new_node->ordersQueue = NULL;
        return (new_node);
    }
    And main() also called some other functions to create new orders and new drivers in their respective queues using malloc().
    I was wondering whether simply doing:
    Code:
    free(sysptr)
    /*where sysptr is defined thus TaxiSystem *sysptr = initSystem();*/
    could suffice? The program runs smoothly and never gives any error messages nor gets stuck. Yet I wasn't sure whether freeing TaxiSystem this way would be enough or whether I also had to iterate over the inner structs too etc.?
    I'd truly appreciate some advice.
    Last edited by peripatein; 06-17-2013 at 03:33 AM.

  8. #68
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    Quote Originally Posted by peripatein View Post
    Yet I wasn't sure whether freeing TaxiSystem this way would be enough or whether I also had to iterate over the inner structs too etc.?
    Yes - if you want to free all allocated memory - you need to iterate through all inner stuff. For each stored pointer received through malloc call you need to call free.
    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

  9. #69
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    Like that?:
    Code:
    	while (system->driversQueue){
    		free(system->driversQueue);
    		system->driversQueue = system->driversQueue->next;
    	}
    	while (system->ordersQueue){
    		free(system->ordersQueue);
    		system->ordersQueue = system->ordersQueue->next;
    	}
    	free(system);

  10. #70
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    I mean, would that be enough?

  11. #71
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    Well, I apologize for being impatient, but perhaps someone else would be willing to kindly answer whether the above code indeed frees the entirety of the struct as needed?

  12. #72
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by peripatein View Post
    Like that?
    You shouldn't use a pointer after freeing it. You'll need to use a temp pointer in your free loops to fix this.

  13. #73
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    My bad. I shall fix it and re-post shortly.

  14. #74
    Hurry Slowly vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,788
    This will not work

    you do not advance your system->driversQueue var...
    Code:
    while (system->driversQueue){
        void* temp = system->driversQueue->next;
        free(system->driversQueue);
        system->driversQueue = temp ;
    }
    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

  15. #75
    Registered User
    Join Date
    Apr 2013
    Posts
    122
    May you please confirm that this is what you meant I should do?:
    Code:
    void freeSystem(TaxiSystem* system){
    	TaxiSystem *tmpdrv = system->driversQueue;
    	TaxiSystem *tmpord = system->ordersQueue;
    	while (tmpdrv){
    		system->driversQueue = tmpdrv;
    		tmpdrv = tmpdrv->next;
    		free(system->driversQueue);
    	}
    	while (tmpord){
    		system->ordersQueue = tmpord;
    		tmpord = tmpord->next;
    		free(system->ordersQueue);
    	}
    	free(system);
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. (queue*)this)->queue::qput’ does not have class type
    By brack in forum C++ Programming
    Replies: 13
    Last Post: 11-11-2010, 03:41 PM
  2. DNS entry changes
    By Thantos in forum Tech Board
    Replies: 4
    Last Post: 09-02-2003, 08:57 PM
  3. Min, Max field entry?
    By JCCC in forum C Programming
    Replies: 1
    Last Post: 04-16-2002, 07:46 PM
  4. Registry entry from AIM help!
    By SyntaxBubble in forum Windows Programming
    Replies: 3
    Last Post: 01-02-2002, 05:00 PM
  5. Queue and Priority Queue
    By Pamela in forum C++ Programming
    Replies: 1
    Last Post: 12-07-2001, 11:09 PM