c programmeren opdracht

Pagina: 1
Acties:

Vraag


Acties:
  • 0 Henk 'm!

  • sadiek
  • Registratie: Januari 2017
  • Laatst online: 04-03 18:13
Beste mensen,

Ik heb een opdracht in programmeren in C. en ik kom er totaal niet uit.
Iemand hulp?
Dit is de opdracht:

Creëer een programma dat van een willekeurig bestand een exacte kopie maakt:
a) Maak uitsluitend gebruik van fopen(), fclose(), fread() en fwrite()
functies!
b) Maak gebruik van argv en argc voor het opgeven via de commandoregel van de namen
van de bron- en bestemmingsbestanden. (Tip: gebruik in CodeBlocks Project -> Set
Program’s Arguments om je programma met argumenten te kunnen uitproberen
zonder elke keer een Windows CMD opdrachtprompt venster te moeten openen)
c) Programmeer defensief: test altijd op juiste argv en argc waarden, en de return waarden
van de file IO functies. Bij foutwaarden, geef een relevante foutmelding alvorens het
programma te beëindigen
d) Let er op dat het programma goed werkt voor elk type file (binaire en tekst) van
willekeurige lengte. Test (heel) kleine en (heel) grote files. Test het ook via de Windows
commando regel uit. 8)7 8)7 8)7 8)7

Alle reacties


Acties:
  • +1 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Wij gaan niet je opdracht voor je maken, daar leer je niks van. Zie ook De Quickstart.

Waar kom je niet uit? Wat lukt je precies niet? Wat lukt je wel? Welke fouten krijg je?

[ Voor 13% gewijzigd door NMe op 10-06-2018 16:03 ]

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • TripleQ
  • Registratie: Juni 2004
  • Niet online
sadiek schreef op zondag 10 juni 2018 @ 15:57:
en ik kom er totaal niet uit.
Waar loop je op vast dan?
Probeer hier eens uit te leggen wat je al geprobeerd hebt en wat er niet werkte.
Ik neem aan dat je een boek over de stof hebt, of anders gezocht hebt naar voorbeelden.

Verwachte overigens niet dat wij je huiswerk gaan maken... Je zult het echt zelf moeten doen

[Edit]
Met hierboven dus :Y)

[ Voor 3% gewijzigd door TripleQ op 10-06-2018 16:03 ]


Acties:
  • 0 Henk 'm!

  • Liveshort
  • Registratie: Februari 2011
  • Laatst online: 18-07 17:30

Liveshort

Certified Crazy Person

Waar loop je vast? Lukt het al om een simpel hello world programmatje te compilen en te draaien? Vanaf daar kun je de opdracht in stukken aanpakken: begin eens met het maken/openen van een file waarvan je het pad hardcoded in je source file hebt staan. Probeer er eens wat naartoe te schrijven en bekijk de resulterende file, probeer dan die file weer eens in te lezen en te printen in je terminal, ga daarna eens kijken naar hoe argc en argv te gebruiken zijn. Mogelijkheden genoeg.

Onthoud: Google (en vooral stackoverflow) is je vriend!

There once was a lady of Wight --- Who travelled much faster than light --- She departed one day --- In a relative way --- And arrived on the previous night


Acties:
  • 0 Henk 'm!

  • sadiek
  • Registratie: Januari 2017
  • Laatst online: 04-03 18:13
ik zat te denken aan:

twee files openen, 1 in read mode die gekopieerd moet worden en de tweede in write mode om daar naartoe te kopieren.
Vervolgens een while lus met fgetc om de characters te kopieeren naar een char tot EOF.
en daarvanuit fputc naar de tweede write file.

alleen de opdracht geeft aan dat ik fgetc en fputc niet mag gebruiken? met welke functies kan het dan nog.

Daarnaast argc en argv:
argc telt het aantal strings die ik invoer
en argv slaat de strings op
Hoe koppel ik dit aan windows dat ik vanuit cmd kan zeggen "kopieer dit bestand en plak het in dit bestand"

Ik heb me er echt wel even in verdiept hoor, jullie zijn mijn laatste redmiddel :D

Acties:
  • 0 Henk 'm!

  • eric.1
  • Registratie: Juli 2014
  • Laatst online: 13:52
sadiek schreef op zondag 10 juni 2018 @ 16:16:
ik zat te denken aan:

twee files openen, 1 in read mode die gekopieerd moet worden en de tweede in write mode om daar naartoe te kopieren.
Vervolgens een while lus met fgetc om de characters te kopieeren naar een char tot EOF.
en daarvanuit fputc naar de tweede write file.

alleen de opdracht geeft aan dat ik fgetc en fputc niet mag gebruiken? met welke functies kan het dan nog.

Daarnaast argc en argv:
argc telt het aantal strings die ik invoer
en argv slaat de strings op
Hoe koppel ik dit aan windows dat ik vanuit cmd kan zeggen "kopieer dit bestand en plak het in dit bestand"

Ik heb me er echt wel even in verdiept hoor, jullie zijn mijn laatste redmiddel :D
Hoe je dit aan kan pakken;
1. Zoek letterlijk op wat die vier functies doen.
(https://www.tutorialspoin...ary/c_function_fwrite.htm b.v.)

2. Begrijp hoe ARGV werkt
(argv is niets meer dan een array van meegegeven parameters, te gebruiken als argv[1], argv[2] voor je 1e en 2e argument)

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
sadiek schreef op zondag 10 juni 2018 @ 16:16:

Ik heb me er echt wel even in verdiept hoor
Dat durf ik hardop te betwijfelen:
sadiek schreef op zondag 10 juni 2018 @ 16:16:

alleen de opdracht geeft aan dat ik fgetc en fputc niet mag gebruiken? met welke functies kan het dan nog.
Je hebt welgeteld 4 functies gekregen waar je het mee moet doen waaronder een fread en fwrite. Goh, waar zou het toch mee moeten 8)7

Als je je vediept had had je op z'n minst die 4 functies opgezocht.

[ Voor 6% gewijzigd door RobIII op 10-06-2018 17:28 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • sadiek
  • Registratie: Januari 2017
  • Laatst online: 04-03 18:13
afijn, ik heb het volgende.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main(int argc, char argv) {

FILE *fp1, *fp2;
int array [10], ;

    fp1 = fopen("read.txt", "r");
    if (fp1 == NULL)
    {
        fprintf(stderr, "Error opening read file.");
        exit(1);
    }

    fp2 = fopen("schrijven.txt", "w");
    if (fp2 == NULL)
    {
        fprintf(stderr, "Error opening schrijf file.");
        exit(1);
    }

    fread(array, sizeof(int),10,fp1);
    fwrite(array, sizeof(int),10,fp2);

    return 0;
}

dit programma kopieerd de tekst uit fp1 naar fp2 maar hij kopieerd er ook nog dit bij: bwÄ[gw@ ”ÿ( î@ @ øDL << wat is dat en hoe krijg ik het weg?

Acties:
  • 0 Henk 'm!

  • Liveshort
  • Registratie: Februari 2011
  • Laatst online: 18-07 17:30

Liveshort

Certified Crazy Person

sadiek schreef op zondag 10 juni 2018 @ 17:54:
afijn, ik heb het volgende.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int main(int argc, char argv) {

FILE *fp1, *fp2;
int array[10], ;

    fp1 = fopen("read.txt", "r");
    if (fp1 == NULL)
    {
        fprintf(stderr, "Error opening read file.");
        exit(1);
    }

    fp2 = fopen("schrijven.txt", "w");
    if (fp2 == NULL)
    {
        fprintf(stderr, "Error opening schrijf file.");
        exit(1);
    }

    fread(array, sizeof(int),10,fp1);
    fwrite(array, sizeof(int),10,fp2);

    return 0;
}


dit programma kopieerd de tekst uit fp1 naar fp2 maar hij kopieerd er ook nog dit bij: bwÄ[gw@ ”ÿ( î@ @ øDL << wat is dat en hoe krijg ik het weg?
Als je code op het forum wilt zetten kun je daar het beste de [code] tags voor gebruiken.

Wat betreft je errors, waarom lees je ints uit de file en niet gewoon byte voor byte (mbv een char array ipv een int array bijvoorbeeld)? Ints zijn namelijk meestal vastgelegd door 4 of 8 bytes afhankelijk van je systeem. Dan lees je dus 4 keer zoveel als je wilt lezen. Verder kan dit stuk code ook niet omgaan met files van verschillende grootte en meen ik dat het voor files de bedoeling is dat je eerst het begin van de file fseek't (zou je even na moeten zoeken)

[ Voor 21% gewijzigd door Liveshort op 10-06-2018 18:05 ]

There once was a lady of Wight --- Who travelled much faster than light --- She departed one day --- In a relative way --- And arrived on the previous night


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
@sadiek een bestand bestaat uit bytes en een byte staat gelijk aan een char, niet aan een int.
Een bestand is ook bijvoorbeeld 54 bytes. Je kan dus 5x 10 bytes lezen, maar de laatste keer kan dat niet.
argv is een array of char pointers, niet een char.

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
sadiek schreef op zondag 10 juni 2018 @ 17:54:
dit programma kopieerd de tekst uit fp1 naar fp2 maar hij kopieerd er ook nog dit bij: bwÄ[gw@ ”ÿ( î@ @ øDL << wat is dat en hoe krijg ik het weg?
  • Zoals al aangegeven: een array van ints is wellicht niet het handigste type.
  • Ik mis een while (of andere) loop?
  • fread heeft een return value (het aantal bytes gelezen); zoals aangegeven: je kunt wel in blokken van 10 (of 100, of 1000 of 761 of...) lezen en schrijven, maar als je bestand geen exacte veelvoud van die blokgrootte is zul je dus iets met die return value moeten doen. Aangenomen dat je file 54 bytes groot is in je in blokken van 10 bytes lees zal fread dus, in een lus, de waardes 10, 10, 10, 10, 10, 4 returnen resp. En dan zul je dus ook resp. 10, 10, 10, 10, 10, 4 bytes moeten schrijven. En daarmee is meteen de 'rommel' in je file verklaard.
Verder zou ik gewoon eens beginnen met debuggen i.p.v. alles steeds voor te laten kauwen; daar leer je tenminste iets van. En als je 't dan toch wil "afkijken" kun je 't net zo goed Googlen; het is niet alsof dit rocket science is en niet al 2 miljard keer eerder gedaan. Het is vergeven van de kant-en-klare implementaties waar je van kunt afkijken. En als je dan niet gaat lopen copy/pasten maar probeert te doorgronden wat er gebeurt (zoals de return value van fread gebruiken zoals hierboven aangehaald) dan kom je er vast uit.

[ Voor 27% gewijzigd door RobIII op 10-06-2018 18:26 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • PageFault
  • Registratie: April 2002
  • Laatst online: 13:02
Aanvullend: het gaat denk ik niet om de meest optimale snelheid te halen: lees niet per 10 bytes, maar gewoon per byte. Dan heb je het gedonder niet met bestanden die geen veelvoud van 10 bytes zijn.

Acties:
  • +1 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
PageFault schreef op zondag 10 juni 2018 @ 20:54:
lees niet per 10 bytes, maar gewoon per byte.
Ja zeg, dan vergeet ie alsnog de return waarde 0 en/of feof te checken :+

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
PageFault schreef op zondag 10 juni 2018 @ 20:54:
Aanvullend: het gaat denk ik niet om de meest optimale snelheid te halen: lees niet per 10 bytes, maar gewoon per byte. Dan heb je het gedonder niet met bestanden die geen veelvoud van 10 bytes zijn.
Maakt praktisch geen bal uit. Windows leest die files toch per 4096 bytes uit, de C runtime weet dat, en dus is de enige overhead dat je fread() wat vaker aanroept. Maar dat is allemaal in-process, zonder OS bemoeienis of I/O.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Hangt toch van de clustergrootte af?
Naar mijn weten was vroeger de disk sector 512 en nu 4096, en de "standaard" block size 4K.
Maar.... een Mac heeft bijvoorbeeld 12K blokken en leest dus 12K en niet 4K zoals jij zegt.
En op NTFS met 16 TB en groter is het 8K, en bij 32 TB en groter is het 16K, etc. etc.
En op FAT32 8+ GB is het 8K en 16+ GB is het 16K
En op exFAT is 256+ MB 32K en 32+ GB is 128K
etc. etc. etc.

Zo veel bestandssystemen zoveel mogelijkheden :p

Je hebt wel een punt dat lezen in blokken van 4096 het gewenste "standaard" resultaat heeft, aangezien de rest niet vaak voorkomt.

Ik heb dan wel
C:
1
char buffer[4097];

Gewoon uit gewoonte om een overflow te vermijden, aangezien er functies zijn die een null termination doen.

[ Voor 18% gewijzigd door DJMaze op 11-06-2018 18:23 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • PageFault
  • Registratie: April 2002
  • Laatst online: 13:02
MSalters schreef op maandag 11 juni 2018 @ 17:11:
[...]

Maakt praktisch geen bal uit. Windows leest die files toch per 4096 bytes uit, de C runtime weet dat, en dus is de enige overhead dat je fread() wat vaker aanroept. Maar dat is allemaal in-process, zonder OS bemoeienis of I/O.
Dat maakt in zoverre heel erg veel uit, dat wanneer je dus blokken van 10 bytes op blijft lepelen, dat je vanzelf enkele bytes "random rotzooi" cadeau krijgt, zie ook de openings post van de TS!

Dat de meeste file systems gebasseerd zijn op sectoren en clusters en ook als zodanig ingelezen wordt, is voor de applicatie laag niet relevant.

Acties:
  • 0 Henk 'm!

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 13-09 00:05
@PageFault : Ik had het over de snelheid; daarvoor maakt het niet uit of je 1 danwel 10 bytes tegelijk uitleest.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Acties:
  • +1 Henk 'm!

  • Thralas
  • Registratie: December 2002
  • Laatst online: 06-10 21:22
RobIII schreef op zondag 10 juni 2018 @ 18:17:
fread heeft een return value (het aantal bytes gelezen);
Kleine correctie: de return value is het aantal items, niet bytes.

Acties:
  • 0 Henk 'm!

  • sadiek
  • Registratie: Januari 2017
  • Laatst online: 04-03 18:13
leuke discussie, uiteindelijk snapte ik er nog geen bal van en heb ik een C-mentor betaald om het me uit te leggen ;) solved

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Voor jou misschien ja, maar als je nou anderen die in de toekomst middels een zoekopdracht op dit topic stuiten ook meteen helpt:
2. Opgelost: Je hebt een probleemtopic geopend en het is opgelost. Post dan altijd op welke manier je het hebt opgelost. Op deze manier is het voor een volgende lezer ook makkelijker een oplossing te vinden. [...]
Wel zo sociaal dus als je even laat zien wat 't uiteindelijk geworden is.

[ Voor 6% gewijzigd door RobIII op 11-06-2018 21:38 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
Zijn antwoord is vast zoiets
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FILE *f_source = fopen("read.txt", "r");
if (!f_source) {
    fprintf(stderr, "Error opening source file.");
    return 1;
}

FILE *f_target = fopen("schrijven.txt", "w");
if (!f_target) {
    fprintf(stderr, "Error opening target file.");
    return 2;
}

char buffer[4097];
buffer[4096] = '\0';
size_t bytes_read;
while (0 < (bytes_read = fread(buffer, sizeof(char), 4096, f_source))) {
    if (fwrite(buffer, sizeof(char), bytes_read, f_target) != bytes_read) {
        fprintf(stderr, "Error writing to target file.");
        return 3;
    }
}

Maar beter is het om ook feof() en ferror() te gebruiken, maar dat mocht niet :)

Echter denk ik dat hij meer moeite heeft met het verwerken van argv.

[ Voor 5% gewijzigd door DJMaze op 11-06-2018 23:18 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • +1 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
DJMaze schreef op maandag 11 juni 2018 @ 23:13:
Zijn antwoord is vast zoiets
[...]
Echter denk ik dat hij meer moeite heeft met het verwerken van argv.
Heb je een glazen bol ofzo? Zullen we deze speculatie gewoon achterwege laten?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • ThomasG
  • Registratie: Juni 2006
  • Laatst online: 23-09 14:00
DJMaze schreef op maandag 11 juni 2018 @ 23:13:
Zijn antwoord is vast zoiets
C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
FILE *f_source = fopen("read.txt", "r");
if (!f_source) {
    fprintf(stderr, "Error opening source file.");
    return 1;
}

FILE *f_target = fopen("schrijven.txt", "w");
if (!f_target) {
    fprintf(stderr, "Error opening target file.");
    return 2;
}

char buffer[4097];
buffer[4096] = '\0';
size_t bytes_read;
while (0 < (bytes_read = fread(buffer, sizeof(char), 4096, f_source))) {
    if (fwrite(buffer, sizeof(char), bytes_read, f_target) != bytes_read) {
        fprintf(stderr, "Error writing to target file.");
        return 3;
    }
}

Maar beter is het om ook feof() en ferror() te gebruiken, maar dat mocht niet :)

Echter denk ik dat hij meer moeite heeft met het verwerken van argv.
Behalve dan dat deze code eigenlijk slecht is. Mocht er een fout optreden, worden de file handles niet gesloten (ze worden überhaupt niet gesloten). En de buffer een byte groter maken voor een null byte is onnodig, omdat fwrite met een size argument werkt en niet null-terminated is. Daarnaast gaat het fout met non-text bestanden omdat Windows een onderschijf heet tussen text en binary mode, en het standaard in text-mode staat.

Acties:
  • 0 Henk 'm!

  • Hydra
  • Registratie: September 2000
  • Laatst online: 06-10 13:59
Misschien wel handig om als een totale beginner om help vraagt niet relevant geneuzel over wat 'optimaal' is snel de kop ingedrukt wordt. Niet dat de TS echt z'n best gedaan heeft, maar zo jaag je mensen wel erg snel weg.

https://niels.nu


Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
ThomasG schreef op dinsdag 12 juni 2018 @ 09:04:
Behalve dan dat deze code eigenlijk slecht is. Mocht er een fout optreden, worden de file handles niet gesloten (ze worden überhaupt niet gesloten). En de buffer een byte groter maken voor een null byte is onnodig, omdat fwrite met een size argument werkt en niet null-terminated is. Daarnaast gaat het fout met non-text bestanden omdat Windows een onderschijf heet tussen text en binary mode, en het standaard in text-mode staat.
Klopt! Het is ook wat ik denk dat hij schrijft. Niet wat ik schrijf ;)
RobIII heeft wel gelijk dat ik niet moet speculeren.

[ Voor 4% gewijzigd door DJMaze op 12-06-2018 09:56 ]

Maak je niet druk, dat doet de compressor maar


Acties:
  • 0 Henk 'm!

  • sadiek
  • Registratie: Januari 2017
  • Laatst online: 04-03 18:13
Eigenlijk was ik al op een zeer goede weg.
Er ontbrak inderdaad nog een while loop die elke char leest met fread en schrijft met fwrite.
De read functie checkt niet op EOF maar op == 1.
en dan slechts alleen de argv en argc implementeren die argc checkt op 3 waarden omdat je 3 stukjes tekst moet invoeren anders werkt het niet.
en in codeblocks werk je met argumenten, daarin "declareer" je de bestanden.

Even als leek uitgelegd, ik ga nu weer verder met mijn tentamens, fijne dag nog en waarschijnlijk zien jullie mij wel weer terug met een stomme vraag ;)

Acties:
  • 0 Henk 'm!

  • DJMaze
  • Registratie: Juni 2002
  • Niet online
sadiek schreef op dinsdag 12 juni 2018 @ 21:35:
en waarschijnlijk zien jullie mij wel weer terug met een stomme vraag ;)
Vragen zijn niet stom, presenteerbladen zijn stom ;)

Maak je niet druk, dat doet de compressor maar

Pagina: 1