-1

enter image description hereHaven't used C in a while and get -1073741819 (0xC0000005) after I ask a user for the d, m, y inputs. I assume it's something to do with how I use pointers. I have created a different program using the pointers similarly, and it all worked fine and dandy. Don't really know what else to say. Why would the program not work. I feel like it's something ridiculously obvious and stupid, but I just can't see it. :D

#include<stdio.h>
#include<string.h>
#include<ctype.h>

void date (int *d, int *m, int *y);
void name (char vards[20], char uzvards[20]);
void income (float *ienakums);
void writefile(int *y,int *m, int *d, char vards[20],char uzvards[20],float *ienakums);


int main(void) {

 char Name[20], last[20];
 int diena,menesis,gads;
 float cash;

    // step 1 - get name + check
    name(&Name[20], &last[20]);
    // step 2 - get date + check
    date(&diena,&menesis,&gads);
    // step 3 - get income + check
    income(&cash);
    // step 4 - write the file
    writefile(&gads,&menesis,&diena,&Name[20],&last[20],&cash);




    }
void name(char vards[20], char uzvards[20]){

int check = 1;
int counter = 0;

do{
    printf("Ievadiet jusu vardu\n");
    gets(vards);

    for(int i=0; i<strlen(vards); i++)
    {
      if(isdigit(vards[i]) > 0)
      {
          counter++;
      }

    }
    if(counter == 0)
    {
        check = 0;
    }
    else{

        check = 1;
    }
}while(check == 1);

check = 0;
do{
    printf("Ievadiet jusu uzvardu\n");
    gets(uzvards);

    for(int i=0; i<strlen(vards); i++)
    {
      if(isdigit(vards[i]) > 0)
      {
          counter++;
      }

    }
    if(counter == 0)
    {
        check = 0;
    }
    else{

        check = 1;
    }
}while(check == 1);
    printf("\nJusu vards ir %s %s",vards,uzvards);


}

void date (int *d, int *m, int *y){

*d = 0;
*m = 0;
*y = 0;

do{
    printf("\nLudzu ievadiet jusu dzimsanas dienu: ");
    fflush(stdin);
    scanf("%d", &d);

}while((d<=0) || (d>31));

do{
    printf("\nLudzu ievadiet jusu dzimsanas menesi: ");
    fflush(stdin);
    scanf("%d", &m);
}while((m<=0) || (m>12));

do{
    printf("\nLudzu ievadiet jusu dzimsanas gadu: ");
    fflush(stdin);
    scanf("%d", &y);

}while((y<1900) || (y>2021));

    printf("\n %d %d %d",*d,*m,*y);
}

void income (float *ienakums){

//do{
printf("\nIevadiet videjos ienakumus: ");
fflush(stdin);
scanf("%f", &ienakums);
//}while(isdigit(ienakums) <= 0);
    printf("%f",*ienakums);

}

void writefile(int *y,int *m, int *d, char vards[20],char uzvards[20],float *ienakums)
{
  FILE *file = fopen("dati.txt", "a+");
    fprintf(file, "\n\tVards:%s  Uzvards:%s  Dzimsanas Datums:%d %d %d Ienakums %.2f EUR \n", vards, uzvards, *d, *m, *y, *ienakums);
    fclose(file);
}

The code now looks like this:

#include<stdio.h>
#include<string.h>
#include<ctype.h>

void date (int *d, int *m, int *y);
void name (char vards[20], char uzvards[20]);
void income (float *ienakums);
void writefile(int *y,int *m, int *d, char vards[20],char uzvards[20],float *ienakums);


int main(void) {

 char Name[20], last[20];
 int diena,menesis,gads;
 float cash;

    // step 1 - get name + check
    name(Name, last);
    // step 2 - get date + check
    date(&diena,&menesis,&gads);
    // step 3 - get income + check
    income(&cash);
    // step 4 - write the file
    writefile(&gads,&menesis,&diena,Name,last,&cash);




    }
void name(char vards[20], char uzvards[20]){

int check = 1;
int counter = 0;

do{
    printf("Ievadiet jusu vardu\n");
    gets(vards);

    for(int i=0; i<strlen(vards); i++)
    {
      if(isdigit(vards[i]) > 0)
      {
          counter++;
      }

    }
    if(counter == 0)
    {
        check = 0;
    }
    else{

        check = 1;
    }
}while(check == 1);

check = 0;
do{
    printf("Ievadiet jusu uzvardu\n");
    gets(uzvards);

    for(int i=0; i<strlen(vards); i++)
    {
      if(isdigit(vards[i]) > 0)
      {
          counter++;
      }

    }
    if(counter == 0)
    {
        check = 0;
    }
    else{

        check = 1;
    }
}while(check == 1);
    printf("\nJusu vards ir %s %s",vards,uzvards);


}

void date (int *d, int *m, int *y){

*d = 0, *m = 0, *y =0;

do{
    printf("\nLudzu ievadiet jusu dzimsanas dienu: ");
    fflush(stdin);
    scanf("%d", d);

}while((*d<=0) || (*d>31));

do{
    printf("\nLudzu ievadiet jusu dzimsanas menesi: ");
    fflush(stdin);
    scanf("%d", m);
}while((*m<=0) || (*m>12));

do{
    printf("\nLudzu ievadiet jusu dzimsanas gadu: ");
    fflush(stdin);
    scanf("%d", y);

}while((*y<1900) || (*y>2021));

    printf("\n %d %d %d",d,m,y);
}

void income (float *ienakums){

//do{
printf("\nIevadiet videjos ienakumus: ");
fflush(stdin);
scanf("%f", ienakums);
//}while(isdigit(ienakums) <= 0);
    printf("%f",ienakums);
}

void writefile(int *y,int *m, int *d, char vards[20],char uzvards[20],float *ienakums)
{
  FILE *file = fopen("dati.txt", "a+");
    fprintf(file, "\n\tVards:%s  Uzvards:%s  Dzimsanas Datums:%d %d %d Ienakums %.2f EUR \n", vards, uzvards, d, m, y, ienakums);
    fclose(file);
}
  • 3
    `&Name[20]` is the address of the item one past the end of the array. Just use `name(Name, last);` Same in other places. – 001 Sep 22 '21 at 17:33
  • Please choose a title which is useful for others with the same issue. Thanks. – user438383 Sep 22 '21 at 17:35
  • Also, there's no need to pass the address of a variable unless you plan on changing it in the function (or it is too large to make a copy). For example in `writefile`, `y, m, and d` are not modified so they don't need to be pointers. – 001 Sep 22 '21 at 17:39
  • And: [Using fflush(stdin)](https://stackoverflow.com/a/2979217) – 001 Sep 22 '21 at 17:41
  • Let me suggest one thing you could say: "I have used a debugger and I observed that ..." (insert your observations). – n. m. could be an AI Sep 22 '21 at 17:42
  • And: `void income (float *ienakums) {... scanf("%f", &ienakums);...}` The variable `ienakums` is already a pointer. Don't pass the address of the pointer to `scanf`. – 001 Sep 22 '21 at 17:45
  • `d` and others are pointers and do not need `&` in `scanf`. Use `scanf("%d", d);` – i486 Sep 22 '21 at 17:45

2 Answers2

2

&Name[20] is the address of element 20 of the array. But there is no element 20, the array indexes go from 0 to 19. So the function is writing past the end of the array.

You should just pass the array itself, not the address of a particular element.

name(Name, last);

When an array is used as a function argument, it's automatically converted to the address of the first element; you don't need an explicit &.

Also, don't use gets(). It's a dangerous, obsolete function that has been removed from the language because you can't tell it the size of the input buffer. Use fgets() and then remove the newline at the end. See Removing trailing newline character from fgets() input

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • I've implemented your changes and the program now proceeds to write a file. The variables for d,m,y and ienakums print properly in the cmd window. However, in the resulting file I get absolute junk(random numbers) for d,y,m and 0.00 for the ienakums float. What could cause that? – StrangeGamer Sep 22 '21 at 18:03
  • In your `date()` function, `d`, `y`, and `m` are passed as pointers, but when using `scanf()` you're passing the address of the pointers (a pointer to a pointer). Since they're already pointers, you don't need the address, just use `scanf("%d", d)`. Similar problem for your `income()` function. – John Bayko Sep 22 '21 at 18:10
  • I made your suggested edit, yet it still yields these values(see image and changed code in the main post). Sorry for bothering you so much... just having a slow day :) – StrangeGamer Sep 22 '21 at 18:24
0

There are too many issues in your code that need to be addressed:

  1. Never use gets(). As already mentioned, it has been completely removed from the C standard. Use a combination of fgets(), strcspn() and sscanf() to read and parse your input.
  2. Avoid using scanf() to read input too. It is very error-prone and shouldn't be used to read user input. Again, use fgets(), strcspn() and sscanf().
  3. fflush(stdin) is undefined behaviour. Just remove that line from your code.
  4. When you open a file with fopen(), always check for its return value. It could be that the file couldn't be read normally or doesn't exist (if the mode is "r").

To read one input line:

char *readline(char *line, int size, FILE *stream)
{
    if (!fgets(line, size, stream)) // Check for errors
            return NULL;
        
    line[strcspn(line, "\n")] = '\0';
    return line;
}

To read an integer/float:

int readint(int *i) // readfloat(float *f)
{
    char line[255];
    if (!fgets(line, sizeof line, stdin))
            return 0;
        
    line[strcspn(line, "\n")] = '\0';
    
    return sscanf(line, "%d", i) == 1; // sscanf(line, "%f", f)
}

To check if your file has been correctly opened:

FILE *file = fopen("dati.txt", "a+");

if (!file) {
    fprintf(stderr, "Could not open file\n");
    return 1;
}

fprintf(file, "\n\tVards:%s  Uzvards:%s  Dzimsanas Datums:%d %d %d Ienakums %.2f EUR \n", vards, uzvards, *d, *m, *y, *ienakums);
fclose(file);
Zakk
  • 1,935
  • 1
  • 6
  • 17