Add Makefile and README; refactor Caesar cipher CLI to interactive stdin/stdout implementation - #1
Add Makefile and README; refactor Caesar cipher CLI to interactive stdin/stdout implementation#1ukis666 wants to merge 1 commit into
Conversation
📝 WalkthroughWalkthroughThe PR adds a Makefile for building a Caesar cipher project from source using gcc with C11 standard, translates the README to Turkish with expanded build and usage instructions, and refactors the core cipher implementation from file-oriented processing to a CLI-driven, in-memory pipeline with new helper functions for shift normalization, character manipulation, and text encryption. Changes
Sequence DiagramsequenceDiagram
participant User
participant Menu as Menu System
participant TextProc as Text Processing
participant Output as Output Handler
loop CLI Loop
User->>Menu: Start/Display menu
Menu->>User: Show options
User->>Menu: Select operation
alt Encrypt Text
Menu->>User: Prompt for text
User->>Menu: Enter text
Menu->>TextProc: Call sifrele_metin()
TextProc->>TextProc: Apply shift to each char
TextProc->>Output: Return encrypted text
else Decrypt All Variants
Menu->>User: Prompt for text
User->>Menu: Enter text
Menu->>TextProc: Call tum_cozumleri_yazdir()
TextProc->>TextProc: Generate 26 shift variants
TextProc->>Output: Print all variants
else Exit
Menu->>User: Exit program
end
Output->>User: Display results
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment Tip You can make CodeRabbit's review stricter and more nitpicky using the `assertive` profile, if that's what you prefer.Change the |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@sifreleyicim/sifreleyicim1/sifreleyici.c`:
- Around line 68-76: Include <errno.h> and <limits.h>, set errno = 0 before
calling strtol(satir, &endptr, 10), then after the call reject the parse if
errno == ERANGE or if deger < INT_MIN || deger > INT_MAX; keep the existing
empty-string and endptr checks (satir[0] == '\0' || (endptr != NULL && *endptr
!= '\0')) and return 0 on those failures, only cast and assign *sonuc =
(int)deger and return 1 when no errors and value is within int range.
- Around line 17-27: satir_oku currently treats fgets()==NULL as an empty string
and never signals EOF; change its signature to return an int status (0 for EOF,
1 for success), on fgets()==NULL return 0 (do not set dizi to ""), after a
successful read check if the newline was present and if not drain stdin until
'\n' to discard the remainder of the overlong input; update sayi_oku to
propagate EOF by returning -1 when satir_oku returns 0, and update main to check
for -1 from sayi_oku and break/exit the input loop instead of treating it as an
invalid choice.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 58973acb-ae97-4f62-ab6b-2640885d58af
📒 Files selected for processing (3)
MakefileREADME.mdsifreleyicim/sifreleyicim1/sifreleyici.c
| void satir_oku(char dizi[], size_t boyut) { | ||
| if (fgets(dizi, (int)boyut, stdin) == NULL) { | ||
| dizi[0] = '\0'; | ||
| return; | ||
| } | ||
|
|
||
| dizi[i] = '\0'; | ||
| size_t len = strlen(dizi); | ||
| if (len > 0 && dizi[len - 1] == '\n') { | ||
| dizi[len - 1] = '\0'; | ||
| } | ||
| } |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Inspect the EOF/truncation path from satir_oku() into sayi_oku() and main().
sed -n '17,27p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- sayi_oku --\n'
sed -n '62,76p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- main loop --\n'
sed -n '91,98p' sifreleyicim/sifreleyicim1/sifreleyici.cRepository: ukis666/Ceasar_Cipher_Decoder_and_Encoder
Length of output: 879
🏁 Script executed:
sed -n '85,110p' sifreleyicim/sifreleyicim1/sifreleyici.cRepository: ukis666/Ceasar_Cipher_Decoder_and_Encoder
Length of output: 570
Differentiate EOF/truncation from ordinary invalid input.
When fgets() returns NULL (EOF from Ctrl-D or closed stdin), the code converts it to an empty string, treating it as invalid input rather than a signal to exit. This traps the loop in an infinite "Gecersiz secim" cycle with no way to break. If input exceeds the buffer size, the missing newline goes undetected, and unread characters remain in stdin, causing the next prompt to consume stale input.
To fix: return a read status from satir_oku() (0 for EOF, 1 for success), drain unread input when no newline is found, have sayi_oku() return -1 on EOF, and let main() check for EOF and break before treating empty input as an invalid choice.
Suggested direction
-void satir_oku(char dizi[], size_t boyut) {
+int satir_oku(char dizi[], size_t boyut) {
if (fgets(dizi, (int)boyut, stdin) == NULL) {
dizi[0] = '\0';
- return;
+ return 0;
}
size_t len = strlen(dizi);
if (len > 0 && dizi[len - 1] == '\n') {
dizi[len - 1] = '\0';
+ } else {
+ int ch;
+ while ((ch = getchar()) != '\n' && ch != EOF) {
+ }
}
+
+ return 1;
}- if (!sayi_oku("", &secim)) {
+ int ok = sayi_oku("", &secim);
+ if (ok < 0) {
+ break;
+ }
+ if (!ok) {
printf("Gecersiz secim.\n");
continue;
}Also applies to: 95-98
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sifreleyicim/sifreleyicim1/sifreleyici.c` around lines 17 - 27, satir_oku
currently treats fgets()==NULL as an empty string and never signals EOF; change
its signature to return an int status (0 for EOF, 1 for success), on
fgets()==NULL return 0 (do not set dizi to ""), after a successful read check if
the newline was present and if not drain stdin until '\n' to discard the
remainder of the overlong input; update sayi_oku to propagate EOF by returning
-1 when satir_oku returns 0, and update main to check for -1 from sayi_oku and
break/exit the input loop instead of treating it as an invalid choice.
| char* endptr = NULL; | ||
| long deger = strtol(satir, &endptr, 10); | ||
|
|
||
| FILE* input_file = fopen("sifreli_text.txt", "w"); | ||
| FILE* output_file = fopen("sifresiz_text.txt", "r"); | ||
| if (can_file_open(output_file, input_file)) { | ||
| // Dosya açılamadıysa programı sonlandırıyoruz | ||
| return 1; | ||
| } | ||
| if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) { | ||
| return 0; | ||
| } | ||
|
|
||
| system("clear"); // Linux'ta ekran temizleme | ||
| printf("DON'T FORGET TO SAVE\n"); | ||
| *sonuc = (int)deger; | ||
| return 1; |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Confirm that sayi_oku() currently uses strtol() without range/error guards.
sed -n '62,76p' sifreleyicim/sifreleyicim1/sifreleyici.c
printf '\n-- guard search --\n'
rg -n 'strtol|errno|ERANGE|INT_(MIN|MAX)' sifreleyicim/sifreleyicim1/sifreleyici.c || trueRepository: ukis666/Ceasar_Cipher_Decoder_and_Encoder
Length of output: 486
🏁 Script executed:
head -20 sifreleyicim/sifreleyicim1/sifreleyici.cRepository: ukis666/Ceasar_Cipher_Decoder_and_Encoder
Length of output: 532
Reject out-of-range numeric input before narrowing to int.
strtol() parses into long, but *sonuc = (int)deger; happens without checking errno or bounds. Values outside the platform int range (e.g., 2147483648 on a 32-bit int system) are accepted and silently truncated instead of triggering validation error.
Add the missing headers:
+#include <errno.h>
+#include <limits.h>Then guard the parse and cast:
+ errno = 0;
char* endptr = NULL;
long deger = strtol(satir, &endptr, 10);
- if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) {
+ if (satir[0] == '\0' || *endptr != '\0' ||
+ errno == ERANGE || deger < INT_MIN || deger > INT_MAX) {
return 0;
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| char* endptr = NULL; | |
| long deger = strtol(satir, &endptr, 10); | |
| FILE* input_file = fopen("sifreli_text.txt", "w"); | |
| FILE* output_file = fopen("sifresiz_text.txt", "r"); | |
| if (can_file_open(output_file, input_file)) { | |
| // Dosya açılamadıysa programı sonlandırıyoruz | |
| return 1; | |
| } | |
| if (satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) { | |
| return 0; | |
| } | |
| system("clear"); // Linux'ta ekran temizleme | |
| printf("DON'T FORGET TO SAVE\n"); | |
| *sonuc = (int)deger; | |
| return 1; | |
| errno = 0; | |
| char* endptr = NULL; | |
| long deger = strtol(satir, &endptr, 10); | |
| if (satir[0] == '\0' || *endptr != '\0' || | |
| errno == ERANGE || deger < INT_MIN || deger > INT_MAX) { | |
| return 0; | |
| } | |
| *sonuc = (int)deger; | |
| return 1; |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@sifreleyicim/sifreleyicim1/sifreleyici.c` around lines 68 - 76, Include
<errno.h> and <limits.h>, set errno = 0 before calling strtol(satir, &endptr,
10), then after the call reject the parse if errno == ERANGE or if deger <
INT_MIN || deger > INT_MAX; keep the existing empty-string and endptr checks
(satir[0] == '\0' || (endptr != NULL && *endptr != '\0')) and return 0 on those
failures, only cast and assign *sonuc = (int)deger and return 1 when no errors
and value is within int range.
Motivation
Description
MakefilewithCC,CFLAGS,TARGET, and a defaultall/cleantarget and path tosifreleyicim/sifreleyicim1/sifreleyici.c.README.mdwith Turkish usage notes, features, build instructions, and examples formakeand directgcccompilation.sifreleyicim/sifreleyicim1/sifreleyici.cby removing file-based operations and global I/O, addingnormalize_shift,satir_oku,kaydir_char,sifrele_metin,tum_cozumleri_yazdir,sayi_oku, andmenu_yazdir, and convertingmaininto an interactive CLI that reads fromstdinand writes tostdout.ALFABE_UZUNLUGUconstant, ensured newline trimming, preserved upper/lower case letters, and implemented normalized shift wrapping for negative/large values.Testing
makewhich invokesgcc -Wall -Wextra -pedantic -std=c11 -o sifreleyici sifreleyicim/sifreleyicim1/sifreleyici.c.gcccommand completed without compiler errors.Codex Task
Summary by CodeRabbit
New Features
Documentation
Chores