Hirdetés
- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- Megérkezett a Google Pixel 7 és 7 Pro
- Samsung Galaxy S21 FE 5G - utóirat
- Apple iPhone 17 Pro Max – fennsík
- Huawei Mate 40 Pro - a csúcson kell abbahagyni?
- Elfújta a szél a Meizu 22 Airt
- EarFun Air Pro 4+ – érdemi plusz
- Huawei Watch GT 5 Pro - egészség + stílus
- One mobilszolgáltatások
- iPhone topik
Új hozzászólás Aktív témák
-
Jester01
veterán
válasz
TheRolf
#2493
üzenetére
Először is, használd a fordítót arra, hogy minél több hibát jelezzen neked. gcc esetén erre a -Wall kapcsoló szolgál. Lássuk mi nem tetszik neki:
t.c: In function 'fordit':
t.c:14: warning: implicit declaration of function 'malloc'
t.c:14: warning: incompatible implicit declaration of built-in function 'malloc'
t.c:14: error: called object 'str' is not a function
t.c:15: error: called object 'out' is not a function
t.c:15: warning: return makes integer from pointer without a cast
t.c: At top level:
t.c:18: warning: return type defaults to 'int'
t.c: In function 'main':
t.c:21: warning: assignment makes pointer from integer without a castAz első kettő azért van, mert nincs meg a malloc prototípusa, ehhez erősen ajánlott egy #include <stdlib.h> (bár nem kötelező).
A következő kettő azért van, mert kerek zárójelet használtál szögletes helyett tömb indexeléshez.
Az ötödik probléma, hogy a main() függvényed visszatérési típusa nincs megadva. Bár C-ben alapértelmezés az int, de azért ajánlott kiírni.
Az utolsó kettő oka, hogy a függvényed visszatérési típusából hiányzik egy csillag, hogy pointert adjon vissza.
Ezeket javítva sajnos további hibákra derül fény:
t.c: In function 'main':
t.c:25: warning: control reaches end of non-void function
t.c: In function 'fordit':
t.c:16: warning: 'i' may be used uninitialized in this function
/tmp/ccle9qDf.o: In function `main':
t.c:(.text+0x89): warning: the `gets' function is dangerous and should not be used.Az első, hogy a main() nem ad vissza értéket. Ezt egy return 0; kiválóan orvosolja.
A második már súlyosabb, azt mondja, az i változónak nincs kezdőérték megadva mielőtt használod. C-ben a változóknak nincs alapértelmezett kezdőértékük.
Végül, a gets függvény használata veszélyes, mivel nincs benne hosszúság ellenőrzés. Ugyan ez nem végzetes hiba de helyette ajánlott az fgets használata.
Jelenleg akkor így néz ki a program ami a fordítónak már nem okoz fejfájást:
#include <stdio.h>
#include <stdlib.h>
int hossza(char *str){
int i=0;
while (str) {
i++;
}
return i;
}
char* fordit(char *str) {
int i=0;
char *out;
out = (char*)malloc((hossza(str))*(sizeof(char)));
while (str[i]) {
out[i] = str[-i-1];
}
return out;
}
int main() {
char betuk[50];
char *z;
gets(betuk);
z = fordit(betuk);
puts(z);
free(z);
//getchar();
return 0;
}(A gets benne maradt egyelőre, lásd később.)
Ezután jutunk el a futási hibákhoz. A felderítésükhöz debugger vagy más diagnosztikai program (pl. valgrind) ajánlott. Példának okáért kapjuk elő a gdb debuggert. Miután beadtuk a stringünket, azt látjuk, hogy a processzor pörög de nem történik semmi. Nézzük meg miben mesterkedik a programunk:
(gdb) r
Starting program: /var/tmp/a.out
hello
^C
Program received signal SIGINT, Interrupt.
hossza (str=0x7fffffffe6d0 "hello\n") at t.c:6
6 while (str) {Ahha. Szóval ott került végtelen ciklusba, mivel az str az biza nem változik. Oda igazából str[i] kellene. Nézzük, jobb lesz-e ettől. Igen, most egy másik ciklusban pörög, aminek a feltétele a megtévesztésig hasonló:
Program received signal SIGINT, Interrupt.
0x00000000004005f5 in fordit (str=0x7fffffffe6d0 "hello\n") at t.c:16
16 while (str[i]) {Innen pedig azért nem lép ki, mert az i nem változik a ciklusban. Tegyünk róla, hogy 1-el növekedjen. Szuper jó, ettől már legalább lefut a program, csak semmit nem ír ki. Nézzük meg például honnan lesz első betűje a kimenetnek:
(gdb) br 17
Breakpoint 1 at 0x40066d: file t.c, line 17.
(gdb) r
Starting program: /var/tmp/a.out
hello
Breakpoint 1, fordit (str=0x7fffffffe6d0 "hello\n") at t.c:17
17 out[i] = str[-i-1];
(gdb) p i
$1 = 0
(gdb) p -i-1
$2 = -1Hoppá, mire is kértük a számítógépet? out[0] = str[-1]. Ez így nem lesz jó, oda nekünk az utolsó betű kellene, ami azt jelenti itt még hozzá kellene adni a string hosszát. Tegyük ezt meg. Csoda, kiírta fordítva a szöveget. Na de minket nem olyan egyszerű boldoggá tenni, ráengedjük a valgrindot is:
hello
==28218== Invalid read of size 1
==28218== at 0x4C25824: __GI_strlen (mc_replace_strmem.c:284)
==28218== by 0x4E8DDCA: puts (ioputs.c:37)
==28218== by 0x400697: main (t.c:28)
==28218== Address 0x518a045 is 0 bytes after a block of size 5 alloc'd
==28218== at 0x4C244E8: malloc (vg_replace_malloc.c:236)
==28218== by 0x40061D: fordit (t.c:15)
==28218== by 0x400687: main (t.c:27)Elismerem ez kissé érthetetlen, de azt szeretné mondani nekünk, hogy a kiírásnál az első 5 byte után a hatodik olvasása nem jó. De miért is akar hatot olvasni, ha egyszer a "hello" csak 5 betű. Jusson eszünkbe, hogy C-ben a stringek végét egy nulla byte jelzi. Írjuk át a programot, hogy ezt vegye figyelembe. Ettől már a valgrind is elégedett lesz.
Végszó:
1) Sajnos az fgets függvény a sor végét jelző entert is eltárolja a pufferbe, így azzal extra izzadnunk kell egy kicsit.
2) gondolom az strlen használata tiltott volt, ezért írtál saját hossza függvényt
3) sizeof(char) definíció szerint 1.
4) a malloc visszatérési típusa void*, és az bármilyen pointerré cast nélkül konvertálható. Lehetőleg kerüljük a felesleges castolásokat.
5) némi visszajelzés a felhasználó felé nem ártFentiek figyelembevételével a végső program:
#include <stdio.h>
#include <stdlib.h>
int hossza(char *str){
int i=0;
while (str[i]) {
i++;
}
return i;
}
char* fordit(char *str) {
int i=0;
int hossz=hossza(str);
char *out = malloc(hossz+1);
while (str[i]) {
out[i] = str[hossz-i-1];
i++;
}
out[i]=0;
return out;
}
int main() {
char betuk[50];
char *z;
int hossz;
printf("string (max %d karakter):\n", sizeof(betuk)-2);
fgets(betuk, sizeof(betuk), stdin);
hossz=hossza(betuk);
if (hossz>0 && betuk[hossz-1]=='\n') {
betuk[hossz-1]=0;
}
z = fordit(betuk);
puts(z);
free(z);
return 0;
}Elnézést a hosszú hozzászólásért, csak igyekeztem halászatot oktatni, nem sült galambot kínálni.
Új hozzászólás Aktív témák
● olvasd el a téma összefoglalót!
● ha kódot szúrsz be, használd a PROGRAMKÓD formázási funkciót!
- Autós kamerák
- 3DMark 11 eredmények
- Ma van a szülinapom
- Samsung Galaxy S24 Ultra - ha működik, ne változtass!
- Megérkezett a Google Pixel 7 és 7 Pro
- Parci: Milyen mosógépet vegyek?
- Samsung Galaxy S21 FE 5G - utóirat
- Milyen videókártyát?
- Apple iPhone 17 Pro Max – fennsík
- Őrült módjára szabja át AI-ra a GeForce-okat Kína
- További aktív témák...
- Asus Prime Z490-P / Beszámítás OK!
- HP EliteBook 645 G10 14" AMD Ryzen 5 PRO-7530U 4,5Ghz 16GB DDR4-3200Mhz 512GB Nvme Magyar Bill.
- Bomba ár! Dynabook Portege X30-L - i5-11G I 8GB I 256SSD I 13,3" FHD Sérült I Cam I W11 I Garancia!
- Bomba ár! Dynabook Portege X30-L - i5-1135G7 I 8-16GB I 256SSD I 13,3" FHD I Cam I W11 I Garancia!
- Bomba ár! Dynabook Portege X30-F - i5-8GEN I 8GB I 256SSD I 13,3" FHD I BillSér I Cam I W11 I Gari!
- HP ProDesk 600 G5 i3-9100 8GB 256GB 1 év garancia
- GYÖNYÖRŰ iPhone 14 Pro Max 256GB Space Black-1 ÉV GARANCIA - Kártyafüggetlen, MS4149
- BESZÁMÍTÁS! MSI B650 R7 7800X3D 32GB DDR5 2TB SSD RTX 5070Ti 16GB Asus ROG Strix Helios GX601 750W
- Új és újszerű 13-14 Gamer, ultrabook, üzleti, 2in1, X360, Touch készülékek kedvező áron Garanciával
- Samsung Galaxy A33 5G / 6/128GB / Kártyafüggetlen / 12Hó Garancia /
Állásajánlatok
Cég: Laptopműhely Bt.
Város: Budapest
Cég: Laptopszaki Kft.
Város: Budapest


