[–] 2 points 2 months ago (1 child)

Most linux distributions either include C man pages by default or add them in when you install dev tools. I’d be surprised if man strchr didn’t already come up with something for you.

If you’re going down this path, it’s worth recognizing the different meanings of the man sections - shell commands in section 1 means that e.g. man chown is going to show you shell instead of the C function you’ll see from man 2 chown. In the same vein, section 3 has library functions, which are sometimes more relevant for you than section 2’s syscalls.

  • source
  • parent
  • context
  • [–] 2 points 2 months ago (1 child)

    Before trying to learn and use the standard library, I'd advise you to write a few simple functions yourself:

    1. void print_until(const char* str, char c) - print every character in str until you see c or null (Note: Don't print the c or null, which should ensure that a str that only contains a \0 doesn't crash.)
    2. const char* print_until_2(const char* str, char c) - as before, but return the pointer to where you found c or null
    3. void print_delimited_by(const char* str, char delimiter, char separator) - use print_until_2 in a while-loop, don't print the delimiter, but do print a separator.

    For example, print_delimited_by("1;2;3",';',',') should print 1,2,3.

    Finally, void num_delimited_by(const char* str, char del) - like print_delimited_by, but add a number before every output, and use newline as the separator.

    These fundamental string exercises will give you a solid foundation for understanding oantby's explanations about the standard library. Note that no memory allocation is necessary.

  • source
  • [–] 2 points 2 months ago* (last edited 2 months ago) (5 children)

    the strtok issue is, per the man page, that strtok returns only “non empty” tokens with your given delimiters.

    Given only one delimiter, the strchr approach is likely what I'd use. understanding strchr (and the similar strstr) is a pretty useful thing to have anyway, so it’s a good time to learn it. strchr makes no modifications and isn’t aiming to make tokens for you. It is looking for the first instance of a given byte in a C string and, provided it found it, returning you a pointer to that byte. as such, if it returns you something other than NULL, you’ve got a pointer to a byte. assuming you’re fine with the function modifying the buffer, you can convert that byte to a nul byte (\0), then print buffer, then a new line. You then advance your buffer pointer to the byte past the now-nul byte. Continue until strchr returns NULL, which is your last line - assuming the buffer is nul-terminated

    Edit: example, now that I've got a real keyboard:

    void strchr_loop(char *buf) {
        char* p;
        while ((p = strchr(buf, '\n')) != NULL) {
            *p = '\0';
            printf("Line = %s\n", buf);
            buf = p + 1;
        }
        printf("Last line = %s\n", buf);
    }
    
  • source
  • [–] 4 points 2 months ago (2 children)

    Any chance you are running this on an OS with a "new line" character that isn't "\n"? Windows for example could be "\r\n". I tried on Linux and it worked, although I only grabbed the necessary parts, so if something else is breaking, I can't say. Or perhaps I misunderstood the issue altogether. Here is what I see:

    The function:

    # code block
    int print_file(char* buffer) {
    	printf("print_file\n");
    
    	int line_num = 1;
    
    	char* line = strtok(buffer, "\n");
    
    	while(line != NULL) {
    		printf("%4d\t%s\n", line_num, line);
    		line = strtok(NULL, "\n");
    		line_num++;
    	}
    	return 0;	
    }
    

    And the output:

    # code block
    test file: test.txt 
    hello 123 123 123 
    asdf asdf asdf 
    0oijf0w0j s0w0wfjwef 
    0wefjfjwefjkwejijiowefjo
    
    output:
       1	hello 123 123 123 
       2	asdf asdf asdf 
       3	0oijf0w0j s0w0wfjwef 
       4	0wefjfjwefjkwejijiowefjo
    count: 4 lines | 0 words | 82 characters
    
  • source
  • [–] 11 points 2 months ago

    A substantial portion of the initial manuscript was generated using artificial intelligence. The author provided the underlying concept and creative direction and worked extensively with AI throughout the development of the book, selecting, restructuring, editing, rewriting, and refining the material. The final book reflects the author's editorial and creative decisions.

    Urgh. If you can't be bother to write it, I can't be bothered to read it.

  • source
  • [–] 1 point 3 months ago

    I can see this. Im not a dev but when scripting I often would mention I like to make something simple shell script if I did not need anything more because it would run fine on pretty much any system. I only went to a higher level shells when I need capabilities that simple shell did not have.

  • source
  • parent
  • context
  • [–] [S] 1 point 3 months ago

    I can see that, personally i dislike using C++, as it has so many different ways to solve the same problem, confining a project to use a specific subset of C++ is very difficult.

    Though mostly what i would like to be closer to other languages, is what is mostly standard across everything, like tuples, so i wouldn't have to do:

    Err fallible(Arg argument, Out* output) { ... }
    

    But at least attributes allow me to warn if the error in this case is unused.

    Thing is, C can compile to anything, so i wonder if Zig/Rust can really be a drop in replacement in most use cases.

  • source
  • parent
  • context
  • [–] 1 point 3 months ago (2 children)

    At least since C99, I've seen a trend where ISO tends to bring in unnecessary C++ features in. In fact, the current boss of WG14 quite explicitly calls for bridging gaps, modernising capabilities, and bringing select features (like constexpr object definitions and ergonomics) closer to what developers enjoy in C++, while "balancing C's unique philosophy and design constraints". I don't suppose it sat well with most C developers who feel C++ has evolved into a language of its own and that we shouldn't try to bridge gaps that don't exist. And consequently, the very fear of "dead on arrival" features have already crept in. Off the top of my mind, VLA is one such example. Appeared in C99 and is now a deprecated feature.

    That said, C89 is, for most parts enough to express that largest chunk of your codebase. But sure, you might need a little bit of size guaranteed integers, so you could borrow that from C99. What're you left with? The convenience of declaring variables midway? That's about as far as it goes. In very rare circumstances you might want to statically assert macros is global variables. Sure, pick C11 just for that task.

    If I really need some awesome syntax sugars, I'd rather use one of those modern languages like Zig, Rust and what nots..

  • source
  • [–] [S] 1 point 3 months ago

    I don't know if I'd assume the same about them, as the way the argument was worded made it seem the new features aren't a positive, or are broken in some way, or at least gave the appearance of the actual reason being technical and not skill.

    I was originally thinking of the use case for C is when you need to have something in a closed ecosystem, as in no dependencies, so generics made sense as an example, and while I'm aware one can use rust, it usually enables (and in a sense encourages) pulling in many dependencies, which is not always desirable.

  • source
  • parent
  • context
  • [–] 6 points 3 months ago (1 child)

    Later versions than C99 have no real added value proposition for the real use-cases where C is actually desired as an implementation language.

    Later versions than C99 continue to introduce C++isms among other shit, from committee members some of whom probably never coded anything serious in C. This actually sometimes trickles down to compiler implementations even when you're sticking with an older version. So they manage to anger you even when you're keeping a distance.

    Despite street myths and stereotypes, most people who choose C for some projects are not grey-hairs stuck in the past and incapable of learning new tools. Many of them in fact do use newer languages like Rust where they see fit. So there is no pressure to pick the one or two features from newer C versions that are maybe possibly can be useful.

    Still, for some big projects that are kind of half-stuck with millions of lines of C, while at the same time having immense pressure to deliver maximum reliability AND security, these newer versions could proof useful at times. But the only project that comes to mind that fits this mold is the Linux kernel really. And there, non-standard language extensions are getting used anyway, so it's kind of an exceptional situation, that is also not very portable, but that's not a concern by the very nature of where a kernel sets in the stack.

  • source
  • [–] 8 points 3 months ago

    It works. You have hammers and nails. Then, someday, a dude come with the new Hammer23, with better ergonomical grip, colored high density 3 sided head, and so on. Yeah, cool, but I still have the same nails to nail, and my current hammer do the job perfectly. And I drilled a hole in my workbench ten year ago that have the perfect size for my current hammer.

  • source
  • [–] 0 points 3 months ago (1 child)

    They haven't bothered to update their knowledge about it. And why should they? They got gud with C89 and can write software that works with it. So since they don't know how to, when they use the modern stuff they break things; they haven't learnt the footguns yet. The same way a n00b would write broken software with any version of C. That feels bad so they reject it. It's like how everyone thinks the music from when they were a teenager is the best music. Starting learning from nothing it's probably better to learn the new stuff too, but if you're maintaining software written with one version it's probably not worth updating it and so you'll need to just work with what there is.

    Although if you really need generics and other more advanced language features and you're starting a new project from scratch it might be better to go with something like rust at this point.

  • source
  • [–] 2 points 4 months ago (1 child)

    We told you to merge all your repositories. You didn’t do it, and now you have a special repository for the releases? That’s ridiculous. You should do it ASAP if you want to be taken seriously. ONE repository called D.eSystem, that’s all.

  • source
  • [–] [S] 1 point 4 months ago (1 child)

    Sic!!! Thank you so much! I'll try this as soon as my new Gentoo system is up and running! Just to have another excuse for me to set it up already. 🤣

    Is it gcc or the OS that determines what encodings I can pass as an option to the compiler?

  • source
  • parent
  • context
  • [–] 2 points 4 months ago* (2 children)

    You can actually change this.

    The compiler has an 'execution' character set that describes how characters should be interpreted at run time, and a 'source' character set, and they need not be the same.

    Check this out

    $ cat test_ebdic.c ; gcc -fexec-charset=EBCDIC-US test_ebdic.c ; ./a.out | xxd
    #include <stdlib.h>
    #include <stdio.h>
    int main(void)
    {
            char data[] = "Hello";
            printf("%s\n", data);
            return EXIT_SUCCESS;
    }
    00000000: c885 9393 960a                           ......
    

    The file was typed in UTF-8, and the compiler automatically translated the literal to EBCDIC-US to emit at run time. My terminal can't display this, so I view it with a hex editor.

  • source
  • view more: ‹ prev next ›