Best way to convert

Discussion in 'Mac Programming' started by Miglu, Oct 19, 2010.

  1. macrumors member

    Joined:
    Jan 22, 2010
    #1
    What is the best way to convert tv_sec, which is of type time_t, into a C string? There is no formatter for it in sprintf. I tried to use strftime(s, 5, "%S", tp->tv_sec) but got "warning: passing argument 4 of 'strftime' makes pointer from integer without a cast".
     
  2. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    It's likely that time_t is going to end up being an int of some variety. Are you trying to just display the number of seconds that it holds, or do you want a nicely formatted date that this value represents (i.e. second since epoch -> date and time represented)?

    strftime's 4th argument is of type struct tm *. Passing in an int to this parameter is not going to go well. What type is tp? Is it a struct tm *? If so, you can pass that to strftime.

    -Lee
     
  3. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #3
    I just want the number of seconds.
    tp is of type struct timespec.
    What is the best way to convert time_t to a string?
     
  4. macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #4
    Well, if you're concerned about maximum cross-platform compatibilty, you'll have to do your own research, but time_t is (always? -- check C++ spec for that) an integer time of some size. So your probably safe casting it to a long long int and using the appropriate printf format specifier for that. E.g.,

    Code:
    // where t is of type time_t
    printf("t is: %lld\n", (long long) t);
    
     
  5. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #5
    I am using Objective-C, not C++. I did snprintf(string, 4, "t is: %lld\n", (long long)tp->tv_sec), but got EXC_BAD_ACCESS. What is the problem?
     
  6. macrumors 603

    Joined:
    Aug 9, 2009
    #6
    Post complete code.

    What is the type of string? Show the actual declaration you have in your code.

    Specifying a length of 4 is clearly wrong, because the "t is: " part is longer than 4.

    Did you look at the reference doc for snprintf()? Do you understand what every one of the parameters means?


    Since you're using Objective-C, have you looked at the init methods of NSString? For example, the ones that take a format-string?
     
  7. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #7
    Whatever I cast tp->tv_sec to, I get EXC_BAD_ACCESS. What is the problem?
     
  8. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #8
    Give us code we can compile that crashes. We have no idea what's wrong right now.

    -Lee
     
  9. macrumors 68040

    iSee

    Joined:
    Oct 25, 2004
    #9
    I believe my suggestion should work for C and Objective-C, too.
    As was mentioned,

    snprintf(string, 4, "t is: %lld\n", (long long)tp->tv_sec)

    is wrong because of the 4.
    Also check that string is a character buffer of sufficient size to hold the result.
    Also, ensure tp is correctly initialized and isn't null. You could use the debugger to help with that.
     
  10. macrumors 68000

    Sydde

    Joined:
    Aug 17, 2009
    #10
    Is tp a struct or a pointer to a struct?
     
  11. macrumors 68040

    Joined:
    Feb 2, 2008
    #11
    Your just suppose to pass *tp not tp->tv_sec.

     
  12. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #12
    I understand snprintf's arguments. Whatever the second argument is, I get EXC_BAD_ACCESS.

    Code:
    //This is in the header
    struct timespec *tpc; 
    
    //This is in the implementation
    - (void) mach_absolute_differenceEnd: (uint64_t) end Start: (uint64_t) start {  
    
    		uint64_t difference = end - start;  
    		static mach_timebase_info_data_t info = {0,0};  
    
    		if (info.denom == 0)  
    				mach_timebase_info(&info);  
    
    		uint64_t elapsednano = difference * (info.numer / info.denom);  
    
    		tpc->tv_sec = elapsednano * 1e-9;
    		tpc->tv_nsec = elapsednano - (tpc->tv_sec * 1e9);
    }
    
    //This is in a method in the implementation 
    char *string;
    snprintf(string, 4, "t is: %lld\n", (long long)tpc->tv_sec);
     
  13. macrumors 68040

    Joined:
    Feb 2, 2008
    #13
    Yeah, but if you got room in string and use the correct format specifier you can convert a time_t variable with snprintf.

    Code:
    #include <time.h>
    #include <stdio.h>
    
    int main()
    {
            time_t t = 123;
            size_t bufsize = 128;
            char buf[bufsize];
    
            snprintf(buf, bufsize, "%lu", t);
            puts(buf);
    
    
            return 0;
    }
    
    
     
  14. macrumors 68040

    Joined:
    Feb 2, 2008
    #14
    You can't just write 4 bytes to nowhere, you need to use malloc/calloc, or set aside some memory on the stack using an array declaration.
     
  15. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #15
    I think the real lesson here is:
    Not posting code == 16 hours with people guessing at your problem
    Posting code == Answer with exactly what's wrong in about 20 minutes

    It would have been even faster if you could have given something to compile like:
    Code:
    #include <stdio.h>
    #include <time.h>
    #include <stdlib.h>
    
    int main(int argc, char *argv[]) {
    	struct timespec *tpc;
    	char *string;
    	tpc = calloc(1,sizeof(struct timespec));
    	tpc->tv_sec = 234;
    
    	snprintf(string,4,"t is: %lld\n",(long long)tpc->tv_sec);
    	return 0;
    }
    
    The 4 would still be wrong, but we'd been able to see right away what was going on.

    -Lee
     
  16. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #16
    Yeah but if he had made the above code he might have figured it out on his own, and where is the fun in that?

    EDIT:
    Every time I'm having a problem with some kind of weird crash or memory leak **, before setting up a new thread about the problem I made a super simple test case to try to narrow down the problem.

    ** (my latest one came from the fact that in iOS sends (applicationWillResignActive:) both when locking and when multi-task switching out of an app, but only sends (applicationWillEnterForeground:) when coming back from multi-tasking and NOT from locking causing a seemingly very random crash with the ridiculous code I have setup for iAds to not be showing when there are no ads to display)
     
  17. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #17
    Thanks. Now I am going to ask an offtopic question but it is not significant enough to deserve its own thread:
    Code:
    	char string[100];
    	fscanf(fp, "%s", string);
    	printf("%s", string);
    I am trying to get a list of 7-digit floats separated by ; from the file that is pointed to by fp. However, only the first one and the ; after it is printed. What is the problem?
     
  18. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #18
    We can't compile that code, but it's a start. Post a copy of the data file you're using. I tried the code below with the data file below and it worked fine (read the whole line).

    Code:
    #include <stdio.h>
    
    int main(int argc, char *argv[]) {
    	char string[100];
    	FILE * fp;
    	fp = fopen("floats.txt","r");
    	fscanf(fp, "%s", string);
    	printf("%s\n", string);
    }
    
    floats.txt
    -Lee
     
  19. thread starter macrumors member

    Joined:
    Jan 22, 2010
  20. macrumors 603

    Joined:
    Aug 9, 2009
    #20
    Read fscanf's man page. fscanf's %s stops at whitespace.

    Your data has whitespace after the semicolon and before the next number.

    So fscanf works correctly. The problem is you don't fully understand how it works.
     
  21. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #21
    From the fscanf manpage:
    Code:
         s     Matches a sequence of non-white-space characters; the next pointer must be a pointer to char, and the array must be
               large enough to accept all the sequence and the terminating NUL character.  The input string stops at white space or at
               the maximum field width, whichever occurs first.
    
               If an l qualifier is present, the next pointer must be a pointer to wchar_t, into which the input will be placed after
               conversion by mbrtowc(3).
    
    So why might it have stopped at the first space?

    -Lee
     
  22. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #22
    How to get the strings after the whitespaces?
     
  23. macrumors 68030

    jared_kipe

    Joined:
    Dec 8, 2003
    Location:
    Seattle
    #23
    *spits coffee out of mouth*

    Seriously? You do it again. You keep calling fscanf over and over until fscanf gets exhausted and refuses to work for you anymore.
     
  24. thread starter macrumors member

    Joined:
    Jan 22, 2010
    #24
    Now I have ; stuck to every string. What is the best way to get it off? I tried string = strsep(&string, ";"), but I get "Incompatible types in assignment".
     
  25. macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #25
    That isn't compilable code. If you post compilable code we can help you. Chances are string is declared:
    Code:
    char string[100];
    Which is not assignment-compatible. In this case I don't see a need to do anything with the result of strsep, but you could assign it to a temporary char * if you needed to do some comparison.

    -Lee
     

Share This Page