program crashes + fscanf() question

This is a discussion on program crashes + fscanf() question within the C Programming forums, part of the General Programming Boards category; Hi all. I have a file with the string/line: 12/16/2008 10:21 AM 969 happyclown.html I am trying to write a ...

  1. #1
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391

    program crashes + fscanf() question

    Hi all.

    I have a file with the string/line:

    12/16/2008 10:21 AM 969 happyclown.html

    I am trying to write a program to read each of the data items in the string, then print them to the screen. The program compiles, but crashes. Here it is:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
        FILE *openfile;
    
        struct data {
            struct tm *MonthDayYear;
            struct tm *HourMinute;
            char *string1;
            int number;
            char *string2;
        } LineData;
    
        if((openfile = fopen( "directorylisting.txt", "rt" )) == NULL)
        {
            perror("Error opening file");
            exit(EXIT_FAILURE);
        }
    
        fscanf(openfile, "%D %R %s %d %s", &LineData.MonthDayYear, &LineData.HourMinute, LineData.string1,
                                            &LineData.number, LineData.string2);
    
        fclose(openfile);
    
        printf("%D %R %s %d %s", LineData.MonthDayYear, LineData.HourMinute, LineData.string1, LineData.number,
                                            LineData.string2);
    
        return 0;
    }
    1. Why does it crash? I'll admit that I've never done anything time related, so that may be the problem. I might have gotten the identifiers wrong, or the types wrong?

    2. Is there a similar function to fscanf(), where a person can specify what data item in the string to scan? Say I only wanted to scan the last data item(happyclown.html), without have to scan the rest? I hope to eventually write a program that will scan hundreds of thousands of lines(strings), but only scan one specific data item from each string. It seems awfully inefficient(and memory intensive) to have to scan everything else in the string too.

    Thanks.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  2. #2
    and the hat of wrongness Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    32,484
    Perhaps it's all the memory that your pointers are NOT pointing to.
    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.
    I support http://www.ukip.org/ as the first necessary step to a free Europe.

  3. #3
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,537
    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.

  4. #4
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks for the replies. They have really pointed(no pun intended) me in the right direction.
    OS: Linux Mint 13(Maya) LTS 64 bit.

  5. #5
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Quote Originally Posted by happyclown View Post

    struct data {
    struct tm *MonthDayYear;
    struct tm *HourMinute;
    char *string1;
    int number;
    char *string2;
    } LineData;
    Is it better to allocate memory to the entire structure, or just to the pointers in the structure? I know pointers need memory allocated, but is there anything wrong with allocating memory to the entire stucture? There is a clear difference in the amount of time that can be saved.

    Code:
    struct data *PointerToData;
    
    PointerToData = malloc(1 * sizeof(struct data));
    OR

    Code:
    #definen FILENAMELENGTH 40
    
      struct data {
            struct tm *MonthDayYear;
            struct tm *HourMinute;
            char *string1;
            int number;
            char *string2;
        } LineData;
    
    LineData.MonthDayYear = malloc(1 * sizeof(struct tm));
    LineData.HourMinute = malloc(1 * sizeof(struct tm));
    LineData.string1 = malloc(FILENAMELENGTH * sizeof(char));
    LineData.string2 = malloc(FILENAMELENGTH * sizeof(char));
    OR

    Code:
    #definen FILENAMELENGTH 40
    
      struct data {
            struct tm *MonthDayYear = malloc(1 * sizeof(struct tm));
            struct tm *HourMinute = malloc(1 * sizeof(struct tm));
            char *string1 = malloc(FILENAMELENGTH * sizeof(char));
            int number;
            char *string2 = malloc(FILENAMELENGTH * sizeof(char));;
        } LineData;
    Thanks.
    Last edited by happyclown; 01-11-2009 at 06:50 PM. Reason: added content
    OS: Linux Mint 13(Maya) LTS 64 bit.

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by happyclown View Post
    Is it better to allocate memory to the entire structure, or just to the pointers in the structure?
    In this case you will might have to do both. The sizeof(struct data) is the sum of it's parts -- in this case they are almost all pointers (a pointer, with no memory allocated to the location it points to, occupies 4 or 8 bytes that holds the address of the memory it points to -- if unallocated, this is just a garbage value). How could you possibly believe that malloc(sizeof(struct data)) could ever inuit malloc(FILENAMELENGTH * sizeof(char))?

    On the other hand, you could do neither. If you declare such a struct:
    Code:
    struct data LineData;
    You don't have to allocate it memory because it's not a pointer. If you want to pass it as a pointer, use &LineData. There is also no reason to be using pointers to struct tm's in the prototype, since they are always the same size just declare them:
    Code:
    struct tm HourMinute;
    You might be able to take care of some of the other variables and not have to use malloc at all.
    Last edited by MK27; 01-11-2009 at 07:05 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185

    Is it better to allocate memory to the entire structure, or just to the pointers in the structure?
    This is not an either-or thing. You allocate memory for (not to, for) the entire structure if and only if you are creating an unknown number of them dynamically. If you just declare a variable as in
    Code:
    struct data bob;
    then there is no need for memory.

    You make sure the pointers inside a struct point to valid memory regardless of how the struct is created; which is either going to come from malloc or something similar in this example. (Now you won't always need to explicitly do this -- for example, in a linked list, the pointers inside the structs are going to point to already-existing objects, so you don't need to create any extra memory because the valid memory is already there.)

  8. #8
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by tabstop View Post
    (Now you won't always need to explicitly do this -- for example, in a linked list, the pointers inside the structs are going to point to already-existing objects, so you don't need to create any extra memory because the valid memory is already there.)
    This MIGHT apply to the struct tm's as well (I don't know how you are using them) -- some functions return a pointer to memory that is allocated so you don't have to and ususually you shouldn't free it either. In that case they should just be pointers.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by MK27 View Post
    This MIGHT apply to the struct tm's as well (I don't know how you are using them) -- some functions return a pointer to memory that is allocated so you don't have to and ususually you shouldn't free it either. In that case they should just be pointers.
    That's my selective reading at work; I can think of no circumstances where "struct time *" is appropriate and many many circumstances where "struct time" is appropriate, so I just read it as the latter.

    And also, do you really expect %D inside a fscanf to read in a time? Why? (Edit: This question is intended at OP, of course.)
    Last edited by tabstop; 01-11-2009 at 07:25 PM.

  10. #10
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Well, localtime and getdate I think return struct tm pointers that don't need allocating. I guess I kind of jumped the gun in my previous post.

    I think the OP (happyclown) has misunderstood the nature of struct tm also, as one struct tm contains the minute, the hour, the second, the day, the month, etc. They are all int members, so maybe we should have a:
    Code:
    &LineData.MonthDayYear.tm_mday
    in that printf statement.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  11. #11
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    Thanks for very helpful replies.

    Quote Originally Posted by MK27 View Post
    How could you possibly believe that malloc(sizeof(struct data)) could ever inuit malloc(FILENAMELENGTH * sizeof(char))?
    Because I am a newbie. I've don't know what inuit means, so I don't understand the question. Never fear, I will google it up.

    Quote Originally Posted by tabstop View Post

    And also, do you really expect %D inside a fscanf to read in a time? Why?
    Because I am a newbie. I've had zero exposure (edit: well, not really zero, but minimal, because my C book dedicates only a single page) to time related stuff, including conversion specifiers. What can I use instead of %D to put into fscanf() to read the time in month-day-year format?

    EDIT: I got %D from a table of what conversion specifiers that can be used with strftime(), in my C book. And according to the table, %D "is equivalent to "%m/%d/%y". The book doesn't have anything other conversion specifiers that I can use in that format.

    And another question:

    Is it possible to declare and allocate memory to a pointer at the same time?

    Code:
    char *string2 = malloc(FILENAMELENGTH * sizeof(char));
    I saw something similar in another thread(and I used it in post #5 in this thread without really knowing if it was correct), but since no one made a comment, I thought I'd confirm. I had always thought this was the only way:

    Code:
    char *string2;
    
    string2 = malloc(FILENAMELENGTH * sizeof(char));
    Thanks.
    Last edited by happyclown; 01-12-2009 at 03:25 PM. Reason: added more content
    OS: Linux Mint 13(Maya) LTS 64 bit.

  12. #12
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by happyclown View Post
    I've don't know what inuit means
    Clue: it's tall and loves ftish more than you
    Quote Originally Posted by happyclown View Post
    What can I use instead of %D to put into fscanf() to read the time in month-day-year format?
    This is part of your "misunderstanding struct tm" problem. A struct tm looks like this:
    Code:
    struct tm {
            int tm_sec;
            int tm_min;
            int tm_hour;
            int tm_mday;
            int tm_mon;
            int tm_year;
            int tm_wday;
            int tm_yday;
            int tm_isdst;
            long int tm_gmtoff;
            const char *tm_zone;
    };
    As you can see, one such struct stores a lot of information. You should be able to find an explanation somewhere in your C library documentation. (If you missed it and you are using GNU, that's no surprise because this part of the manual is totally atrocious, perhaps mirroring the functionality of C time functions) Anyway, it's defined (more or less as above) in "time.h" which you must include in order to use it.

    For example:
    Code:
    #include <stdio.h>
    #include <time.h>
    
    int main () {
    	time_t TIME=time(NULL);  // a time_t is just a long number
    	struct tm *ptr=localtime(&TIME);   // "translate" that number 
    	printf("The date is %d/%d/%02d\n"
    		"The time is %d:%d:%d\n",
    		ptr->tm_mon+1,ptr->tm_mday,ptr->tm_year-100,
    		ptr->tm_hour,ptr->tm_min,ptr->tm_sec);
    }
    Look! All that and only one struct!

    Quote Originally Posted by happyclown View Post
    Is it possible to declare and allocate memory to a pointer at the same time?

    Code:
    char *string2 = malloc(FILENAMELENGTH * sizeof(char));
    Yes.
    Last edited by MK27; 01-12-2009 at 03:57 PM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Regarding "when do I allocate and when don't I", I would say that memory for smaller data items, less than several dozen bytes is best as a direct variable (e.g. an array of char or the type itself - and it doesn't matter if this is inside a struct or as a local variable in a function). Even struct tm is a small in this sense. In most cases, it's probably not worth allocating memory until we have several hundred bytes.

    Obviously, there are situations where allocation of small data objects is necessary: Linked lists and other types of "dynamically sized storage" - but for essentially any of the examples given above, there is no need to allocate memory inside the struct - even a filename in this case is probably fine to have a fixed size limit to it.

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

  14. #14
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by happyclown View Post
    Thanks for very helpful replies.



    Because I am a newbie. I've don't know what inuit means, so I don't understand the question. Never fear, I will google it up.


    Because I am a newbie. I've had zero exposure (edit: well, not really zero, but minimal, because my C book dedicates only a single page) to time related stuff, including conversion specifiers. What can I use instead of %D to put into fscanf() to read the time in month-day-year format?
    What makes you think you can? Read in an int, a slash, an int, a slash, and an int. Save what is appropriate to the appropriate places.
    Quote Originally Posted by happyclown View Post
    EDIT: I got %D from a table of what conversion specifiers that can be used with strftime(), in my C book. And according to the table, %D "is equivalent to "%m/%d/%y". The book doesn't have anything other conversion specifiers that I can use in that format.
    And do you call strftime? No? So why does it matter?
    Quote Originally Posted by happyclown View Post
    And another question:

    Is it possible to declare and allocate memory to a pointer at the same time?

    Code:
    char *string2 = malloc(FILENAMELENGTH * sizeof(char));
    Of course.

  15. #15
    In my head happyclown's Avatar
    Join Date
    Dec 2008
    Location
    In my head
    Posts
    391
    I am still having a bugger of a time with this.

    Here's my code so far:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    
    int main(void)
    {
        FILE *openfile;
    
        struct data {
            int month;
            int day;
            int year;
            int hour;
            int minute;
            char *string1 = malloc( 10 * sizeof(char));   <=========== (15) =====
            int number;
            char *string2 = malloc( 10 * sizeof(char));
        } LineData;  <========== (18) =====
    
        if((openfile = fopen( "directorylisting.txt", "rt" )) == NULL) <============ (20) ====
        {
            perror("Error opening file");
            exit(EXIT_FAILURE);
        }
    
        fscanf(openfile, "%d/%d/%d %d:%d %s %d %s", &LineData.month, 
    &LineData.day, &LineData.year, &LineData.hour, &LineData.minute,
    LineData.string1, &LineData.number, LineData.string2);
    
        fclose(openfile);
    
        printf("%d/%d/%d %d:%d %s %d %s", LineData.month, 
    LineData.day, LineData.year, LineData.hour, LineData.minute,
    *LineData.string1, LineData.number, *LineData.string2);
    
        return 0;
    }
    And here are the compiler error messages:

    (15) warning: no semicolon at end of struct or union

    (15) parse error before `='

    (18) warning: data definition has no type or storage class

    (20) parse error before `if'

    I don' t have a problem reading the dates and times, it's just the strings.

    I know malloc probably doesn't need to be used here, but I am just trying to get some experience with it.



    Thanks.
    Last edited by happyclown; 01-16-2009 at 05:19 AM. Reason: formatted code to fit the screen
    OS: Linux Mint 13(Maya) LTS 64 bit.

Page 1 of 2 12 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. BOOKKEEPING PROGRAM, need help!
    By yabud in forum C Programming
    Replies: 3
    Last Post: 11-16-2006, 10:17 PM
  2. Replies: 4
    Last Post: 06-23-2006, 07:03 PM
  3. DEV-C++ made program crashes when run from outside the ide
    By rainmanddw in forum C++ Programming
    Replies: 3
    Last Post: 01-20-2006, 09:27 PM
  4. Question about K&R program
    By Aerie in forum C Programming
    Replies: 15
    Last Post: 04-24-2005, 07:09 AM
  5. Question type program for beginners
    By Kirdra in forum C++ Programming
    Replies: 7
    Last Post: 09-15-2002, 05:10 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21