0

I'm creating a sales project for a specific product in c. What happens is that each customer is required to register to have a customer number, but I have a problem because the program manages the number, but when it goes to save it in the txt file, it doesn't give the correct one. However I'm having another problem with the client's name, if I write the full name it gives an error. How can I solve these problems? Thanks

This is my code:

 #include <stdlib.h>
#include <stdio.h>

typedef struct client CLIENT;

struct client {
    char name[80];
    char country[10];
    int tin;
};

void createprofile() {
    char tin_present;
    int i;
    
    
    FILE* bd;
    bd = fopen("bd.txt", "a+");
    CLIENT c;


    printf("\t *** Create customer profile *** \n");

    printf("Client code: ");

    for (i = 0; i < 1; i++) {
        printf("%d\n ", rand() % 1000000); 
    }

    printf("Type your name: ");
    scanf("%s", &c.name);

    printf("TIN present?? ");
    scanf("%s", &tin_present);
    if (tin_present == 's' || tin_present == 'S') {
        while (1) {
            printf("\n\tEnter your TIN: ");
            scanf("%d", &c.tin);

            if (c.tin >= 999999999) {
                printf("\tNumber with more than 9 digits is not allowed. Please try again.");

            } else if (c.tin <= 99999999) {

                printf("\tNumber with less than 9 digits is not allowed. Please try again.");
            } else
                break;
        }
        printf("\tValid.\n");
    } else {
        printf("TIN not entered\n");
    }

    printf("What is your country? ");
    scanf("%s", &c.country);

    fprintf(bd, "code: %d | name: %s | tin: %i | country: %s \n", c.name, c.tin, c.country);
    fclose(bd);
}
Ana
  • 1
  • 3

2 Answers2

1

Add client code member to struct, i.e. int client_code;

Then consider changing this:

for (i = 0; i < 1; i++) {
    printf("%d\n ", rand() % 1000000); 
}

To this:

c.client_code = rand() % 1000000;
printf("Client Code: %d\n ", c.client_code);

Note on using rand(). If not already done, (in the code you have not shown) srand() should be called early in your program, one time only, Prior to calling rand(), to ensure that your pseudo-random values are truly pseudo-random. (The link provides examples how.)

Then in your file output, add client code:

fprintf(bd, "code: %d | name: %s | tin: %i | country: %s \n", c.client_code, c.name, c.tin, c.country);

Other suggestions might include either using an array of struct to contain more than one client

#define MAX_CUSTOMERS 100 //or what makes sense for your need

typedef struct {
    char name[80];
    char country[10];
    int tin;
    int client_code;
}CLIENT_s;

CLIENT_s client[MAX_CUSTOMERS];

...or use Linked Lists in which to read your client file, add, delete clients, then update file.

ryyker
  • 22,849
  • 3
  • 43
  • 87
  • @Eugene Sh - Thanks for the edit. – ryyker Dec 16 '21 at 19:56
  • 1
    Don't forget to remind the OP to call [srand()](https://linux.die.net/man/3/rand) (e.g. `srand(time(0));`), and to call it exactly once in the program (before calling rand()). – paulsm4 Dec 16 '21 at 20:29
  • @paulsm4 - I did this in the comments under O Post, but will add it here as well. Thank you. – ryyker Dec 16 '21 at 20:54
1
  1. For the random number problem, as ryyker already commented, the problem is that you're not storing your created number anywhere, you're just printing it.

You can do as ryyker suggested:

  • Create a new "info" inside your CLIENT object, where you can store the value of client-id. Consider changing this:
typedef struct client CLIENT;

struct client {
    char name[80];
    char country[10];
    int tin;
};

To this:

/*    If you want to, you can do this, change your struct prototype
and condense it into the struct declaration    */

typedef struct client {
    char name[80];
    char country[10];
    int tin;
    int client_code; // or any other variable name your prefer to
} CLIENT; // and condensing, you write here the struct shortcut/typedef-name
  • As @paulsm4 reinforced, you're not setting the rand() seed nowhere in your code, so you should set it once, earlier in the program using srand():
srand(0);
  • Now, you can store the generated value inside your client information. Consider changing this:
for(i = 0; i < 1; i++) {
    printf("%d", rand() % 1000000);
}

Into this (note that as already commented before, there's no need to use this for with just one iteration):

c.client_code = rand() % 1000000;
  • And then add the new value into your bd.txt file:
fprintf(bd, "code: %d | name: %s | tin: %i | country: %s \n", c.client_code, c.name, c.tin, c.country);

  1. For client's name, I guess the problem you're having maybe is on the scanf function.

-> In C, vectors are treated as pointers. This being said, when you write the vector's name in some place of your program, what the program receives is the memory address of the first position of the vector.

-> A string is a vector of chars, so we'll not use the & (passes memory address of a variable) in scanf, 'cause its name is already a pointer.

Then, consider making this change:

printf("Type your name: ");
scanf("%s", &c.name);

To this (the same applies to your country scanning):

printf("Type your name: ");
scanf("%s", c.name); // without the '&'

OBS: if you want to read a string/fullname with spaces, you should use this format for scanf:

printf("Type your name: ");
scanf("%[^\n]s", c.name); // [^\n] tells to the program to ignore newline characters until "Enter" be pressed
  • 1
    You've given a pretty exhaustive answer, but you're still missing a couple of things to OP should note: 1) calls to [rand()](https://linux.die.net/man/3/rand) should be preceded by a call to "srand()" once, earlier in the program. 2) One should always save - and check - the return value from [sprintf()](https://linux.die.net/man/3/printf). This is the only way to ensure that all the reads in the format specification actually succeeded. – paulsm4 Dec 17 '21 at 04:39
  • @paulsm4 Thanks for your comment, really appreciated it. What about this edit, still exhaustive (I want to get better at this haha). I didn't understand what you meant the implementation of `sprintf()`, could you show how, please? – SeawardSalmon6 Dec 17 '21 at 17:02
  • Sorry - my bad. I meant "scanf()" (same man page; different library call). You should always check the return value of *scanf()*. The examples you gave should each return "1" (i.e. "successfully read one item"). – paulsm4 Dec 17 '21 at 17:04
  • Like `if(scanf(" %[\n]s", str) != 1) its_an_error_do_something;` ? – SeawardSalmon6 Dec 17 '21 at 17:27
  • Yes - exactly.. – paulsm4 Dec 17 '21 at 17:59
  • regarding: `scanf("%[^\n]s", c.name);`the `s` in the format string will cause the `scanf()` to fail, because the next character in `stdin` will be `\n`, not `s`. Suggest removing that `s` – user3629249 Dec 18 '21 at 00:15
  • regarding: `srand(0);` this will result in the same output sequence when calling `rand()` Much better to use: `srand( (unsigned)time(NULL) );` – user3629249 Dec 18 '21 at 00:25