Problem with calling the function in C

Hello!
I'm new here, and don't know how to ask help correctly, but i have a problem:
Program crashes when running. I susppcet the problem is calling the function.
Program prints the text after reading the data, but then crashes.
Please help!

(My native language is Estonian and thats why the program text is in Estonian-language.)


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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
#include <stdio.h>
#include <string.h>


//Objekt, mis käsitleb raamatu infot
struct Raamat{
       char Raamat[50];
       char Eesnimi[50], Perekonnanimi[50];
       int Ilmumisaasta, Lehtedearv;
       char Keel[50];
       int Hinne;
       char Loetud[50];
       };

//Põhiprogrammi algus
int main()
{
    void raamatu_lugemine(int, int, char[50][100], int);
    char sisend_rida[200];
    char andmebaas [50][100];
    struct Raamat Raamat;
    char g[10];
    int x = 0;
    int y = 4;
    int pikkus = -1;
    FILE *SF;
    SF = fopen("andmebaas.txt", "r");

    // Andmete lugemine
    int i, j;
    for(i = 0; i <= 100 && ! feof(SF); i++){
          fgets(sisend_rida,50, SF);
          strcpy(andmebaas[i],sisend_rida);
          pikkus++;
          }
    fclose (SF);
    for( i = 0; i <= 100; i++){
          strcpy(sisend_rida, andmebaas[i]);

    //tutvustus, PROGRAM PRINTS THIS TEXT AND THEN CRASHES
    printf("Koostasin kogumiku parimatest raamatutest, mida olen lugenud ning lisasin ka selliseid, mida soovin lugeda lähiajal.\n\n\n");
    //5 esimest raamatut
    raamatu_lugemine(x, y, andmebaas,pikkus);
     while(1){
     printf("j = 5 järgmist kirjet, e = 5 eelmist kirjet, v = väljub");
     scanf("%s", g);
     if(g =="j"){
         x = x+5;
         y = y+5;
         raamatu_lugemine(x,y,andmebaas,pikkus);
         }
    if(g =="e"){
         x = x-5;
         y = y-5;
         raamatu_lugemine(x,y,andmebaas,pikkus);
         }
    if(g == "v"){
         break;
    }
    }
    system("pause");
    return 0;
   }
}

//Andmerea töötlemine loetavale kujule
 void raamatu_lugemine(arv, arv2, andmebaas, pikkus)
    int arv;
    int arv2;
    char andmebaas[50][100];
    int pikkus;
    {
    struct Raamat Raamat;
    char sisend_rida[200];
    int i;
    for(i = arv; i <= arv2 && i <= pikkus; i++){
            strcpy(sisend_rida, andmebaas[i]);
            strcpy(Raamat.Raamat,strtok(sisend_rida, "###"));
            Raamat.Ilmumisaasta = atoi(strtok(NULL, "###"));
            Raamat.Lehtedearv = atoi(strtok(NULL, "###"));
            strcpy(Raamat.Eesnimi, strtok(NULL, "###"));
            strcpy(Raamat.Perekonnanimi, strtok(NULL, "###"));
            strcpy(Raamat.Keel, strtok(NULL, "###"));
            strcpy(Raamat.Loetud, strtok(NULL, "###"));
            Raamat.Hinne = atoi(strtok(NULL, "###"));

            printf("Raamat %s", Raamat.Raamat);
            printf("[%s]; ", Raamat.Keel);
            printf("%s ", Raamat.Eesnimi);
            printf("%s; ", Raamat.Perekonnanimi);
            printf("%d aasta; ", Raamat.Ilmumisaasta);
            printf("%d lk, ", Raamat.Lehtedearv);
            printf("%s ", Raamat.Loetud);
            printf("(%d/10)", Raamat.Hinne);
}
}
Well you have no function declaration. The program has no idea what to do when it comes across the function call
This is C not C++ and function declaration is on the line 18. Its justl ike here http://nios.ac.in/cca/cca15.pdf page 4.
Could someone please help me fix this, i don't get it at the moment.
What you need to do, is if you haven't already done so, is debug the call to raamatu_lugemine()

Or, if you prefer, add some diagnostic output. That is, add more printfs, esp. (a) to display what the i/p params are, (b) the andmebaas[] values, and (c) what strtok() is up to.

If your program is dying in raamatu_lugemine(), the most likely suspect in strtok. If this doesn't find what it needs, it returns NULL. If you feed NULL to strcpy() or atoi() then you will hit an access violation (or an assert, with some debug runtime libraries).

I think that feeding the output of strtok() directly into another function is generally a bad idea. But here you could replace atoi() and strcpy() with custom functions which handle the NULL case safely. For example

1
2
3
4
5
int safe_atoi ( const char * str ){
    if (str == NULL)
        return -1; // or some other unusual value
    return atoi(str); 
}


And similarly for strcpy()

Andy

PS By the way, the function header for raamatu_lugemine() is in very old fashioned "classic" K&R. Even they switched to ANSI C by 1988 (the 2nd edition of their book). Your function should start off like:

1
2
3
4
5
6
7
void raamatu_lugemine(int arg, int arg2, char andmebaas[50][100], int pikkus)
{
    struct Raamat Raamat;
    char sisend_rida[200];
    int i;
    for(i = arv; i <= arv2 && i <= pikkus; i++){
    ...


No one should be using pre-ANSI C in this millenium!
Last edited on
Okay, i edited the code. Now the code compiles nicely ( and it doesn't crash), but i have still some problems. First, the program prints the text from .txt file incorrectly.
My .txt file looks like this:

Book name###Year###number of pages###writer first name###writer family name###book language###have i read it(loetud - yes; lugemata - no)###mark(max 10 points)

Kärbeste jumal###1954#248###William###Golding###est###loetud###9
Kääbik, ehk, Sinna ja tagasi###1937#360###John Ronald Reuel###Tolkien###est###loetud###10
Harry Potter ja tarkade kivi###1997###263###Joanne###Rowling###est###lugemata###0
Ööloom###2008###263###Kate###Thompson###est###loetud###6
Arabella, mereröövli tütar###2008###314###Aino###Pervik###est###lugemata###0
Kolm musketäri###2004###684###Alexandre###Dumans###est###loetud###8
Kõik algas Omahas###1962###140###Rex###Stout###est###loetud###7
Timm Thaler ehk müüdud naer###1962###217###James###Krüss###est###loetud###7
Bullerby lapsed###1965###245###Astrid###Lindgren###est###lugemata###0
Vahtramäe Emil on veel elus###2004###216###Astrid###Lindgren###est###loetud###10
Doktor Dolittle'i tsirkus###1931###376###Hugh###Lofting###est###lugemata###0
Suur vastasseis###1976###388###Lev###Kassil###est###lugemata###0
Tasuja###1984###84###Eduard###Bornhöhe###est###loetud###5
Kapten Granti lapsed###1868###452###Jules###Verne###est###lugemata###0
Kaks kaptenit###1957###677###Venjamin###Kaverin###est###lugemata###0
Kakskümmend tuhat ljööd vee all###1982###368###Jules###Verne###lugemata###0


It must print every line like this:
Raamat “Kärbeste jumal” [est]; William Golding; 1954 aasta; 248 lk, loetud (9/10)

Secondly, j and e and v doesn't work. when i press j and ENTER, it must show next 5 lines from the document and when i press e and ENTER, it must show 5 previous lines from the .txt file. But when i press them, nothing happens.

My code now:
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <string.h>

void raamatu_lugemine(int arv, int arv2, char andmebaas[50][100], int pikkus);
int safe_atoi ( const char * str );
char safe_strcpy (char * str2, const char * str );

//Object, mis käsitleb raamatu infot
struct Raamat{
       char Raamat[50];
       char Eesnimi[50], Perekonnanimi[50];
       int Ilmumisaasta, Lehtedearv;
       char Keel[50];
       char Hinne;
       char Loetud[50];
       };

//Põhiprogrammi algus
int main()
{
    char sisend_rida[50];
    char andmebaas [50][100];
    struct Raamat Raamat;
    char g[10];
    int x = 0;
    int y = 4;
    int pikkus = -1;
    FILE *SF;
    SF = fopen("andmebaas.txt", "r");

    // Andmete lugemine jadasse
    int i;
    for(i = 0; i <= 100 && ! feof(SF); i++){
          fgets(sisend_rida,50, SF);
          strcpy(andmebaas[i],sisend_rida);
          pikkus++;
          }
    fclose (SF);
    for( i = 0; i <= 100; i++){
          strcpy(sisend_rida, andmebaas[i]);

    //tutvustus
    printf("\n\n");
    printf("Koostasin kogumiku raamatutest, mida olen lugenud ning lisasin ka selliseid, mida soovin lugeda lähiajal.\n\n\n");
    //5 esimest raamatut
    raamatu_lugemine(x, y, andmebaas,pikkus);
     while(1){
     printf("j = 5 järgmist kirjet, e = 5 eelmist kirjet, v = väljub\n");
     scanf("%s", g);
     if(g =="j"){
         x = x+5;
         y = y+5;
         raamatu_lugemine(x,y,andmebaas,pikkus);
         }
    if(g =="e"){
         x = x-5;
         y = y-5;
         raamatu_lugemine(x,y,andmebaas,pikkus);
         }
    if(g == "v"){
         break;
    }
    }
    system("pause");
    return 0;
   }
}

//Andmerea töötlemine loetavale kujule
 void raamatu_lugemine(int arv,int arv2, char andmebaas[50][100],int pikkus)
    {
    struct Raamat Raamat;
    char sisend_rida[50];
    int l;
    for(l = arv; l <= arv2 && l <= pikkus; l++){
            safe_strcpy(sisend_rida, andmebaas[l]);
            safe_strcpy(Raamat.Raamat,strtok(sisend_rida, "###"));
            Raamat.Ilmumisaasta = safe_atoi(strtok(NULL, "###"));
            Raamat.Lehtedearv = safe_atoi(strtok(NULL, "###"));
            safe_strcpy(Raamat.Eesnimi, strtok(NULL, "###"));
            safe_strcpy(Raamat.Perekonnanimi, strtok(NULL, "###"));
            safe_strcpy(Raamat.Keel, strtok(NULL, "###"));
            safe_strcpy(Raamat.Loetud, strtok(NULL, "###"));
            Raamat.Hinne = safe_atoi(strtok(NULL, "###"));

            printf("Raamat '%s' ", Raamat.Raamat);
            printf("[%s]; ", Raamat.Keel);
            printf("%s ", Raamat.Eesnimi);
            printf("%s; ", Raamat.Perekonnanimi);
            printf("%d aasta; ", Raamat.Ilmumisaasta);
            printf("%d lk, ", Raamat.Lehtedearv);
            printf("%s ", Raamat.Loetud);
            printf("(%d/10)\n\n", Raamat.Hinne);
}
}

int safe_atoi ( const char * str ){
    if (str == NULL){
        return -1;
    }
    return atoi(str);
}

char safe_strcpy (char * str2, const char * str ){
    if (str == NULL){
        return -1;
    }
    return strcpy(str2, str);
}
Last edited on
#1 safe_strcpy doesn't look quite right. strcpy returns a char* to start with.
http://www.cplusplus.com/reference/clibrary/cstring/strcpy/

1
2
3
4
5
6
char* safe_strcpy (char * str2, const char * str ){
    if (str == NULL){
        return strcpy(str2, "???");
    }
    return strcpy(str2, str);
}


#2 comparing strings

1
2
3
     scanf("%s", g);
     if(g =="j"){
         ....


is not the way to compare a string. Use strcmp() compare them (e.g.)
http://www.cplusplus.com/reference/clibrary/cstring/strcmp/

1
2
3
     scanf("%s", g);
     if(strcmp(g, "j") == 0){
         ....


Your code is comparing the addresses of the two strings, which will never be the same.

Or rework your code to work with chars instead.
Last edited on
Topic archived. No new replies allowed.