[โ€“] 1 point 5 months ago

Rust made the same mistake that C++ made, otherwise it might've been a viable option. Now instead debugging a memory issue for 3 days, I think a month on how to architect my software, just to scrap that 5 months later and rewrite it from scratch.

  • source
  • parent
  • context
  • [โ€“] 6 points 5 months ago* (1 child)

    I'm too lazy to confirm, but I think scanf (as well as many other I/O functions) works on top of the buffered input. I.e. when you scanned only one character on the first run of scanf but there are more left in the buffer, then subsequent calls will read from that buffer, e.g.

    printf("your prompt>")
    /* you type 123 */
    /* buffer contains: "123" */
    scanf(...)
    /* you scanned 1 char ("1") */
    /* buffer contains: "23" */
    printf("new prompt>");
    /* the prompt has been printed AFTER your previous input but the buffer hasn't been reset! */
    /* buffer contains: "23" */
    /* you type 456 */
    /* buffer contains: "23456" */
    scanf(...)
    /* scanf returns "2" */
    /* buffer contains: "3456" */
    

    In general you have two options:

    1. drain the buffer after / before each loop cycle
    2. use unbuffered I/O

    For both cases, do your research on how to do it :) That K&R from above should be a great start indeed.

  • source
  • [โ€“] 3 points 5 months ago (1 child)

    I'm going to avoid commenting on anything else in your code and just say that you should be using getline() to read a line of input from the user. Also note that yor extra call to getchar() is throwing away the user's first character of input after a command is executed.

  • source
  • [โ€“] 2 points 5 months ago

    If you moved the printfs back, you'd end up with 6 printfs, and you can just hardcode in the wasiswill value in the format string.

    As it happens, the strcpys are unnecessary anyway, you can just assign "will be" to a char pointer:

    char* williswas = "";
    if (year == 2026) {
        williswas = "is";
    }
    ...
    

    The strings are already in your read only memory, you just need a pointer to them.

    Making the GOTO targets unique makes a stronger argument for just dropping the gotos entirely, because the execution flow for each of the 6 cases is now getting intertwined. You may understand it today, but in 3 months time you'll hate reading it.

  • source
  • parent
  • context
  • [โ€“] [S] 2 points 5 months ago (1 child)

    Thank you very much for your input! ๐Ÿ˜ƒ How clumsy of me not to make the GOTO targets unique... Then I'll reverse the code to what I had initially written, namely, exactly what you said.

    Could you clarify what you mean by "save the strcpys"?

  • source
  • parent
  • context
  • [โ€“] [S] 2 points 5 months ago*

    Cool insight! Also, this reminds me, where I work, we have a piece of really old, probably early 2000's, software with which we book and document interviews with our clients (convicts on parole, infact). When I once accidentally tried to enter a future date as the date of an interview, it gave me an error message saying "you can only book interviews between 1753 and present day". After looking into it, I found that the Gregorian calendar, in my country, was officially adopted as late as 1753 because of religious opposition. I laughed so hard at this, still wondering if this was left there as an Easter egg by a developer or if it's using a library that behaves this way.

  • source
  • parent
  • context
  • [โ€“] 3 points 5 months ago (2 children)

    This is not a good way to use GOTO :(.

    For starters: Your GOTO targets aren't unique, NLEAP1 and NLEAP2 are the same, and LEAP and NLEAP3 are the same.

    I would probably just put the printfs where the gotos are and save the strcpys. Just make sure to return out after the printfs. Sometimes being verbose in your code is better than being clever with gotos.

    Your returns are returning the return value from the printfs.

    I.e: same as:

    int ret = printf(...);
    return ret;
    

    Printfs returns an int with the number of bytes it wrote out.

  • source
  • [โ€“] 3 points 5 months ago (1 child)

    I honestly kinda love date/time manipulation stuff while coding because it's very nature is reliant on exceptions and edge cases. While it can be annoying it is far from boring especially if your day to day is just managing ledgers or APIs. Even with my odd endeavor into date/time shenanigans though it's almost always better to use a library as the complexity will quickly grow out of scope.

  • source
  • parent
  • context
  • [โ€“] [S] 3 points 5 months ago (2 children)

    I don't think that you were off point at all by pointing out the factual errors by initializing at 0. I appreciate it as much as your advice on the code itself! This is just my lack of common sense and me sucking at math.

    Thank you very much for the input on how to tidy up the code! I'll give it a shot! ๐Ÿ˜Š

  • source
  • parent
  • context
  • [โ€“] 3 points 5 months ago (3 children)

    You can do the ordinal comparison once at the start instead of for both the positive and negative case. Then track a isLeap variable and just do one printf at the end with the combination of your different variables.

    Your code feels repetitive now because it is. You're comparing years multiple times and printing "[not?] a leap year" multiple times.

    The reason returning printf works is because the return type of printf is an int containing the count of characters printed.


    I recognize that this is besides the point, but It doesn't make a ton of sense to attribute a Gregorian interpretation to years before the adoption of the Gregorian system, and thus to truly be honest in the response different leap rules ought to be used for pre-Gregorian years. In any case this will also return the wrong result for 0 or negative years as there aren't negative years or a year 0.

  • source
  • [โ€“] 2 points 6 months ago* (2 children)

    Did you know that

    	int history[10] = {0,0,0,0,0,0,0,0,0,0};  
    

    is the same thing as

            int history[10] = {0};
    

    And an idom in C would be to define a constant for the size like this

    enum { HISTORY_MAX = 10};
    int history[HISTORY_MAX] = {0};
    int history_limit = HISTORY_MAX;
    
  • source
  • [โ€“] 2 points 6 months ago

    That's fair enough, and a good way to learn. Still, in this day and age with Claude etc, I respect the effort you're putting in.

    In the interests of proposing alternatives, you could also make the pin list a global variable. I'll let you work out why its a bad idea though :)

  • source
  • parent
  • context
  • [โ€“] [S] 2 points 6 months ago* (1 child)

    Thanks for the pointers. ๐Ÿ˜

    Oh, I just meant that I'm experimenting, evaluating and thinking instead of "just" searching for a straight answer on the world wide web.

    Edit: Also meaning, that when I post a question here, I have already writhen (spelling?) in pain for a few hours or a day without getting anywhere.

  • source
  • parent
  • context
  • view more: โ€น prev next โ€บ