Save text to file permanently and read from it - c

Hello everyone i have to do simple login program in C, i have a problem to save username, full name and password because i need to choose '1' for sign up and '2' for sign in but always when i exit the console and try to read my file everything disappears.
#include <stdio.h>
int main() {
FILE *f = fopen("users.txt", "w+");
if (f == NULL) {
printf("N/A");
exit(1);
}
int choose,
username[15],
fullName[20],
password[15],
// confirmPassword[15];
printf("Welcome!\n");
printf(" 1: Sign up\n 2: Sign in\n");
printf("--------------------------------\n");
scanf("%d", &choose);
if(choose==1) {
printf("Username: ");
scanf("%s", &username);
printf("Full name: ");
scanf("%s", &fullName); /// BECAUSE OF SPACE IT COUNTS LIKE A PASSWORD
printf("Password: ");
scanf("%s", &password);
fprintf(f, "%s\n%s\n%s", username, fullName, password);
}
if(choose==2) {
char c;
printf("Username: ");
while( c != EOF) {
c = fgetc(f);
printf("%c",c);
}
}
fclose(f);
return 0;
}
I have to deal with HASH too but i will try that on my own. And help about /// comment !

As per previous comments, and with my idea, here is how you may fix the code:
1. use int c or unsigned int c to declare c variable.
2. set c tp be (whatever as long it is not EOF);
3. make do while loop that at the end checks for EOF.

Related

How to write, read and delete a file in a single script in C programming

I created a file and filled it with some entries. However, I want to read this file and show it on the screen. Also, after showing the entries, I want it to be deleted with my permission. But I am stuck at this point please help me.
EDIT: Code is updated but still couldn't figure it out how to do :/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char name[20], surname[20], city[30], country[30], gender[15];
int count = 0;
int main() {
FILE *f1;
f1 = fopen("C:\\FurkanArslan.txt", "r+");
while (count < 10) { // every step provides 5 new data, so 5*10 will provide 50 data in total.
printf("\n*Please enter required information: \n");
printf("Name :"); scanf("%s", name);
printf("Surname:"); scanf("%s", surname);
printf("Country:"); scanf("%s", country);
printf("City :"); scanf("%s", city);
printf("Gender :"); scanf("%s", gender);
fprintf(f1, " %s | %s | %s | %s | %s\n\n", name, surname, gender, city, country);
count++;
}
fclose(f1);
printf("\n<<<<<%d data has been successfully saved!>>>> \n", count * 5);
printf("-------------------------------------\n");
f1 = fopen("C:\\FurkanArslan.txt", "r");
char c, answer;
while ((c = fgetc(f1)) != EOF)
putchar(c); // In this part I displayed file on the screen.
printf("\n\n <<<< %d entries are displayed on the screen! >>>>", count * 5);
printf("\n\nWould you like to remove your file [Y/N] ?");
scanf(" %c", &answer);
if (answer == 'y' || answer == 'Y') {
remove("f1");
printf("\n\n***File successfully removed!");
}
return 0;
}
In order to show the content of a file you have to open it and read it letter by letter, after that, you can use the putchar function to output the current character
FILE *fp = fopen("path/to/file.txt","r");
char c;
while((c=fgetc(fp))!=EOF)
putchar(c);
fclose(fp);
after that to remove a file you need to use the remove function, which receives the name of the file as paramter.
remove("my_file.txt");
There are multiple issues in your code:
there is no need to make the variables and arrays global, just define them in the body of the main() function.
you should tell scanf() the maximum number of characters to store in the destination array with a length specifier in the format string (eg: "%19s") and check for conversion success.
the variable c used in the reading loop must have type int for proper detection of EOF. fgetc() returns a positive byte value if successful and the special negative value EOF at end of file.
you do not need to reopen the file after writing to it. Sine you opened it for update mode, you can just seek back to the beginning of the file with rewind(f1) or fseek(f1, 0L, SEEK_SET).
the file is open for read and update mode ("r+"): it will fail if the file does not exist. You should open it in write and update mode with "w+" to create or truncate it.
you should check that fopen succeeds at opening the file, otherwise you invoke undefined behavior passing a null stream pointer to fprintf.
to remove the file, remove() takes the filename as its argument. You must close the file before attempting to remove it.
Here is a modified version:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
const char *filename = "C:\\FurkanArslan.txt";
char name[20], surname[20], city[30], country[30], gender[15];
int count = 0;
FILE *f1 = fopen(filename, "w+");
if (f1 == NULL) {
printf("Cannot open file %s.\n", filename);
return 1;
}
while (count < 10) { // every step provides 5 new data, so 5*10 will provide 50 data in total.
printf("\n*Please enter required information: \n");
printf("Name :"); if (scanf("%19s", name) != 1) break;
printf("Surname:"); if (scanf("%19s", surname) != 1) break;
printf("Country:"); if (scanf("%29s", country) != 1) break;
printf("City :"); if (scanf("%29s", city) != 1) break;
printf("Gender :"); if (scanf("%14s", gender) != 1) break;
fprintf(f1, " %s | %s | %s | %s | %s\n\n", name, surname, gender, city, country);
count++;
}
printf("\n<<<<< %d data has been successfully saved to %s! >>>>\n",
count * 5, filename);
printf("-------------------------------------\n");
rewind(f1);
int c;
while ((c = fgetc(f1)) != EOF)
putchar(c);
printf("\n\n <<<< %d entries are displayed on the screen! >>>>\n", count);
fclose(f1);
printf("\nWould you like to remove your file [Y/N] ?");
char answer;
if (scanf(" %c", &answer) == 1 && (answer == 'y' || answer == 'Y')) {
if (remove(filename)) {
printf("\n\n***Error removing file %s: %s\n",
filename, strerror(errno));
} else {
printf("\n\n***File %s successfully removed!\n", filename);
}
}
return 0;
}

Error while sign up in simple file login program

I already asked before and have done something that would work i think (but i'm a beginner so that story falls into a water) i have an error when i tried to sign up can anyone help? I have few more hours to send it (homework) AND i don't ask someone to do it for me, just to gimme instructions
#include <stdio.h>
#include <string.h>
int signIn(char username[30], char pass[30]){
FILE *p;
char user2[30], pass2[30];
p = fopen("users.txt", "r+");
fscanf(p,"%s\n%s",user2,pass2);
if( (strcmp(username,user2)==0) && (strcmp(pass,pass2)==0) )
printf("\nUser and password correct!!!");
else
printf("\nUser or password incorrect!\n\n");
printf("\n\n");
fclose(p);
return 0;
}
int signUp(char username[30], char pass[30], char fullName[30]) {
FILE *p;
p = fopen("users.txt", "r+");
printf("Username: ");
scanf("%s", &username);
printf("Password: ");
scanf("%s", &pass);
printf("Full name: ");
scanf("%s", &fullName);
fprintf(p, "%s\n%s\n%s", username, fullName, pass);
fclose(p);
return 0;
}
int main(){
char username[30], pass[30], fullName[30];
int choose;
printf("Welcome to student login system!\n");
printf(" 1: Sign in\n 2: Sign up\n");
printf("--------------------------------\n");
scanf("%d", &choose);
if(choose==1) {
printf("\nUser:");
scanf("%s",username);
printf("\nPassword:");
scanf("%s",pass);
signIn(username, pass);
}
if(choose==2) {
signUp(username, pass, fullName);
}
}
I tried a lot different ways and i'm really confused right now..
scanf("%s", &username); is not correct. It shall be scanf("%s", &username[0]); One should give concentration to the warnings especially for array/pointers involved.
Similarly below 2 lines
scanf("%s", &pass[0]);
scanf("%s", &fullName[0]);
fprintf(p, "%s\n%s\n%s", username, fullName, pass); You writing the fullname as second line, but while reading, you read 2nd line as password. So fprintf(p, "%s\n%s\n%s", username, pass,fullName );
Another suggestion, after opening the file, the file pointer shall be checked for its validity. for some reason, if it returns NULL, then your program would crash.
Instead of simply trying compiling and getting the o/p, best way to debug this simple code is to sit down with pen and paper, try analyse what happens with each line
A number of things that are wrong with your code jumped out at me. I tried to fix as much as I could. The following should work.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int signIn(char username[], char pass[]) {
FILE *p;
char user2[30], pass2[30], fullName[50];
if (!(p = fopen("users.txt", "r+"))) {
printf("Could not read from users.txt file\n");
fclose(p);
return 1;
}
int ret = 2;
while (fgets(user2, 30, p) != NULL) {
fgets(pass2, 30, p);
fgets(fullName, 50, p);
// you have written the fullName to the file as a third line, so you must check for this too
if ((strcmp(username, user2) == 0) && (strcmp(pass, pass2) == 0)) {
printf("\nUser and password correct!!!\n");
printf("Logged in as %s", fullName);
ret = 0;
break;
}
}
if (ret == 2)
printf("\nUser or password incorrect!\n");
printf("\n\n");
fclose(p);
return ret;
}
int signUp(void) {
FILE *p;
char username[30], pass[30], fullName[50];
if (!(p = fopen("users.txt", "w+"))) {
printf("Could not write to users.txt file\n");
fclose(p);
return 1;
}
printf("Username: ");
fgets(username, 30, stdin);
printf("Password: ");
fgets(pass, 30, stdin);
printf("Full name: ");
fgets(fullName, 50, stdin);
fprintf(p, "%s%s%s", username, pass, fullName);
printf("You have signed up!\n");
fclose(p);
return 0;
}
int main(void) {
char username[30], pass[30];
int choose;
printf("Welcome to student login system!\n");
printf(" 1: Sign in\n 2: Sign up\n");
printf("--------------------------------\n");
scanf("%d", &choose);
getchar();
if (choose == 1) {
printf("User: ");
fgets(username, 30, stdin);
printf("Password: ");
fgets(pass, 30, stdin);
return signIn(username, pass);
}
else if (choose == 2) {
return signUp();
}
return 0;
}
EDIT: I apologize for the sloppy answer, I was not on my main computer. This code will work for reading 1 user.

C read file, struct and infinity loop

I wrote a program that collects user data and saves it to a file. At the moment when he wants to view the file, the program loops and shows only the first record. I do not know what this error is caused.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
FILE *fptr;
struct notification {
char name[50];
char lastname[50];
char price[10];
char descreption[100];
}notification;
void insertRecord()
{
fptr=fopen("G:\\file.txt","a+");
fflush(stdin);
printf("Podaj imie: ");
gets(notification.name);
printf("Podaj nazwisko: ");
gets(notification.lastname);
printf("Podej cene: ");
gets(notification.price);
printf("Podaj opis usterki: ");
gets(notification.descreption);
strcat(notification.descreption,"\n");
if(fwrite(&notification,sizeof(notification),1,fptr) != 1)
{
perror("Blad: ");
} else{
printf("Dane dodane poprawnie\n");
}
fclose(fptr);
}
void readDatabase()
{
struct notification *object2=malloc(sizeof(struct notification));
fptr=fopen("G:\\file.txt","rb");
fread(object2,sizeof(struct notification),1,fptr);
while(!feof(fptr))
{
printf("Imie: %s\n", object2->name);
printf("Nazwisko: %s\n", object2->lastname);
printf("Cena: %s\n", object2->price);
printf("Opis: %s\n", object2->descreption);
printf("==========\n");
}
fclose(fptr);
}
int main() {
int i,option=0,check=0;
do{
printf("1) Dodaj rekord do bazy \n");
printf("2) Odczytaj rekordy z bazy \n");
printf("0) Zakoncz program \n");
scanf("%d", &option);
switch (option)
{
case 1:
insertRecord();
break;
case 2:
readDatabase();
break;
default:
break;
}
}while(check == 0); //petla dziala dopóki zmienna check bedzie równa 0
}
EDIT:
Correct insertRecord function:
void insertRecord()
{
fptr=fopen("G:\\file.txt","a+");
fflush(stdin);
struct notification *obj = malloc(sizeof(struct notification));
printf("Podaj imie: ");
gets(obj->name);
printf("Podaj nazwisko: ");
gets(obj->lastname);
printf("Podej cene: ");
gets(obj->price);
printf("Podaj opis usterki: ");
gets(obj->descreption);
strcat(notification.descreption,"\n");
if(fwrite(obj,sizeof(struct notification),1,fptr) != 1)
{
perror("Blad: ");
} else{
printf("Dane dodane poprawnie\n");
}
free(obj);
fclose(fptr);
}
Now ALL display and insert OK, but in file.txt I see Chinese characters, why?
There are a variety of problems in the readDatabase function
while(!feof)-is-always-wrong
the fread needs to be in the loop.
you don't need to malloc the memory, but if you do malloc memory, you should free it when you're done with it
you always need to check the return value from fopen, because it can and does fail, e.g. because the file is not found
With all that in mind, the readDatabase function should look like this
void readDatabase( void )
{
struct notification object2;
if ( (fptr = fopen("G:\\file.txt","rb")) == NULL )
{
printf( "File not found\n" );
return;
}
while ( fread( &object2, sizeof(struct notification), 1, fptr ) == 1 )
{
printf("Imie: %s\n", object2.name);
printf("Nazwisko: %s\n", object2.lastname);
printf("Cena: %s\n", object2.price);
printf("Opis: %s\n", object2.descreption);
printf("==========\n");
}
fclose(fptr);
}
Move this line:
fread(object2,sizeof(struct notification),1,fptr);
inside your while loop.
scanf("%d", &option); followed by gets() leads to trouble. The first does not consume the '\n' after the number and the second only reads in the short line '\n'.
Do not use scanf(). Do not use gets(). Use fgets(), then parse the input.
scanf() will leave new line character in input stream by default. you can use getchar() function to clear this new line character or you can flush the input buffer like this.
while ((ch = getchar()) != '\n' && ch != EOF);
but don't use fflush(stdin) because if the file stream is for input use, as stdin is, the behaviour is undefined, therefore it is not acceptable to use fflush() for clearing keyboard input. As usual, there are some exceptions, check your compiler's documentation to see if it has a (non-portable) method for flushing input.

fprintf in do while loop wrote only one line in file C

I don't know why it is writing only one line in my file
void foo()
{
int ID;
char answer;
FILE *input = fopen("Dane.txt", "w");
do
{
printf("Give ID: ");
scanf("%d",&ID);
fprintf(input, "%d\n", ID);
printf("Exit? y/n ");
scanf("%s", &answer);
fflush(NULL);
}
while (answer != 'n');
fclose(input);
}
Output (in file) is only first ID number which I write on console. But where are others?
EDIT: ok I got it. The error was in char answerand it should be char answer[2] and ending while should be while(answer[0] != ...). Before it the program read only one character - the line end. When i hit e.g. "n ENTER" it take only ENTER. Now it take the first char from tab i.e. "n". Thank everybody for help
You are doing some logical mistake. You are asking whether exit or not. If user does not want to exit, then he would press n. So, to continue the loop, the answer should be equal to n, right?
Modified version of your program:
void foo()
{
int ID;
char answer;
FILE *input = fopen("Dane.txt", "w");
do
{
printf("Give ID: ");
scanf("%d",&ID);
fprintf(input, "%d\n", ID);
printf("Exit? y/n ");
scanf(" %c", &answer);
fflush(NULL);
}
while (answer == 'n');
fclose(input);
}
answer has only one space to read and it isn't capable to store string whose length is 1 character or longer.
This won't affect the result, but using input for output file pointer is confusing.
The conditio in while is unnatural.
Try this:
#include <stdio.h>
void foo();
int main() {foo(); return 0;}
void foo()
{
int ID;
char answer[4];
FILE *output = fopen("Dane.txt", "w");
if (output == NULL) return;
do
{
printf("Give ID: ");
if (scanf("%d",&ID) != 1) break;
fprintf(output, "%d\n", ID);
printf("Exit? y/n ");
if (scanf("%3s", answer) != 1) break;
fflush(NULL);
}
while (answer[0] != 'y');
fclose(output);
}
When I ran your function, I got all three numbers I entered in the file:
$ ./a.out
Give ID: 25
Exit? y/n y
Give ID: 33
Exit? y/n y
Give ID: 10
Exit? y/n n
$ cat Dane.txt
25
33
10
However, your question is backwards. You ask, "Exit? y/n" and then exit if the answer is "n" ("no"). The question should be "Continue? y/n", so that when the user answers in the affirmative, it continues.
Also, naming your output filehandle "input" is backwards, and as others have mentioned, your answer variable should be a character array of at least 2 characters, as char answer[2];.

User Input to File

I'm creating a program that should create a structure of a list of people entered by the user; the only problem I'm having is getting the user input data to appear in the text file. Anyone know how to do this? Here is the code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct person{
char name[20];
int age;
struct person *next_ptr;
} PERSON;
int main (void){
struct person PERSON;
FILE *fp;
char ans, ch;
int ppl=0;
fp=fopen("person_struct", "w");
if(fp != NULL){
while(ppl<25){
printf("Would you like to add a person to the list? [y/n] ");
scanf("%c", &ans);
if(ans == 'y') {
printf("\nEnter a name:\n");
scanf("%s", PERSON.name);
fprintf(fp, "%s",PERSON.name);
printf("\nEnter age:\n");
scanf("%i", &PERSON.age);
fprintf(fp, " %i\n", PERSON.age);
}
else {
ppl=25;
}
ppl++;
}
fclose(fp);
}
printf("\n\n\n");
system("pause");
return 0;
}
Youe scanf statement is wrong you forgot ampersand & operator before PERSON.age its int
scanf("%i", PERSON.age);
^ & missing
correct is:
scanf("%i", &PERSON.age);
You have two scanf stamens in your code to inputs from user one for string to scan name.
scanf("%s", PERSON.name);
This is correct and No need of & before string. But age is int and to scan int.float you need to add & before variable that is why added ampersand & before PERSON.age.
ref: scanf
Second:
fputs(PERSON.age, fp); is wrong syntax of fputs is:
int fputs( const char *str, FILE *stream );
^ you are passing int
first argument should be const char* but your are passing int
fputs(PERSON.age, fp);
^ wrong , age is int not char*
When you need formatting input/output prefer printf and scanf functions, My suggestion change your read/write like: (read comments)
printf("Enter a name:\n");
scanf("%s", PERSON.name); // here is No & because `name` is string
scanf("%i", &PERSON.age); // age is `int` so & needed
fprintf(fp,"%s %i\n",PERSON.name, PERSON.age);
EDIT: Because you commented, your code is working after these rectifications, see
$ gcc x.c -Wall
$ ./a.out
Would you like to add a person to the list? [y/n]y
Enter a name:
yourname
14
Would you like to add a person to the list? [y/n]y
Enter a name:
firendName
15
Would you like to add a person to the list? [y/n]n
sh: 1: pause: not found
$ cat person_struct.txt
yourname 14
firendName 15
In addition to Grijesh's answer:
Please explain scanf("%s", &ans);. How many characters can you store in ans? How many characters does the string "y" require to store? Verify your beliefs: printf("sizeof ans: %zu\n" "sizeoof \"y\": %zu\n", sizeof ans, sizeof "y");
Perhaps you meant: if (scanf("%c", &ans) != 1) { /* assume stdin has closed or reached EOF */ }. Note the %c, which will read only one character into ans.
Alternatively, if you change ans to an int, you can use: ans = getchar();
edit: In short, I think your loop should look something like this:
for (size_t ppl = 0; ppl < 25; ppl++){
int ans;
printf("Would you like to add a person to the list? [y/n]");
do {
ans = getchar();
while (ans >= 0 && isspace(ans));
if (ans != 'y') {
break;
}
printf("Enter a name:\n");
if (scanf("%s", PERSON.name) != 1 || scanf("%i", &PERSON.age) != 1) {
break;
}
fprintf(fp, "%s %i\n", PERSON.name, PERSON.age);
}

Resources