[C] While blijft hangen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo,

Ik probeer een programma te schrijven dat vraagt om:

-pad invoerbestand
-bestandsnaam invoerbestand
-pad uitvoerbestand
-bestandsnaam uitvoerbestand

Vervolgens zal het programma een tabel die in het invoerbestand staat 90 graden draaien en in het uitvoerbestand wegschrijven.

Het programma moet bestand zijn tegen het verkeerd invullen van de bestandsnaam van het invoerbestand. Dat wil zeggen dat wanneer de bestandsnaam van een niet bestaand invoerbestand wordt ingevoerd, het programma opnieuw om de naam zal vragen.

Ik heb dit op de volgende manier gedaan:

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
34
35
36
37
38
39
40
41
#include <stdio.h>
#include <string.h>

int main()
{
 FILE * ifp,* ofp;
 char padinvoer[100], naaminvoer[50], paduitvoer[100], naamuitvoer[50];
 int array[10][10];
 int r, k, doorgaan;

 printf("\nPad invoerbestand:\n");
 scanf("%s", padinvoer);
 do{
    printf("Naam invoerbestand\n");
    scanf("%s", naaminvoer);
    ifp = fopen(strcat(padinvoer, naaminvoer), "r");
    if (ifp == NULL)
       doorgaan = 1;
    else
       doorgaan = 0;
    }while(doorgaan);

printf("\nPad uitvoerbestand:\n");
scanf("%s", paduitvoer);

printf("Naam uitvoerbestand\n");
scanf("%s", naamuitvoer);

ofp = fopen(strcat(paduitvoer, naamuitvoer), "w");

for (r=0;r<10;r++)
    for(k=0;k<10;k++)
    fscanf(ifp, "%d", &array[r][k]);
    
for (r=0;r<10;r++)
    {
    for(k=0;k<10;k++)
    fprintf(ofp, "%d ", array[k][r]);
    fprintf(ofp, "\n");
    }
}


Wanneer ik nu alles in 1 keer goed invul werkt het programma naar behoren.
Wanneer ik de verkeerde bestandsnaam invul vraagt het programma mij nogmaals de bestandsnaam in te vullen.
Tot zover werkt alles dus zoals bedoeld.

Wanneer ik echter de goede bestandsnaam invul nadat ik een verkeerde heb ingevuld blijft het programma mij vragen om een bestandsnaam, hoe vaak ik ook de goede invul.

Ik heb de 'do while' al op een paar alternatieve manieren in mijn code gehad, maar steeds bleef het programma in de loop hangen.

Wat doe ik hier fout?

Acties:
  • 0 Henk 'm!

  • remco_k
  • Registratie: April 2002
  • Laatst online: 18:53

remco_k

een cassettebandje was genoeg

Kijk eens goed naar de plek waar je het pad voor het invoer bestand vraagt, wacht op input en waar je do{ staat.

[ Voor 150% gewijzigd door remco_k op 30-10-2011 10:40 ]

Alles kan stuk.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dit heb ik met opzet buiten de 'do while' gedaan omdat deze gewoon hetzelfde mag blijven.
De bestandsnaam is het enige dat veranderd hoeft te worden.

Nu zou strcat toch gewoon het eerder ingevulde pad en de opnieuw ingevulde bestandsnaam moeten combineren, of zie ik dat verkeerd?

Acties:
  • 0 Henk 'm!

  • remco_k
  • Registratie: April 2002
  • Laatst online: 18:53

remco_k

een cassettebandje was genoeg

Wat is de output van die strcat?
Echo die eens naar het scherm. Daar zit ook een probleempje.

Tevens moet je er even over nadenken wat er gebeurd als je wel het pad en bestand goed had getikt, maar als het bestand in gebruik is door een andere applicatie waardoor de fopen ook failed.

Maar vooral: als fopen failed, zoek dan uit waarom hij failed.
Gebruik GetLastError() om de error code op te zoeken en iets als SysGetErrorText(errCode) om er een leesbare tekst uit te halen en presenteer die aan de gebruiker. Dan weet je waarom fopen niet lukte... Daar zijn namelijk meerdere mogelijkheden, zoals je inmiddels zult snappen.

Edit:
@hieronder, niet teveel weggeven! :)

[ Voor 7% gewijzigd door remco_k op 30-10-2011 10:50 ]

Alles kan stuk.


Acties:
  • 0 Henk 'm!

  • yade
  • Registratie: Mei 2002
  • Laatst online: 16-07 13:47
Strcat append de source aan de destination, en de destination is padinvoer. Die wordt niet hersteld, maar iedere keer iets langer, tot er een buffer overflow optreed. ;)

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
oké,
ik was er net zelf achtergekomen dat strcat de 2e string toevoegd aan de 1e en als output de 1e string geeft.

Nu ga ik er nog eens over nadenken hoe ik dit op een goede manier op ga lossen.

Bedankt remco!

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb het probleem nu als volgt opgelost.

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
34
35
36
37
38
39
40
41
42
43
44
45
#include <stdio.h>
#include <string.h>

int main()
{
 FILE * ifp,* ofp;
 char padinvoer[100],hulppad[100], naaminvoer[50], paduitvoer[100], naamuitvoer[50];
 int array[10][10];
 int r, k, doorgaan;

 printf("\nPad invoerbestand:\n");
 scanf("%s", padinvoer);
 for(k = 0; k <= (sizeof(padinvoer) / sizeof(char)); k++)
 hulppad[k] = padinvoer[k];
 do{
    printf("Naam invoerbestand\n");
    scanf("%s", naaminvoer);
    for (k=0; k<=(sizeof(padinvoer)/sizeof(char)); k++)
    padinvoer[k] = hulppad[k];
    ifp = fopen(strcat(padinvoer, naaminvoer), "r");
    if (ifp == NULL)
       doorgaan = 1;
    else
       doorgaan = 0;
    }while(doorgaan);

printf("\nPad uitvoerbestand:\n");
scanf("%s", paduitvoer);

printf("Naam uitvoerbestand\n");
scanf("%s", naamuitvoer);

ofp = fopen(strcat(paduitvoer, naamuitvoer), "w");

for (r=0;r<10;r++)
    for(k=0;k<10;k++)
    fscanf(ifp, "%d", &array[r][k]);
    
for (r=0;r<10;r++)
    {
    for(k=0;k<10;k++)
    fprintf(ofp, "%d ", array[k][r]);
    fprintf(ofp, "\n");
    }
}


Ik vind het er nogal stuntelig uitzien zo,
maar ik weet helaas niet hoe ik het makkelijker op zou kunnen lossen.


Nog bedankt voor de hulp!

Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:51
Dit werkt op zich, maar je riskeert nog steeds buffer overflows.

Waarom zou je de pad naar het invoer- en uitvoer bestand niet gewoon als command line arguments opvragen? Daar wordt je programma een stuk simpeler van, en voor de gebruiker is het ook makkelijker, zeker als 'ie je programma vanuit een script wil aanroepen.

Met dit stukje code zijn wel een aantal dingen mis:
C:
1
2
for(k = 0; k <= (sizeof(padinvoer) / sizeof(char)); k++)
    hulppad[k] = padinvoer[k]; 

Ten eerste geldt sizeof(char) = 1 (per definitie). Ten tweede overschrijdt je nu beide buffers met één karakter, aangezien indices in een array van 100 elementen van 0 tot en met 99 lopen, niet tot en met 100. Ten derde is er al een standaardfunctie die precies hetzelfde doet: memcpy(). Maar in dit geval kun je beter strcpy() gebruiker omdat je er vanuit gaat dat hulppad (minstens) even groot is als padinvoer, en dat padinvoer een geldige zero-terminated string bevat. Kortom, schrijf gewoon:
C:
1
strcpy(hulppad, padinvoer);

[ Voor 53% gewijzigd door Soultaker op 30-10-2011 22:06 ]


Acties:
  • 0 Henk 'm!

  • Gratzip
  • Registratie: Oktober 2010
  • Laatst online: 26-09-2020
Hier is ook nog een oplossing voor je originele code (wel een beetje een vieze):

C:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 int r, k, doorgaan;
int len;             // nummertje voor lengte pad

 printf("\nPad invoerbestand:\n");
 scanf("%s", padinvoer);
 len = strlen(padinvoer);          // opslaan van lengte pad
 do{
    printf("Naam invoerbestand\n");
    scanf("%s", naaminvoer);
    ifp = fopen(strcat(padinvoer, naaminvoer), "r");      // strcat begint te plakken bij de null byte
    if (ifp == NULL) { 
       doorgaan = 1;
       padinvoer[len]='\0';         // null byte in je pad string plakken bij len
       }
    else
       doorgaan = 0;
    }while(doorgaan); 


Zodat hij niet steeds stukjes aan je padinvoer string blijft plakken maar steeds terug gaat naar het einde van je originele padinvoer.

[ Voor 15% gewijzigd door Gratzip op 31-10-2011 17:56 ]

Pagina: 1