[C] Segmentation fault - enkel bij het uitlezen van C source

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo iedereen,
Ik moet noodgedwongen programmeren in C voor een project Algoritmen & Datastructuren (voor performantieredenen).

Ik ben (bij wijze van inleiding) begonnen met het schrijven van een aantal regels die een bestandje uitschrijven om de syntax wat herop te frissen.

Maar hierbij ben ik echter op iets vreemds gestoten. Omdat ik geen echte inputfiles had testte ik steeds met inputreader.c, de source (niet de header) van het uiteindelijke programmaatje.
Telkens als ik dat als argument doorgaf gaf hij een segmentation fault (core dumped). Heel frustrerend want bij elk ander bestand deed hij dat niet.

Nu zou ik graag willen weten hoe dat kan, heb ik geen rekening gehouden met eventuele niet-afdrukbare tekens? Maar dat verklaart ook niet waarom er een geheugenfout optreedt.

Hieronder de snippet:

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/* inputreader.c
   Project Algoritmen & Datastructuren 3
   Laatste update: 16/10/2010 
*/

#include "inputreader.h"


int main(int argc, char *argv[]) {
    /*
        For test purposes only
    */
    read_file(argc,argv);
}

void read_file(int argc, char *argv[]) {
    if(argc<2) {
        printf("Usage:  command [textfile]\n");
        printf("%s exited with exit code: %d\n",argv[0],1);
        exit(1);
    }
    FILE *zoekwoordfile = fopen(argv[1],"r+");
    if(zoekwoordfile==NULL) {
        printf("Foutief bestand, controleer of %s wel bestaat.\n",argv[1]);
        exit(1);
    }
    
    printf("Bestand gevonden. Start leesoperatie.\n");
    char line[2000];
    while(fgets(line, 20, zoekwoordfile)) {
        printf(line);
    }
}


Dit geeft de volgende output:
~/PROJECTDA3/src >../dest/projectda3.o inputreader.c
Bestand gevonden. Start leesoperatie.
/* inputreader.c
   Project Algoritmen & Datastructuren 3
   Laatste update: 16/10/2010
*/

#include "inputreader.h"


int main(int argc, char *argv[]) {
    /*
                For test purposes only
        */
        read_file(argc,argv);
}

void read_file(int argc, char *argv[]) {
        if(argc<2) {
        printf("Usage:  command [textfile]\n");
Segmentation Fault (core dumped)


Ik hoop van harte dat jullie mij verder kunnen helpen, want ik ben ten einde raad.

Met vriendelijke groeten & alvast bedankt

Acties:
  • 0 Henk 'm!

  • Emmeau
  • Registratie: Mei 2003
  • Niet online

Emmeau

All your UNIX are belong to us

ga eens kijken wat *argv[] betekent in main, en hoe je dat moet gebruiken in je code.

ik doel op regel 13, read_file(argc,argv);

[ Voor 21% gewijzigd door Emmeau op 16-10-2010 20:29 ]

If you choose to criticise you choose your enemies


Acties:
  • 0 Henk 'm!

Verwijderd

Je gebruikt op regel 31 printf, maar niet helemaal zoals zou moeten:
C:
1
printf ("%s", line);

Dit zou wel werken.

Jij voert namelijk met regel 19 een string in die % bevat. %s en %d om precies te zijn. Er zijn echter niet genoeg argumenten voor printf, want die verwacht een extra argument om voor %s in te vullen, en dan nog een om %d te vullen.

Snap je wat er misgaat? :)

Met mijn regel gaat het wel goed, hij vult de letterlijke tekst in op de plaats van %s in het eerste argument. Hierdoor maken de bijzondere tekens in de input niet meer uit.

[ Voor 19% gewijzigd door Verwijderd op 16-10-2010 20:30 ]


Acties:
  • 0 Henk 'm!

  • CoolGamer
  • Registratie: Mei 2005
  • Laatst online: 20-09 15:47

CoolGamer

What is it? Dragons?

Printf zal struikelen over de "%" tekens in je tekst. Die hebben binnen printf een speciale betekenis. Een workaround hiervoor is het vervangen van "%" door "%%". (Oplossing Cheatah is beter)

[ Voor 10% gewijzigd door CoolGamer op 16-10-2010 20:30 ]

¸.·´¯`·.¸.·´¯`·.¸><(((º>¸.·´¯`·.¸><(((º>¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸<º)))><¸.·´¯`·.¸.·´¯`·.¸.·´¯`·.¸


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Verwijderd schreef op zaterdag 16 oktober 2010 @ 20:28:
Jij voert namelijk met regel 19 een string in die % bevat. %s en %d om precies te zijn. Er zijn echter niet genoeg argumenten voor printf, want die verwacht een extra argument om voor %s in te vullen, en dan nog een om %d te vullen.

Snap je wat er misgaat? :)

Met mijn regel gaat het wel goed, hij vult de letterlijke tekst in op de plaats van %s in het eerste argument. Hierdoor maken de bijzondere tekens in de input niet meer uit.
Het werkt :) Daar kon ik nog uren op gezocht hebben! Bedankt!

Maar de precieze reden is me nog niet helemaal duidelijk. Bij mijn eerste printf vul ik toch wel elk argument in? De %s wordt ingevuld met argv[0] en de %d met 1. Dan zou hij toch niet meer moeten zoeken naar "%", hij heeft ze al allemaal ingevuld. Maar nu blijkt het toch vlekkeloos te werken als ik jouw syntax gebruik. Ik was nochtans van mening dat je printf ook gewoon mocht gebruiken als een standaard print functie.


Maar ik ben al uiterst tevreden dat het werkt! :)
bedankt iedereen!

Acties:
  • 0 Henk 'm!

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

NMe

Quia Ego Sic Dico.

Verwijderd schreef op zondag 17 oktober 2010 @ 11:38:
[...]

Maar de precieze reden is me nog niet helemaal duidelijk. Bij mijn eerste printf vul ik toch wel elk argument in? De %s wordt ingevuld met argv\[0] en de %d met 1. Dan zou hij toch niet meer moeten zoeken naar "%", hij heeft ze al allemaal ingevuld.
Tuurlijk, maar die eerste twee printf's gingen toch ook niet fout? De printf op regel 31 leverde een bug op, toch? En die heeft maar één argument, waar dus best wel eens een %-teken in zou kunnen staan.

'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!

Verwijderd

Topicstarter
NMe schreef op zondag 17 oktober 2010 @ 11:57:
[...]

Tuurlijk, maar die eerste twee printf's gingen toch ook niet fout? De printf op regel 31 leverde een bug op, toch? En die heeft maar één argument, waar dus best wel eens een %-teken in zou kunnen staan.
Aha, nu begrijp ik het, als er maar één argument wordt opgegeven, dan probeert hij toch nog substituties door te voeren. Bedankt voor de verduidelijkingen, ze waren echt handig. Wel stom dat printf dan toch één argument toelaat.

Iedereen nog veel programmeerplezier gewenst! :)

Acties:
  • 0 Henk 'm!

  • fleppuhstein
  • Registratie: Januari 2002
  • Laatst online: 07-09 13:37
Verwijderd schreef op zondag 17 oktober 2010 @ 12:35:
[...]


Aha, nu begrijp ik het, als er maar één argument wordt opgegeven, dan probeert hij toch nog substituties door te voeren. Bedankt voor de verduidelijkingen, ze waren echt handig. Wel stom dat printf dan toch één argument toelaat.

Iedereen nog veel programmeerplezier gewenst! :)
Nee niet stom, maar verwachte gedrag, hoe zou je anders het volgende doen als minimaal twee argumenten worden verwacht:

code:
1
printf('Hello world');

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het punt is, printf() weet helemaal niet hoeveel argumenten hij toegespeeld krijgt. Het enige wat ie kan doen is gewoon aannemen dat er zoveel argumenten zijn als dat er substituties in de string nodig zijn. Dus als er een %s en een %d in de string staat, dan gaat ie ervan uit aan dat die twee extra argumenten ook daadwerkelijk bestaan.

Bottom line, nooit een string waarvan je niet weet wat ie bevat direct met printf() afdrukken. Daarvoor is de functie puts(). Of je gaat voor Cheatah's oplossing.

[ Voor 20% gewijzigd door .oisyn op 17-10-2010 14:29 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1