-
PROHARDVER!
Új hozzászólás Aktív témák
-
emitter
őstag
válasz
emitter #1512 üzenetére
tárgytalan a dolog, tényleg nagyon sz@r sorrendben és teljesen összevissza volt leírva a wav-file felépítése
hogy lehet ilyen munkát kiadni valakinek a kezéből
fejből, elméletben írta és soha ki nem próbálta
úgyhogy most szépen fut a progim, felismeri a wavokat - minden OK![link]
most már csak annyi a problámám, hogy a lejátszás végén elég sokáig tart (5-6 mp), míg kilép a progiból... ez vajon mitől lehet?
mégegy dolog: szeretném kibővíteni majd a tudását mp3-ra is, tudtok mondani olyan libet, ami mp3-at tud dekódolni? mert eddig a neten sajna nem sok mindent találtam, persze keresek tovább, de azért ha tudtok kapásból ilyet, az jól jönne
emitter
mod: Jester, köszi szépen az infót, sokat segítettélja, a kódom mostantól nem wav2.c, hanem a linkelt
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1512 üzenetére
Mivel a te wavod a kiírás szerint csak 10676 byte így persze, hogy nem kell a ciklus hiszen egy bufferbe belefér
Próbáld egy nagyobb fájllal.
Az snd_pcm_writei visszatérési értéke csak akkor hiba, ha kisebb mint 0. Egyébként a kiírt keretek számát adja vissza. Gondolom teljesen szabályos, ha alkalomadtán kevesebbet ír ki mint amennyit beadtál, ilyenkor feltehetõleg ciklusban újra kell próbálni. De olvasd el a doksit ezügyben.
Vszg azért kapsz segmentation fault-ot, mert többet íratsz ki a bufferbõl mint amekkora a mérete. Most már én is kezdek belezavarodni (persze én nem néztem utána), hogy minta (sample) vagy keret (frame) számot kell neki megadni. -
emitter
őstag
válasz
emitter #1511 üzenetére
az mitől lehet, hogy a progim más formátum-hosszt ismer fel egy adott wavnál, mint a 'file' progi
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ ./wav2 rexi.wav
Begin fileposition: 0
RIFF
10676
WAVE
fmt
format_length: 16
format_tag: 1
channels: 1
sample_rate: 44100
avg_bytes_sec: 44100
block_align: 0
bits_per_sample: 1
...
----------
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ file rexi.wav
rexi.wav: RIFF (little-endian) data, WAVE audio, Microsoft PCM, 8 bit, mono 44100 Hz
----------
és ezáltal persze rosszul is játsza le a rexi.wav-ot..
itt a kibővített kód [link], ugyanis átírtam, hogy ő olvassa ki a wav headerjéből az infókat... mindezt ezen az oldalon találtam: [link]
az az érdekes, hogy az írója szerint a 38.-ik bájttól már jön a wavban a 'data', szóval a hasznos rész, ezzel szemben az én wavomnál csak a 41.-ik bájt az első adatbájt
akkor a maradék 3 bájt mi lehet?
asszem erre az írásra mondtad Jester, hogy nem tudja a fazon, mit is csinál valójában, ez lehet, mert elég zavaros a dolog, pl szerinte köv. sor
fread(&bits_per_sample, sizeof(short), 1, fp); //8 bit or 16 bit file?
egy mintavétel méretét adja meg bitben. Ehhez képest nekem bits_per_sample: 1
mit javítsak a kódon, hogy jól felismerje a wav sample-méretét? -
Jester01
veterán
válasz
emitter #1506 üzenetére
Az semmiképp nem egészséges, hogy minden buffert 10x játszol le
Amúgy úgy látom különbözõ library verziót használunk, mert nekem a rate beállító fv tényleg nem pointer vár (ezért is írtam tegnap, hogy nekem mûködött az eredeti változat). Cserébe viszont nekem nem szól
MOD: már legalább szól16384 biztos sok volt neki. Alakulgat...
[Szerkesztve] -
emitter
őstag
válasz
emitter #1505 üzenetére
nagyon nem vagyok tisztában azzal, hogy végülis egy wavban milyen infó hol található (fejlécre gondolok), és hogy mi történik akkor, ha nem a neki megfelelő paraméterekkel játszom le... ez utóbbiról azt olvastam, h kárt is okozhat akár, szernecsére nekem csak idegesítő zaj jött a hangszórómból
itt találtam egy wav-felépítést: [link]
viszont nekem így néz ki a wav fájlom (eddig kettőt néztem meg, mindkettő fejléce azonos hosszú):
RIFF~DÝ^@^@WAVEfmt ^P^@^@^@^A^@^A^@^Q+^@^@''V^@^@^B^@^P^@data...
szóval a 40.-ik karakternél kezdődnek a tényleges adatok. Egyébként attól, hogy véletlenül a 44. karaktertől kezdem el lejátszani, attól még kéne szólnia, nem? csak legfeljebb ''kicsit'' később kezdve
segítsetek, mert egyedül nem tudok túljutni ezen a dolgon
ui: és arról sem találtam még infót, hogy mekkora buffert ajánlatos fenntartani, ez gondolom megegyezik azzal az adatmérettel, amit egyszerre kiküld a hangkártyának - ez mekkora legyen? próbálkoztam már 1-16384 bájtig, egyik se jött be, csak zümmögés...
mod: a wav fejlécénél ''fmt'' után egy szóköz van, és természetesen az egész fejléc egy sorban van
és felraktam a legújabb wav2.c-t
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1493 üzenetére
Ezt a wav1.c-t sürgõsen felejtsd el! Fogalma sincs az ürgének mit csinál. Ha 4 byteos tömbbe olvas be, akkor azt pl. nem lehet strcmp-vel hasonlítani, mert nincs benne lezáró 0. Helyesen strncmp-vel 4 karakter hosszon stb. Ugyanezen okból nem tudod kiírni sem: %s-t próbáltál, ez pedig nem string, csak 4 karakter.
A wav2 nekem mûködik. Fordítsd debug infóval és nézd meg gdb-vel, hogy hol halálozik el.
melyik fv küldi a buffer tartalmát a hangkártyának?
Mégis mit gondolsz? Hiszen csak egyetlen hívás van a ciklusban, az snd_pcm_writei.
Egészen pontosan kell bele egy (f)read ami beolvassa a következõ 128 byteot. Gondolom érdemesebb lesz nagyobb buffert használni. -
Jester01
veterán
válasz
emitter #1491 üzenetére
Nemtom honnan szedted, de az összes hibás fread hívásból lemaradt egy & jel.
Amúgy a minimal playback progi kis módosítással lejátssza a wavod, ha nem baj, hogy a paramétereket nem a wavból veszi. Simán abban a lejátszó ciklusban feltöltöd a buf-t a fájlból (az elsõ - azt hiszem - 44 byteot átugrod, az a fejléc) -
Jester01
veterán
válasz
emitter #1485 üzenetére
Az undefined reference az linkelési hiba. Kell egy -lasound kapcsoló, mert ezek az alsa könyvtárban vannak.
honnan tudjam, hogy ez a fv milyen típusú mutatót vár 3. arg-ként
A legbiztosabb ha megnézed a header fájlban, hiszen a fordító is onnan tudja. De amúgy az alsa doksiban minden bizonnyal benne van.
A BYTE és DWORD típusokkal vigyázni kell, hogy amit használsz valóban 8 és 32 bit legyen. Ezt eselteg egy configure scripttel lehet ellenõrizni ami mindig kideríti melyik szabványos típus felel meg. De te most valóban nyugodtan írhatsz helyettük unsigned char-t és unsigned int-et. -
emitter
őstag
válasz
emitter #1477 üzenetére
átírtam, szerintem most jónak kell már lennie, viszont még mindig az #1477-ben leírt hibát adja
nem is értem ezt a sort:
sa.sa_handler = sigchld_handler;
miközben a fv definíciója ez:
void sigchld_handler(int s){
while(wait(NULL) > 0);
}
hogyan hívhatok egy paraméteres fv-t paraméter nélkülaz az érdekes, hogy ugyanez a fv-hívás működött régebben, mikor még osztály nélkül írtam meg a progit...
szerinted hol a hiba, mit javítsak?
és felraktam a táramra a legújabb server_oop.cpp-t.. -
Jester01
veterán
válasz
emitter #1476 üzenetére
Destruktort (általában) nem kell meghívni, az meghívódik az objektum megszûnésekor magától. Ha mégis meg akarod hívni (de most nem
) akkor simán metódushívással (objektumpéldányra!)
A másik problémádra: az a baj, hogy a tagfüggvények implicit elsõ paraméterként megkapják az objektumra mutató pointert (this). Igy aztán már nem egyezik a prototípus. Csinálj belõle static metódust, az nem kap this pointert. Viszont abban ebbõl kifolyólag nem is hivatkozhatsz nem static tagokra.
MOD: ja és a send()-nek természetesen úgy mondod meg, hogy egy tagfüggvénybe rakodm, ezáltal elrejtve az implementációt.
[Szerkesztve] -
emitter
őstag
válasz
emitter #1476 üzenetére
és mégegy hiba, amire nem tudok rájönni:
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ g++ -Wall -o server_oop server_oop.cpp
server_oop.cpp: In member function 'void myConn::buildConn(int, int&, sockaddr_in&)':
server_oop.cpp:71: error: argument of type 'void (myConn:: )(int)' does not match 'void (*)(int)'
ezt erre a sorra dobja:
sa.sa_handler = sigchld_handler; //levag minden halott folyamatot
ez a sor ugyanis a buildConn() fv-ben van, ami a private részben van.
előtte szintén a private részben van egy ilyen fv:
void sigchld_handler(int s){
while(wait(NULL) > 0);
}
amíg nem írtam át a progit osztályosra, addig simán működött a dolog
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1462 üzenetére
Huhh? Ha átálltál, akkor milyen buf-od van már megint? A size() az a string osztály metódusa:
#include <iostream>
#include <string>
using namespace std;
int main(int, char**)
{
string s;
getline(cin, s);
cout << ''length: '' << s.length() << '', size:'' << s.size() << endl;
return 0;
}
Esetleg a using-ot kifelejtetted? -
Jester01
veterán
válasz
emitter #1460 üzenetére
Elõször is eldöntöd, hogy mit akarsz használni. Ha maradsz a c ''stringeknél'' akkor a c-s stdio-t használod és a c-s függvényeket (strlen, fgets stb.) Ha c++ stringet használsz, akkor a c++ lehetõségeit használd (iostream, string stb). Ha pedig c++ stringbõl c string kell, akkor a c_str() metódussal azt is kaphatsz, de ez csak olvasható.
-
Jester01
veterán
válasz
emitter #1458 üzenetére
Az >> operátor ugyanúgy szavakat olvas mint a scanf %s formátuma. Ha egész sort akarsz, akkor használd a getline függvényt.
A <> és az idézõjel pont ugyanazt jelenti mint c-ben, mégpedig a keresési útvonalat határozza meg. Ha idézõjelet használsz, akkor az aktuális fájlhoz képest értelmezett relatív elérési útvonallal megadott directoryban keresi elõször és csak utána a -I kapcsolóval megadott illetve a beépített helyeken. A C++ headerek .h kiterjesztés nélkül vannak, pl. #include <string>. De ez mást tartalmaz mint a string.h! -
emitter
őstag
válasz
emitter #1457 üzenetére
az mitől van, hogy a cin egy sztring beolvasásánál a szóköznél kettévágja azt, és elég furcsa dolgokat művel
while(1){
cout << ''> '';
cin >> buf;
cout << buf;
cout << ''\nstrlen(buf): '' << strlen(buf) <<endl;
if(send(sockfd, buf, strlen(buf), 0) == -1){
perror(''send'');
exit(1);
}
}
ez a kérdéses kódom, és ezt írja ki:
> ki vagy?
ki
strlen(buf): 2
> vagy?
strlen(buf): 5
>
mintha a stdin-bemeneti puffert nem űrítené a szóköz beolvasása után, 2x fut le a ciklus, mire kiürül a puffer...
mivel tudnék segíteni a dolgon? (fflush(stdin)-re semmit nem csinál)
szóval azt szeretném ha szóközös sztringeket egybe venné
thx
mod: még annyit kérdeznék, hogy #include-nál C++ban mikor kell '''' közé és mikor <> közé rakni a libet: pl. ha a string libet akarom behúzni, azt hogyan kell helyesen? Tudom, h a C-s módszert is elfogadja, de én szeretnék teljesen C++valid lenni
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1453 üzenetére
Figyi, te elloptad emitter nickjét? Neki azért sikerült egy aknakeresõ progit írni.
Az a sor NEM konvertálja az argv[1] stringet számmá ergo nem jó porton fog hallgatózni a szervered. Ha nem hiszed, írasd ki a MYPORT értékét.
Másik kérdésedre: az fg paranccsal elõtérbe hozhatod. -
Jester01
veterán
válasz
emitter #1447 üzenetére
megint nem gondolkoztam mielőtt írtam: csak konvertálnom kellett (socklen_t*)-vel
Rossz ötlet volt. A változó típusát kell átállítani, nem a pointert castolni. Pl. ha a socklen_t 64 bites és te egy int* pointert adsz be átcastolva, akkor szépen felülíródik az utána lévõ memóriaterület elsõ 4 byte-ja.
nagy nehezen tájöttem a hibára:
if( sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1){...
a sockfd-s kifejezést még külön be kellett zárójelezni... de hogy miért
Operátor precedencia. Különben miért volt nehéz? A gcc warningot dob érte...
server.cpp:36: warning: suggest parentheses around assignment used as truth value
Ugye az accept-nél is zárójeleztél? Én különben is kerülöm az értékadás+feltétel kombinációt, jelen esetben abszolút semmit nem nyersz vele. Ha simán azt írod, hogy
newfd = accept(sockfd, (struct sockaddr *)&client_addr, &sin_size);
if (newfd == -1){
az sokkal olvashatób és még a precedencia dologba sem szaladsz bele.
Ugye a szerver a 9999-es porton listenel? Mert a kód amit kitettél a netre az tojik a parancssorra és mindenképp a 3490-es porton figyel. (netstat -l)
MOD: és amúgy mûködik is:
hcs:/tmp> ./server
Kliens ciminfoja:
ip: 16777343
port: 33205
Program vege. Nyomj egy bill-t!x
hcs:~> nc 127.0.0.1 3490
Hello world!
[Szerkesztve] -
emitter
őstag
válasz
emitter #1447 üzenetére
valszeg a localhost miatt van a hiba, de miért???
a beej leírása szerint simán kéne menni egyazon gépen mind2 proginak (külön ablakból indítottam őket)
a szerver eljut az accept-ig, ott várakozik a kérésekre
a kliens viszont sajnos Connection refused-t dob
akár LAPTOP-ot írok hostként, akár 192.168.1.2-t, akár 127.0.0.1-t... -
emitter
őstag
válasz
emitter #1446 üzenetére
nagy nehezen tájöttem a hibára:
if( sockfd = socket(AF_INET, SOCK_STREAM, 0) == -1){...
a sockfd-s kifejezést még külön be kellett zárójelezni... de hogy miért
-------------
közben újabb hiba, a szervert elindítva ugyanarról a gépről nem tudok rácsatlakozni
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ telnet LAPTOP 9999
Trying 127.0.0.1...
telnet: Unable to connect to remote host: Connection refused
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$
vagy
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ ./client LAPTOP 9999
connect: Connection refused
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$
ezek vajon miért
ja, természetesen előtte elindítottam a szervert:
emitter@LAPTOP:~/BME_nemet/Prog2/Nagyhazi$ ./server 9999
Listening...
[Szerkesztve] -
emitter
őstag
válasz
emitter #1445 üzenetére
megint nem gondolkoztam mielőtt írtam: csak konvertálnom kellett (socklen_t*)-vel
viszont most újabb hiba jön futtatáskor, amivel már tényleg nem tudok mit kezdeni:
bind: Socket operation on non-socket
a server.cpp-t felnyomtam ide: [link]
ha a setsockopt()-ot bennhagyom (most ki van kommentezve), akkor is ugyanezt a hibát adja, csak bind helyett setsockopt-ra -
Miracle
senior tag
-
Miracle
senior tag
válasz
emitter #1409 üzenetére
(őszintén megmondom, a magyarsága borzasztó a fordításnak, majdnem elment tőle a kedvem, hogy lehet valaki ilyen pocsék helyesírású ) de azért átrágtam magam rajta
ott van az angol valtozat is. egyebkent meg valaki a szabadidejeben leforditotta, ha nem tetszik javitsd ki vagy ne hasznald.
szóval: ha én a progimban wav-streamet akarok [ ... ] szóval ebben az esetben milyen módot ajánlotok: stream, vagy datagram
ez nem _veletlen_ egybeeses
es ezen kívül: milyen fv-nyel érdemes küldeni a cuccost: send(), sendto(), write()?
a writeot semmikepp sem, a snedto fv. to es tolen parameterei ignoralva vannak connection-modu socketek eseten, mint pl. a SOCK_STREAM, igy ex-has valassz egyet, ugyan az a ketto.
aztán, úgy csináljam a dolgot, hogy nyitok én egy portot a gépen, vagy hagyjam a kernelre a random választást?
ahogy tetszik. habar a szerveren nem art tudni melyik porton figyel a progi mert oda kell csatlakozni a kliensnek. (es ha nem tudod nyilvan nehez)
az átküldött adatokat érdemes mondjuk md5-tel ellenőrizni (mármint hogy megérkezett-e minden rendben, vagy elvileg nem veszhet el adat?)
vaw stream eseten imho tok folosleges de ahogy erzed... nem lesz gaz.
mod: és mégegy dolog: Linuxon írom az egészet és C++ban kéne (ezt eddig nem is mondtam ) namost nekem csak egy gépemen van linux, azt lehet hogy csak látszólag küldöm a hálózatra a cuccost, hogy ki tudjam próbálni a működőképességét, de valójában mondjuk a saját ip-mre küldöm, így egyazon gépen futhat a kliens és a szerver progi? vagy hogyan oldjam meg ezt
127.0.0.1 szinte kivetel nelkul minden oprendszeren 1 loop-device, ami gyakorlatilag a localhostod, ide batran csatlakozhatsz. csatlakozhatsz emellett a sajat IP cimedre is, es akkor nem kell erre a 99.99999% valoszinuseggel letezo loop-devicera hagyatkozni. vagy feloldhatod a ''localhost'' domainnevet, az is magadra mutat majd. -
Miracle
senior tag
válasz
emitter #1399 üzenetére
IMHO teljesen felesleges a hangkartyaval foglalkozni, kezdj vaw streammel, es legyen vaw stream a kimenet is, ezt mind a ket rendszeren nagyon konnyen le tudod jatszani, elo tudod allitani, es nem kell vele szorakozni. namarmost vaw streamet nem kuldunk at halozaton, mert a rendszergazda sovenyvagoval disconnectel a halozatrol, valamifele tomoritest kell alkalmazni. hasznalhatsz valami vesztesegmentes stream tomorito eljarast, mint pl lz algoritmusok, vagy hasznalhatsz valamilyen minosegveszteseges tomoritest, mint pl. mp3 vagy ogg (utobbit javaslom, mert jobban tomorit) majd az igy letrejovo adatfolyamot valahogy at kell tuszkolni a halozaton, ami egy TCP csatorna felett nem egy nehez feladat. a nehezseg ott kezdodik az egeszben, hogy neked detektalnod kell, hogy ha keves a savszelesseg akkor nyilvan nem er el eleg adat a fogadohoz, ekkor valahogy ra kell birni a szervert, hogy nehany masodpercet ugorjon at, esetleg csokkentsen bitratat stb.stb. ez a nehez resze a feladatnak szerintem. Azon kivul lehet kis problema a TCP kapcsolattal is, de ezzel szerintem oprendszer szinten kell foglalkozni, puffermeretek beallitasa, utemezo algoritmusok beallitasa stb. Segitesz magadon, ha mind a ket oldalra egy eleg tetemes meretu buffert sikerulne beepitened, es igy kis kesleltetesert cserebe a felmerulo problemakat elore lathatod, es nem tuzolto munkaval kell majd a streamet rendberakni. mindenkeppen szukeged lesz ennek az elkeszitesehez ezekre:
vaw fileok megnyitasa, esetleg atkodolasa (mp3lame, oggvorbis remek libek, sok anyag letezik, ez nem gazos)
valamilyen halozati kapcsolat kezelese, en socketeket ajanlok, az eleg baratsagos dolog, rengeteg anyag
valamilyen szintu operacios-rendszer ismeretre a finomhangolashoz
sztem ennyi eleg is ;)
sok sikert, telleg szep feladat ;) -
Jester01
veterán
válasz
emitter #1397 üzenetére
Elvileg elég a virtuális hangkártya a szerverbe, de egyszerûbb egy full duplex hangkártyával ''felvenni'' a kimenõ hangot.
Olyan szinten lehet kompatibilitás, hogy a win által szolgáltatott streamet linuxon hallgathatod vagy fordítva. Viszont a feladat jelentõs része (értsd: hang kezelés) tök máshogy néz ki a 2 rendszeren. Szóval véleményem szerint a két platformra külön kell megírnod a progit. Bár lehetnek benne közös részek, pl. a magas szintû protokoll kezelése.
Szép feladat. -
c4-eXp
aktív tag
válasz
emitter #1389 üzenetére
Nekem az első linkelt van meg, sztem korrekt kis könyv, ha csak az alapok kellenek, akkor tökéletesen megfelelel. A 3. linkelt könyvet nemrég vette meg a barátom. Azt mondta rá, hogy jó, viszont más stílusú, mint az első. Ha kifejezetten a c++ nyelvet akarod elsajátítani, akkor sztem az elsőt válaszd. A másik könyv asszem már feltételez egyfajta előismeretet, és inkább a programozási módszereket, praktikákat, trükköket részesíti előnyben. Inkább ilyen gyakorlati féle könyv. Tulajdonképpen a kettő együtt a legjobb, mivel kiegészítik egymást. A Stroustrup féle könyv pedig szerintem felesleges, ha csak az alapok kellenek.
-
Jester01
veterán
válasz
emitter #1334 üzenetére
Igen, ez alap linuxon. A bemenet soronként pufferelt és echo módban van.
Használd a wincon.h-t, azért írtam
A terminálkezelõ curses könyvtár átkapcsolja a bemenetet és van benne getch is.
Egy kicsit módosítani kellene a headert, mert az inicializálás eléggé igénytelen módon az aknakeresõ progidhoz van illesztve (ha jól emlékszem arra épít, hogy az elsõ hívás egy képernyõtörlés lesz.) -
emitter
őstag
válasz
emitter #1323 üzenetére
najó elég béna voltam, nem godnolkoztam
szóval müxik, de nem teljesen úgy ahogy én akarom:
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
int
input_timeout (int filedes, unsigned int seconds)
{
fd_set set;
struct timeval timeout;
/* Initialize the file descriptor set. */
FD_ZERO (&set);
FD_SET (filedes, &set);
/* Initialize the timeout data structure. */
timeout.tv_sec = seconds;
timeout.tv_usec = 0;
// select returns 0 if timeout, 1 if input available, -1 if error.
return select (FD_SETSIZE,
&set, NULL, NULL,
&timeout);
}
int
main (void)
{
int i=0;
while(i<10)
{
if( input_timeout(STDIN_FILENO, 1) )
{
printf(''gomnyomas tortent '');
printf(''%d\n'',i);
i++;
}
else
{
printf(''%d\n'',i);
i++;
}
}
return 0;
}
ugyanis pl. 3 mp-ig várok, ok, számol 3-ig
aztán nyomok 1 entert, ekkor azt kéne kiírnia, h ''gomnyomas tortent 4''
majd kéne tovább számolnia, nem?
ehelyett ezt írja:
gomnyomas tortent 4
gomnyomas tortent 5
gomnyomas tortent 6
gomnyomas tortent 7
gomnyomas tortent 8
gomnyomas tortent 9
és mindezt 1 pillanat alatt, mintha már nem számolna a timeout
mit rontottam el -
Jester01
veterán
válasz
emitter #1323 üzenetére
azt mondtad h szedjem ki a temp_failure-t, hát kiszedtem, de így meg a select ha jól látom, nem is hívódik meg sehol
Persze, mert azt is kiszedtedTalán azt hagyd benne, a return-nel egyetemben.
return select (FD_SETSIZE, &set, NULL, NULL, &timeout));
Már most nem tudom hogyan magyarázzam, ha az elõzõt nem értetted.
Na még egy próba.
Nézzük onnan, hogy mit szeretnél:
1. Ha a felhasználó megnyom egy gombot, akkor arra reagálni akarsz.
2. Másodpercenként kiírni az idõt.
3. Közben nem terhelni a processzort.
A 3. pont miatt meg kell mondani az operációs rendszernek, hogy az 1. és 2. események bekövetkeztekor fusson a progi. Ezt például a select függvénnyel lehet, ami azt tudja, hogy figyel tetszõleges számú fájlleírót megadott ideig. Billentyûleütés akkor van, ha a stdin fájlból van mit olvasni. Ezt szépen meg lehet adni a select-nek. Sajnos azt viszont nem tudja, hogy másodpercenként térjen vissza akkor is ha nincs billentyûleütés, csak várakozási idõt lehet neki megadni. Ezért a 2. pontot kicsit át kell fogalmazni, mégpedig úgy, hogy nem azt mondod, hogy másodpercenként, hanem azt, hogy a következõ másodpercig. Ezt pedig úgy csinálod, hogy minden frissítésnél illetve a select meghívása elõtt lekéred az idõt (a gettimeofday függvénnyel, mert kell a pontosság!) és a timeout értéket ebbõl számolod, értelemszerûen: timeout = elõzõ frissítés + 1mp - aktuális idõ.
A select visszatérési értéke elárulja, hogy az 1. vagy a 2. feltétel következett-e be, vagyis a felhasználó megnyomott egy gombot (ekkor getch() és eseménykezelés) vagy pedig a várakozási idõ járt le (ekkor idõ frissítése kell.). -
Jester01
veterán
válasz
emitter #1316 üzenetére
5?
Azt ne írja már ki ...
nem kaptam választ arra, h mi is az a file-descriptor
Pontosan az, amit írtál.Egy szám amivel alacsony szinten fájlokra lehet hivatkozni. A 0,1,2 sorban az stdin, stdout és stderr, de ezekre van makró. (STDIN_FILENO & co)
A select akkor tér vissza ha valamelyik fájlon a kért írás vagy olvasás elvégezhetõ avagy a timeout letelik. Jelen esetben arra használjuk, hogy térjen vissza ha történt gombnyomás (vagyis ha az stdin-rõl van mit olvasni) vagy letelt a következõ frissítésig hátralévõ idõ. -
Jester01
veterán
válasz
emitter #1309 üzenetére
A TEMP_FAILURE_RETRY gondolom csak egy kis makró volt, ami addig próbálja a selectet amíg 0-t vagy 1-et ad vissza (vagyis nem hibát). Neked ez eleve nem jó, mert majd újra kell számolni a timeout-ot. Szóval simán hagyd el.
Úgy kell használni, hogy nyilvántartod mennyi idõ múlva esedékes a következõ frissítés, ez lesz a timeout értéke az input_timeout hívásban (kicsit át kell alakítani, hogy ne csak másodperceket tudjon). A filedes az az STDIN_FILENO, ahogy a példában is van. Megvizsgálod az input_timeout visszatérési értékét: ha 0 akkor timeout miatt tért vissza, vagyis az idõt kell kiírni. Ha 1 akkor a felhasználó nyomott egy billenytût amit nyugodtan beolvashatsz a getch()-val, már nem fog blokkolni.
Ezután lekéred az idõt, újraszámolod a timeout értékét és ismét mehet a select. Ne a time() függvényt használd, mert nagyobb pontosságra van szükség, hanem a gettimeofday-t. -
emitter
őstag
válasz
emitter #1309 üzenetére
egyébként nem is fordul a példakód, ezt dobja:
emitter@LAPTOP:~$ gcc -Wall -o time_select time_select.c
time_select.c: In function ‘input_timeout’:
time_select.c:21: warning: implicit declaration of function ‘TEMP_FAILURE_RETRY’
/tmp/cck7Ph7m.o: In function `input_timeout':
time_select.c: (.text+0x73): undefined reference to `TEMP_FAILURE_RETRY'
collect2: ld returned 1 exit status
emitter@LAPTOP:~$
mod: auto szmálji-konverzió
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1305 üzenetére
info libc, 13.8 Waiting for Input or Output. [link]
Az a lényeg, hogy olyan select hívást használj ami addig blokkol amíg nem lehet olvasni az stdin-t és nem múlik el a következõ frissítés idõpontja. (Ott a példa a doksiban)
Miracle, nyugodtan segíts ám te is, és szólj ha hülyeségekre biztatom Emittert -
-
emitter
őstag
válasz
emitter #1299 üzenetére
hát télleg nagyon béna voltam, úgylátszik kicsit elszoktam a kódolástól, de mostantól megint belejövök
szal csak simán át kellett konvertálni int-be a time_t-t
és sikerült megoldani a másodperc-számlálást mindenféle delay nélkül:
#include <time.h>
#include <stdio.h>
int main()
{
int i, kezdo, akt, t;
kezdo=t=(int)time(NULL);
printf(''Kezdo ido: %d\n'',kezdo);
i=0;
while(1)
{
akt=(int)time(NULL);
if(akt!=t)
{
t=akt;
printf(''%d\n'',akt-kezdo);
i++;
}
if(i==5) break;
}
printf(''Press any key!'');
getchar();
return 0;
}
akkor most ezzel a megpróbálom megcsinálni az aknakeresőm idő-számlálóját
mod: Jester01: azért figyeled az 5 századmásodperces hsz-időkülönbségünket
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1299 üzenetére
A time_t az nem objektum, hanem pont az ami neked kell
info libc:
''it represents the number of seconds elapsed since 00:00:00 on January 1, 1970.
[...] In the GNU C library, `time_t' is equivalent to `long int'. In other systems, `time_t' might be either an integer or floating-point type.''
De hiszen ezt te magad is használtad már. -
Jester01
veterán
válasz
emitter #1293 üzenetére
vmi az ascii-kódokkal sincs rendben: csillagokat kéne írnia
Ja. A wincon.h-ban felveheted a leképezõ táblázatba.
az időszámlálóra visszatérve, szerinted nem fog menni a többszálúsággal
Mármint a windows-os többszálúságra gondoltam, hogy azt már nehéz lenne így transzparensen emulálni. Aztán lehet, hogy mégsem olyan ördöngõsség: a timer_create környékén nézelõdj. -
Jester01
veterán
válasz
emitter #1288 üzenetére
vsscanf meg nincs deklarálva...
Igen, úgy látom, hogy az feltételesen van csak benne az stdio.h-ban, csak C99 módban látszik. Szóval vagy be kell kapcsolni (most hirtelen nem is tudom mivel) vagy a vsscanf prototípust kell megadni (és nem az emul_scanf-et, amit te csináltál).
milyen ftp-klienst tudnál ajánlani, ami gyors és könnyen használható?
Midnight Commander? -
Jester01
veterán
válasz
emitter #1279 üzenetére
szóval itt ez a wincon.h, akkor ezt hova is másoljam be
Mindegy, a -I kapcsolóval mondhatod meg, hová tetted. A példámban a main.c mellett volt, ezért van a -I után pont.
a progim használ egy olyat, h windows.h, azzal mi lesz
Semmi, csinálj egy üres fájlt. Vagy szedd ki a forrásból. Vagy tedd be #ifndef __linux__ közé.
és akkor így kell fordítanom majd: make -funsigned-char -lm -lncurses -I main.c ugye?
Most éppen nem tudom milyen környezetet használsz, simán parancssorból a gcc -Wall -funsigned-char -lm -lncurses -I. -o main main.c lefordítja. -
Jester01
veterán
válasz
emitter #1274 üzenetére
Halló, megjöttem
A kódodon nem kellett sokat (semmit) átírni, mert csináltam egy kis headert
[link] ami leképezi a windowsos hívásokat linuxosra. Mivel leginkább konzol kezelésrõl van szó, így ez wincon -> curses leképezésrõl szólt. A többszálú idõméréssel nem tud mit kezdeni. Fordítani -funsigned-char -lm -lncurses -I. kapcsolókkal kell.
Persze ha eleve úgy fog neki valaki progit írni, hogy platformfüggetlen legyen, akkor nem ezt az utat választja. -
Miracle
senior tag
válasz
emitter #1268 üzenetére
miert gondolod, hogy a windows.h, es a benne deklaralt fuggvenyek hasznalata teljesen normalis linux alatt? ;)
ha linux alatt fejlesztesz C nyelven akkor http://www.gnu.org/software/libc/manual/ ezzel erdemes elkezdeni, ez a glibc, azaz Gnu C Library, sok sok fuggveny. felulrol kompatibilis POSIX .. SUS3 szabvanyokkal, ez az egyik legjobban hasznalhato linux API. ha szempont, hogy a kodod mas oprendszerek alatt is mukodjon akkor szoritkozz azokra a fuggvenyekre, amik a POSIX vagy a SUS3 szabvanyokban vannak definialva, ez minden fuggvenynel le van irva. Ha platformfuggetlen kodot szretnel akkor masik lehetseges megoldas, hogy nem a Glibc hanem a www.unix.org -on elerheto SUS3 doksit vagy ha meg portabilisebb akarsz lenni akkor a POSIX-re valo szoritkozassal a kodod VMS es windows alatt is mukodokepes marad(ha most kezdesz foglalkozni ezzel akkor ez a kategoria is boven eleg, de posix doksit eleg nehez talalni a neten). a nativ linux api hasznalata csak akkor javasolt ha hiperszuperhatekony kodot szeretnel alkotni, de ha most kezdesz ezzel foglalkozni akkor ezt meg 1-2 evig ne nagyon peddzegesd mert eleg durva dolgokkal talalkozhat szembe az ember, egy kis tapasztalat szukseges hozza. -
cucka
addikt
válasz
emitter #1269 üzenetére
esetleg megpróbálhatod értelmezni a hibaüzeneteket.
pl rengeteg helyen van ilyen hiba:
main.c:61: error: ‘HANDLE’ undeclared (first use in this function)
azaz nincs deklarálva HANDLE nevű változó/függvény, mégis használni szeretnéd
nem találja a windows.h és wincon.h fileokat, meg kéne nézni, hogy ott vannak-e egyáltalán
többi hibaüzenetről forráskód nélkül nehéz bármit is mondani -
Jester01
veterán
válasz
emitter #1228 üzenetére
Lehet
make main (ha jól emlékszem main.c-nek hívják a progidat)
Még makefile sem kell hozzá, elég a beépített default.
Nézegesd a projekt beállításokat, valahol biztos ott van a használni kívánt fordító. A logot meg lökd fel a webre, megnézem. Jöhetsz ám msn-re is ha van kedved. -
Jester01
veterán
válasz
emitter #1185 üzenetére
A Sleep-et vedd ki, az jelképezte a programot (''Do other useful work here'')
A DeleteTimerQueue pedig kilépéskor kell, amikor már nem akarod, hogy fusson a másik szál.
MOD: majd nem használhatsz printf-et az idő kiírásnál, mert elállítja a kurzorpozíciót.
Helyette pl. a WriteConsoleOutput függvényt használhatod.
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1181 üzenetére
Fejleszted? Király
Sajna neked egy getch()-t tartalmazó ciklusod van, ami bizonytalan ideig blokkolja a futási szálat, szóval folyamatos kiírást csak másik szálon tudsz csinálni. Szerencsére ez nem olyan nehéz [link] Az eventes dolog az neked nem kell. Gyakorlatilag csak egy CreateTimerQueue() és egy CreateTimerQueueTimer hívás, ahol ez utóbbinak megadod a függvény címét ami kiírja az időt. Mivel ez másik szálon fut az a legegyszerűbb, ha kap egy külön helyet a képernyőn amit csak ő használ így nem akad össze a fő szállal.
Amúgy a kódod kis módosítással nekem működik. A time(&t1) hívás a diff előtt inkább egy t1 = t2 értékadás. Az 500000 meg nevetségesen kis szám
MOD: Gyere msnre ha akarsz
[Szerkesztve] -
Jester01
veterán
válasz
emitter #1179 üzenetére
Milyen környezetben és mi a pontos elvárás?
Szinkron módon egyszerűen megvárod a következő másodpercet (Sleep) vagy gyakorta ellenőrzöd, hogy eltelt-e már egy másodperc.
Ha közben hosszabb dolga van a programnak, akkor valami aszinkron megoldás kell (időzítő, többszálúság, ...) -
Miracle
senior tag
válasz
emitter #1166 üzenetére
osztálytársam az Elte-re ment infóra, eddig nem sok örömöt lelt benne
aztmondta h van 6-féle matekjuk komoly! mindegyikből vizsga
és most 1. félévben még nem is tanulnak progot mindenesetre érdekes
hat ehhez ha nem haragszol hozzaszolok mert egy elsoeves alapjan aki a beszamolo szerint azok koze tartozik akik rossz helyre jottek nem biztos hogy jo megitelni a szakot.
Apro kis intermezzo, hogy a progmat kepzes iden indult utoljara, es a proginfo veszi at a helyet, ami 3 szakirannyal megy, az egyik nagyjabol annyi matekkal mint a progmat, aztan egy masik 5 eves joval kevesebb matekkal, ez is 5 eves, aztan a harmadik szakirany kb annyi matekkal mint a muinfo(rossz nyelvek szerint az volt a viszonyitasi alap amikor keszitettek a tantervet), es ez 3 eves.
tehat elso evben valoban eleg kemeny a matematika, de ez 2. evtol valtozni fog, es 3. evtol kb annyit ulsz majd gep elott hogy mar elkepesztoen unni fogod. ha kifejezetten programozassal akarsz foglalkozni, akkor pesten nem igazan van ennel komolyabb alapokat nyujto kepzes. persze sok a matematika eleinte, de nekem most 3. evben 1 darab targyam van ami matek, meg lenne meg egy, ha nem csusztam volna el belole elozo evben, meg van megegy, de azon csak nevetni lehet, ilyen toltelektargy szinvonal.
az alapveto problema egyebkent az a rinyalos golyakkal, hogy nem kepesek elolvasni a felveteli tajekoztatot, bele van[volt] irva, hogy programtervezo matematikus. itt jegyeznem meg hogy a rendes es az alkalmazott matematikusokhoz kepest nagyon minimalis a mi matematikank, nagyjabol az 1/10-e es az 1/15-e koze saccolnam(a valaszthato savok nelkul, azokkal mar joval tobb tud lenni), a szakunkra jellemzo ,,speci matematika'' (programozas matematikai modellje) egyutt. szoval ez nem egy olyan teljesithetetlen szint. persze ha valakinek semmi kedve nincs foglalkozni a matekkal, akkor nem fog atmenni a gyakokon, es a vizsgakon, ez is egyetem, es raadasul nem is konnyu, tanulni kell. Arrol nem is beszelve, hogy kulonbozo tomoritesi, es kodolasi algoritmusok eppen arra a matematikara epulnek, amit elso masfel evben belevernek az oktatok a fejunkbe, csak ezt nem nagyon reklamozzak, igazabol nem tudom hogy miert. ez a szak tobbek kozott errol is szol.
na nem akartam itt most nagy eszosztasba kezdeni de eszmeletlenul felbosszant amikor hulyesegeket olvasok a sajat szakomrol, es tobbsegeben azoktol a golyaktol akik rossz helyre jottek. (ebben az egyetem is hibas, progmatos ismeros nelkul nem nagyon lehet megtudni hogy ugyan mirol is van szo ezen az kepzesen)
es semmikepp sem akartalak eltantoritani a szomszedos egyetemtol[BME] vagy akarmelyik masiktol, nem ez volt a celom. -
c4-eXp
aktív tag
válasz
emitter #1166 üzenetére
Nah, hát akkor még könnyen lehet, hogy egy egyetemre fogunk járni.
Csak ahhoz még kéne írnom egy jó matek, meg fizika emelt szintűt.
Eddig nagyon úgy voltam vele, hogy a BME-re szeretnék menni műszaki infóra, de most kicsit elbizonytalanodtam, mivel számításba jött a programtervező matematikus szak Szegeden. Az Eltére tuti nem jelentkezek, én is hallottam róla, hogy nagyon durva szinten nyomják a matekot, és hogy 1. évben szinte semmi programozás nincsen (részvétem az osztálytársadnak
). Szóval még eléggé kétesélyes a dolog, pénteken megyek Szegedre nyílt napra, kíváncsi vagyok milyen kedvcsináló lesz ott.
Viszont ez tetszik, amit leírtál a BME-ről, pl. hogy már nem oktatnak Pascalt, hanem egyből a C#/C++ nyelvet nyomatják. Valamint a Java is jó, és ezek legalább olyan dolgok, amikkel tudsz is majd mit kezdeni később.
Egyébként az ELTE Radnóti Miklós Gyakorlóiskolába járok, nem rossz suli, bár inkább humán beállítottságú. Mondjuk azért a biológia, meg fizika tanárok elég jók. Most büszke is vagyok magamra, mert valszeg továbbjutok fizika oktv-n a 2. fordulóba.Te hova jártál?
-
Jester01
veterán
-
Jester01
veterán
válasz
emitter #1156 üzenetére
Az aknaz lényegi része valahogy így kellene kinézzen:
for(i=0;i<max_aknak; ) //aknák véletlen elhelyezése
{
int dx, dy;
int cx, cy;
j=rand()%my; //az aknák koordinátája 0,my és 0,mx között lehet
k=rand()%mx;
if(mezo[j][k].akna==0) //ha az adott mezõn már van akna, nem rakunk oda
{
mezo[j][k].akna = 1;
i++;
for(dy = -1; dy <= 1; dy++)
{
cy = j + dy;
if (cy >= 0 && cy < my)
{
for(dx = -1; dx <= 1; dx++)
{
cx = k + dx;
if ((dy != 0 || dx != 0) &&
cx >= 0 && cx < mx)
{
mezo[cy][cx].szomsz++;
}
}
}
}
}
}
A feltárós résznél nem igazán értem, hogy akkor most miben mit számolsz, de úgy sejtem, hogy egy ilyen módosítással jó lehet:
if (mezo[x][y].mark == -1)
{
(*mezoszam)++;
} else {
mezo[x][y].mark = -1;
(*maradt)++;
}
És ez nem kell a hívás elõtt:mezo[j-1][i-1].reveal=1;
mezo[j-1][i-1].mark=-1;
mezoszam++;
A mezoszam felteszem a feltárt vagy megjelölt mezõket számolja. Vagyis az automatikus feltárásnál csak akkor kell növelni, ha nem megjelölt mezõt tárunk fel, hiszen az már egyszer meg lett számolva. Viszont ha már meg volt jelölve, akkor most töröljük a jelölést, hiszen tudjuk, hogy nincs ott akna. Emiatt azonban a maradt változót növelni kell. Amúgy ez a +1/-1 a mark esetén elég sok fejfájást okozott nekem. Mostmár nehogy átírd, de a többi helyen használt 0/1 jobb lett volna.
MOD: szöveg jó, kód rossz[Szerkesztve]
-
Jester01
veterán
válasz
emitter #1150 üzenetére
Segítség, megerőszakolták a függvényemet!
A temp az egy pointer lenne, tessék szépen kiírni a csillagokat.
Teljesen fölösleges minden hívásnál az egész táblát végigellenőrizni, hiszen elég csak az aktuális cellát vizsgálni.
És a harmadik: a hívás után közvetlenül van egy goto jatek; szóval sosem fogja figyelembe venni a temp kiszámított értékét, amit úgyis újraszámolsz. Ráadásul a maradt változót és a kiírást sem frissíted és a megjelölést sem szünteted meg. -
Jester01
veterán
-
Jester01
veterán
-
Jester01
veterán
-
emitter
őstag
válasz
emitter #1142 üzenetére
közben sikerült minden színt kikevernem:
#define color_white SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY)
#define color_lightgray SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED)
#define color_gray SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_INTENSITY)
#define color_black SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), )
#define color_red SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED|FOREGROUND_INTENSITY)
#define color_darkred SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_RED)
#define color_lime SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_INTENSITY)
#define color_green SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN)
#define color_blue SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define color_darkblue SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE)
#define color_navyblue SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_BLUE
#define color_cyan SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_BLUE|FOREGROUND_INTENSITY)
#define color_fuchsia SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE|FOREGROUND_RED)
#define color_purple SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_BLUE|FOREGROUND_RED|FOREGROUND_INTENSITY)
#define color_brown SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_RED)
#define color_yellow SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), FOREGROUND_GREEN|FOREGROUND_RED|FOREGROUND_INTENSITY)
sztem ennyi az összes lehetséges kombináció
azért csodálkozom, h C-ben ennyire alapszinten kezelik a színeket... pascalban simán rendelkezésre állt az összes szín...
Új hozzászólás Aktív témák
Hirdetés
● olvasd el a téma összefoglalót!
- Nagyon erős ajánlattá kezd válni a SteamOS
- Macska topik
- Renault, Dacia topik
- Trollok komolyan
- WoW avagy World of Warcraft -=MMORPG=-
- Honor Magic6 Pro - kör közepén számok
- Debrecen és környéke adok-veszek-beszélgetek
- Anime filmek és sorozatok
- Vezetékes FEJhallgatók
- Csak semmi szimmetria: flegma dizájnnal készül a Nothing Phone (3)
- További aktív témák...
- Lenovo Ideapad 330S-15IKB / I5 /20GB RAM / GTX 1050 / M.2 SSD
- Gamer PC - i3 12100f, RTX 3070 és 16gb DDR5 + GARANCIA
- Lenovo ThinkPad T14 Gen 5 Ultra-I7/64GB/512SSD/Érintőképernyő/garancia
- Lenovo ThinkPad T14 G3 I5-1245U/32GB/1TBSSD/Érintőképernyő/Garanciás.
- Dell Precision Munkaállomás 7750 17.3" i7-10850H/32GBRAM/1TBSSD/RTX3000/WIN11PRO
- ALIENWARE Area-51 R6 Threadripper Edition 1920X
- Bomba ár! Fujitsu LifeBook U758 - i5-8GEN I 8GB I 256GB SSD I HDMI I 15,6" FHD I W11 I Garancia!
- ÁRGARANCIA!Épített KomPhone Ryzen 9 5900X 16/32/64GB RAM RTX 5070 12GB GAMER PC termékbeszámítással
- Azonnali készpénzes AMD Radeon RX 5000 sorozat videokártya felvásárlás személyesen / csomagküldéssel
- Samsung Galaxy A54 128GB, Kártyafüggetlen, 1 Év Garanciával
Állásajánlatok
Cég: Promenade Publishing House Kft.
Város: Budapest
Cég: CAMERA-PRO Hungary Kft
Város: Budapest