r/C_Programming

I started learning C two weeks ago, and I'm feeling doubtful

Q12. Write a program that evaluates an expression:

Enter an expression: 1+2.5*3
Value of expression: 10.5

The operands in the expression are floating-point numbers; the operators are +, -, *, and /.
The expression is evaluated from left to right (no operator takes precedence over any other operator).

I'm totally new to programming and C is my first programming language. I've been following KN King's book-"C programming: A modern approach", and honestly, some projects are overwhelming for me. I'm almost done with chapter 7 and I struggle to do some questions. I terribly fail to do them. I think when questions involve nesting loops or nesting if, I don't feel comfortable with it. I was doing the above question, and tbh I've lost confidence in my progress and I'm feeling as if I didn't study deep enough, because I hear people say that this is a beginner book and I feel that it shouldn't be that tough. So I'm kinda doubtful about my progress, whether I'm unable to solve because of my incapability or the questions are genuinely troubling. I'd appreciate if you could advice me whether I should keep going or restart from a certain point.

reddit.com
u/Lelouch--Lamperouge — 1 hour ago

How to zero-initialise non-specified values in an array at compile time?

Imagine a situation where you need to define whether a given character is vowel by accessing alphabet represented as an array of booleans (or integers). Like:

int is_vowel(const char c) { return arr[c]; }

So, we demand an array arr where at all vowels indeces the value is set to 1 or non-zero:

static const char arr[] = {
    ['a'] = 1, ['o'] = 1, ['e'] = 1, ['y'] = 1, ['u'] = 1};

The problem now is that the other values that we did not specify may be undefined (or if they may not, please correct me). Is there a way to force compiler to zero-initialise other values?
Does static const modifier guarantees anything about its value per standard in this case?

Of course i could simply make the array mutable and initialise it during runtime, but i would prefer do it at compile time. Maybe there's an attribute, or a language feature i have no clue about; so I wish to find out the most elegant and proper way to accomplish that.

reddit.com
u/Interesting_Buy_3969 — 1 hour ago

Anyone looking for someone for a project?

I'm a decently skilled hobbyist programmer, specializing in C. I've got a non-programming day job, but I'm looking for something to flex my muscles. If anyone has a project they would like a little hand with, let me know. Big plus if it involves SDL.

reddit.com
u/CruelNoise — 9 hours ago

Having a *really* tough time understanding how to make/link my own libraries

Hello, I've been learning how to program my arduino bare-metal, and I've gotten to the point where I thought it'd be more convenient to start making my own library for interacting with some components. However, I've hit a roadblock at actually linking my library code to my project code.

My current library looks like this:

├── build
│   └── usb.o
├── etc
│   ├── lcd.h
│   ├── myavr.h
│   ├── rustypes.h
│   ├── shreg.h
│   └── spi.h
├── include
│   ├── usart.h
│   └── usb.h
├── lib
│   └── libusart.a
├── Makefile
└── USART
    └── usb.c

Where /etc/ is just a placeholder for some headers that need refactoring. The makefile of this library looks like this:

# Variables
CPU = atmega328p
F_CPU = 16000000UL
CC = avr-gcc
ar = avr-ar

# Flags
CFLAGS = -Os
CPUFLAGS = -DF_CPU=$(F_CPU) -mmcu=$(CPU)

# Makers
usart.a: USART/usb.c
  $(CC) $(CFLAGS) $(CPUFLAGS) -c USART/usb.c -o build/usb.o
  $(ar) rcs lib/libusart.a $(wildcard build/*.o)

clear:
  rm -r build/*
  rm -r lib/*

Furthermore, I have a symbolic link in ~/lib/libusart.a to the actual library in this directory, for convenience.

However, when I try to compile my project, I get the following error:

Creating build directory...
avr-gcc -Os -DF_CPU=16000000UL -mmcu=atmega328p -I~/Documents/Arduino/MyAvrLib/ -c src/main.c -o build/main.o
avr-gcc -DF_CPU=16000000UL -mmcu=atmega328p -L~/lib -lusart build/main.o -o build/main.bin
build/main.o: In function `main':
main.c:(.text.startup+0x1c): undefined reference to `USB_init'
main.c:(.text.startup+0x3e): undefined reference to `USB_send_str'
collect2: error: ld returned 1 exit status
make: *** [Makefile:16: sketch] Error 1

My makefile for this project looks like:

CPU = atmega328p
CPU_CLOCK = 16000000UL
Device = /dev/ttyUSB0

CFLAGS = -Os
CPUFLAGS = -DF_CPU=$(CPU_CLOCK) -mmcu=$(CPU)
LIBRARIES = -L$(HOME)/lib -lusart
INCLUDES = -I$(HOME)/Documents/Arduino/MyAvrLib/

###################
# USER CONFIG END #
###################

sketch: src/main.c dir
  avr-gcc $(CFLAGS) $(CPUFLAGS) $(INCLUDES) -c src/main.c -o build/main.o
  avr-gcc $(CPUFLAGS) $(LIBRARIES) build/main.o -o build/main.bin
  avr-objcopy -O ihex -R .eeprom build/main.bin build/main.hex
  @echo "Hex image successfully created..."

dir: src/main.c
 @echo "Creating build directory..."
 @mkdir -p build/

flash: sketch
  sudo avrdude -c arduino -p $(CPU) -P $(Device) -U flash:w:build/main.hex
  @echo "Sketch flash successful..."

clear:
  rm -rf build/

I'm genuinely at a loss for what I'm doing wrong. I've tried looking things up, but the avr nongnu guide on making libraries (https://www.nongnu.org/avr-libc/user-manual/library.html) has no examples, so I have nothing to check against. Help would be greatly appreciated!

reddit.com
u/Athropod101 — 15 hours ago

how can i improve error handling in my code?

Hi! i am currently have this snippet of code:

char *shader_get_source(const char *shader_path) {
    if (!shader_path) {
        fprintf(stderr, "Shader error: invalid args\n");
        return NULL;
    }
  
    // open file in read only mode
    int shader_fd = open(shader_path, O_RDONLY, S_IRUSR | S_IWUSR);
    if (shader_fd == -1) {
        perror("Shader error");
        return NULL;
    }
  
    struct stat shader_stat;
    if (fstat(shader_fd, &shader_stat) == -1) {
        perror("Shader error");
        close(shader_fd);
        return NULL;
    }
    // printf("shader file size: %ld\n", shader_stat.st_size);
  
    char *shader_mmap =
        mmap(NULL, shader_stat.st_size, PROT_READ, MAP_PRIVATE, shader_fd, 0);
    if (shader_mmap == MAP_FAILED) {
        perror("Shader error");
        close(shader_fd);
        return NULL;
    }
  
    // close the file after mmap returned
    close(shader_fd);
  
    char *shader_src = malloc(sizeof(char) * shader_stat.st_size + 1);
    if (!shader_src) {
        fprintf(stderr, "Shader error: couldn't allocate space\n");
        return NULL;
    }
  
    // copy the file content to the allocated string
    memcpy(shader_src, shader_mmap, shader_stat.st_size);
    shader_src[shader_stat.st_size] = '\0';
    // printf("%s", shader_src);
  
    if (munmap(shader_mmap, shader_stat.st_size) == -1) {
        perror("Shader error");
        free(shader_src);
        return NULL;
    }
  
    return shader_src;
}

it just mmap's a file and store it as a NUL terminated string

is there a better way to handle errors? because there is a good chance i will forget to free something before returning because of an error and right now i am repeating myself a lot

reddit.com
u/Valuable_Moment_6032 — 21 hours ago
🔥 Hot ▲ 69 r/C_Programming

C gems

Most of us probably know about donut.c, the famous program that renders an animated 3D donut in the terminal. I'm looking for more C gems like that -- cute, short and instructive.

I'm aware of IOCCC, but there's so many programs! A curated list would be nice. Or if anyone knows of other places to find such gems, I'd love to hear.

u/hyperficial — 1 day ago
🔥 Hot ▲ 77 r/C_Programming

Any reason not to use C23?

C11 seems to be a de facto standard — not that I made a representative poll about it, send out some crawlers to gather intel from Github, Gitlab, and Codeberg, nor did I do any research on that; it's rather a personal observation.

Is there a reason for that? Why not C17 or C23? Of course, if the code base was started before these versions were finalised, there might not be a reason to switch over, yet backward compability would also not prevent using a newer version.

Do you give any thought to that when starting a new project, or are you just defaulting to C11 out of habit?

reddit.com
u/CosmicMerchant — 2 days ago
▲ 5 r/C_Programming+1 crossposts

Making a port of Inquirer.js to C

Hello, recently i started porting Inquirer.js to C, cause i needed a simple but good-looking TUI, i only implemented A Text input for now, but is cross-platform (Windows, Posix, Unix), i know it isn't much but i wanted to hear some feedback! P.S. I'm only 15 and still going to School, so i do not expect this to be used much

github.com
u/F3lix550 — 23 hours ago

How to catch CTRL input in C?

Hello,

Im trying to intercept any keypresses of the user that correspond to CTRL, in my case, i want to intercept CTRL + Q.

I first tried looking at the CTRL keycode online but couldn't find anything.

I dug a little deeper and found that i could use signal.h to intercept CTRL + C.

But can you intercept any others combinations? In my case, CTRL + Q?

Thanks for reading my message.

reddit.com
u/HedgehogNo5130 — 2 days ago

Is setting -pedantic enough?

Back in college I learned algorithms using C++ and decided some 30 years later I wanted to play with C and am really liking it. However, one question is not clear for me, when using GCC, is -pedantic enough or should I still use -Wall, -Werror, etc.?

reddit.com
u/kewlness — 2 days ago

recvfrom() function always return 10 bytes on UDP connection socket

Hey everyone,

I was practicing Socket Programming using C and ran into an issue. The recvfrom() function always returns 10 bytes on UDP socket regardless of the input given.

Here is the code which I have written:

udp_server.c:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>

#define PORT 6900
#define LINES 128 // QUERY: Changing the value to 4096 breaks the program

int main(){
    int sockfd, numrec, byterec;
    char recvline[LINES + 1]; 

    struct 
sockaddr_in
 ser_addr;
    const struct 
sockaddr_in
 clnt_addr;
    
    
socklen_t
 len = sizeof(clnt_addr);

    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("Socket Error!!");
        exit(1);
    }

    memset(&ser_addr, '\0', sizeof(ser_addr));
    ser_addr.sin_family =  AF_INET;
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    ser_addr.sin_port = htons(PORT);

    bind(sockfd, (struct 
sockaddr
*) &ser_addr, sizeof(ser_addr));

    while(1){
        if((numrec = recvfrom(sockfd, recvline, LINES, 0, (struct 
sockaddr
 *)&clnt_addr, &len)) < 0){
            perror("recvfrom error");
            exit(1);
        }

        // QUERY: FROM WHERE byterec IS FETCHING THE VALUE
        fprintf(stdout, "Connection from %s, port %d. Received %d bytes.\n", inet_ntoa(clnt_addr.sin_addr), ntohs(clnt_addr.sin_port), byterec);
        fflush(stdout);

        // recvline[byterec]='\0';
        if(strcmp(recvline, "Terminate\n") == 0){
            fprintf(stdout, "a client want me to terminate\n");
            fflush(stdout);
            break;
        }

        if(sendto(sockfd, recvline, byterec, 0, (struct 
sockaddr
 *)&clnt_addr, len) < 0){
            perror("sendto error");
            exit(1);
        }
    }

    fprintf(stdout, "server normal end\n");
    fflush(stdout); 


    return 0;
}

udp_client.h:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/socket.h>
#include<sys/types.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#define PORT 6900
#define LINES 20

int main(){
    int sockfd, bytesent, numrec, byterec;
    char sendLine[LINES], recvLine[20];
    
    struct sockaddr_in ser_addr;
    struct sockaddr_in echo_addr;
    socklen_t len = sizeof(echo_addr);
    
    if((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
        perror("Socket Error!!");
        exit(1);
    }

    memset(&ser_addr, '\0', sizeof(ser_addr));
    ser_addr.sin_family =  AF_INET;
    ser_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    ser_addr.sin_port = htons(PORT);

    while(1){
        printf("==>");
        fflush(stdout);
        fgets(sendLine, LINES, stdin);
        
        if(strcmp(sendLine, "exit\n") == 0){
            break;
        }
                
        bytesent = sendto(sockfd, sendLine, strlen(sendLine), 0, (struct sockaddr*) &ser_addr, sizeof(ser_addr));
        if(bytesent == -1){
            perror("sendto error");
            exit(1);
        }

        if(strcmp(sendLine, "Terminate\n") != 0){
            printf("----VARIABLE VALUES BEFORE----\n");
            printf("recvLine size: %d\n", sizeof(recvLine));
            printf("echo_addr size: %d\n", sizeof(echo_addr));
            printf("len var address: %p\n", &len);
            printf("len value: %d\n", len);
            printf("byterec value: %zd\n", byterec);
            printf("\n");

            if ((byterec = recvfrom(sockfd, recvLine, sizeof(recvLine), 0, (struct sockaddr*) &echo_addr, &len)) < 0){
                perror("recvfrom error");
                exit(1);
            }

            printf("----VARIABLE VALUES AFTER----\n");
            printf("recvLine size: %d\n", sizeof(recvLine));
            printf("echo_addr size: %d\n", sizeof(echo_addr));
            printf("len var address: %p\n", &len);
            printf("len value: %d\n", len);
            printf("byterec value: %zd\n", byterec);
        }

        // recvLine[byterec] = '\0';
        printf("from server: %s\n", recvLine);
    }

    close(sockfd);
    printf("echo client normal end\n");

    return 0;
}

Additional Info: I am using cygwin for the compiler.

What I tried:

  1. I tried to use char datatype for recvLine buffer variable. In this case, the value of byterec variable became 1.
  2. I gave the input of length more than the size of buffer. The valuebyterec variable changed to 10. I assumed that it might be happening because of buffer overflow. Therefore, I tried step 3.
  3. I gave the input of length less than the size of buffer. Still, the value of byterec variable is getting changed to 10.
  4. I tried to change the buffer size, LINES constant, tried to match their values. Doesn't matter what I try? the value of byterec always changes to 10 after recvfrom() function.

After trying to debug for the whole day and countless googling, I am unable to figure out what's wrong with my code. Any help would be appreciated.

Thanks in advance.

reddit.com
u/Escapshion — 2 days ago

Strange data reset in C program

Disclaimer: When you see the below functions, don't worry about their implementations, I know I have implemented them incorrectly. Skip to the explanation below.

#include <stdio.h>
#include <stddef.h>

struct header {
	size_t cap;
	size_t len;
};
#define header(pointer) ((struct header *) pointer - 1)

size_t cap(const void *const obj) {
	if (obj != NULL) {
		return header(obj) -> cap;
	}

	return 0;
}

size_t len(const void *const obj) {
	if (obj != NULL) {
		return header(obj) -> len;
	}

	return 0;
}

int main() {
	const struct {
		struct header hdr;
		int *buff;
	} obj = {
		.hdr = {
			.cap = 4,
			.len = 4
		},
		.buff = (int[]) { 1, 2, 3, 4 }
	};
	const int *const arr = ((
		struct {
			struct header hdr;
			int *buff;
		}
	) {
		.hdr = {
			.cap = 4,
			.len = 4
		},
		.buff = (int[]) { 1, 2, 3, 4 }
	}).buff;

	printf("\
			\rlen(&obj.buff) : %zu, cap(&obj.buff) : %zu\n\
			\rlen(&arr) : %zu, cap(&arr) : %zu\n\
	\r", len(&obj.buff), cap(&obj.buff), len(&arr), cap(&arr));

	return 0;
}

This is just a program demonstrating something I have been trying and an interesting thing I noted in my attempts to create it.

godbolt link

I am creating 2 identical objects. However, somehow they are acting differently.

My output of this program is returning the length and capacity values from &obj.buff but not from &arr. This is the exact output:

bin/main.exe	
len(&obj.buff) : 4, cap(&obj.buff) : 4	
len(&arr) : 8, cap(&arr) : 17179869187

So, why is that one of them is correctly returning the length and capacity values and the other is not?

My guess is that maybe C is resetting the data that it allocated since I am using only a part of that allocated data. However, I can't seem to verify this.

The output is compiled using -O3 but I tried removing that flag too and it didn't change the output.

Any help is appreciated.

PS: Yes the implementation of the function may seem incorrect, ignore that for now, I changed it, this was a previous implementation that I noticed this strange behaviour in.

u/alex_sakuta — 2 days ago

I made my own vesion control - looking for feedback

the core idea was simple, i store the changes + the context in a binary file (still as a text format). but im still thinking about applying hashing and proper binary storing. so far it only does a commit by doing './main . commit <commit_message>'.

here is the repo: https://github.com/yacine204/cit

u/Just_Jaguar3701 — 18 hours ago

Entry experience for low level and C jobs

Hi everyone, I'm new to this subreddit and to C in general. If this question isn't appropriate for this sub, please let me know and I will gladly remove or edit it.

I'm a young developer with experience building full-stack web projects. Over time, I realized that I didn't feel fulfilled animating objects with JavaScript. I felt the need to go deeper and work on complex projects involving low-level development. That being said, I started learning C and computer science fundamentals, and I can't explain how much I'm enjoying being closer to the hardware.

I also appreciate the ecosystem here. In webdev, everyone is focused on AI and new frameworks; it feels like the joy of building things from scratch is fading, not to mention that AI-generated code can be quite buggy. Furthermore, the webdev junior market is in crisis; competition is massive, with 200+ applicants per position, especially in regions like latam.

My question is about the junior job market for C and low-level roles. I want to commit to C and systems programming, but my country isn't technologically advanced, and most roles are for web development or maintaining legacy systems in Java or COBOL. There are almost no local opportunities for low-level work.

TL;DR:

  • What is the current state of the job market for junior C/low-level developers?
  • How much experience is typically required to land a remote low-level junior role?
  • What are the chances of landing a remote junior job from latam?
  • What kind of projects best demonstrate C expertise for these types of roles?
reddit.com
u/Eswaldots — 2 days ago

Book to learn C

I hate to ask this basic question here, but;

I'm now in 2nd semester CS and until now we've been working with Java, so I more or less know the fundamentals.

I'm interested in learning C, I've looked through some of the guide books but a lot of them have a "starting from 0" approach, i.e. explaining what programming is, what a compiler is and the usual drill that you get in a book for complete beginners to programming.

Is there any resource for learning C for someone who already is familiar with a programming language?

Thankss

reddit.com
u/Enes_00133 — 3 days ago