Segmentation error, C File handling program - c

Easy access program
Using linux first of all. I am trying to make a program that will first sign up a user in case he ain't got an account after that he will be directed to a login screen where he will enter his account details and then will be logged in. After that he will be given options to provide easy access to websites e.t.c. Like if the user enters 1 he will be directed to f.b, 2 for quora and so on. I successfully managed to code the program to the log in phase but i did it in a single function i.e main(), so i thought it would be nice if i had separate functions for performing specific tasks. I have coded it this time in separate functions, but i am getting segmentation error this time when i try to open FILE using fopen(). And also please tell me some way to open a website in a browser using console command. Like we have in windows (start www.facebook.com e.g). Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct user_data {
char name[50];
unsigned long password;
};
struct user_data new_user; // Will hold the data of new
struct user_data data_ver; // Will hold the data read
void sign_up(void);
void sign_in(void);
int main(void) {
beginning: // Beginning label in case of invalid input
printf("\t\t\t\t WELCOME TO EASY ACCESS APPLICATION");
printf("\n\n\nIf you have an account press 1.\n\nPress 2 for sign up.");
char user_choice; // Wil hold the
// user_choice i.e whether he wants to sign up / sign in
user_choice = getchar();
if (user_choice == '1') {
sign_in(); // In case of 1 goto sign in page
}
else if (user_choice == '2') {
sign_up(); // Opening file);
// In case of 2 goto sign up page
}
else {
printf("Invalid input. Try again.\n\n");
puts("Press any key to continue...");
getchar();
system("clear");
goto beginning;
}
return 0;
}
void sign_up(void) {
FILE *data = fopen("data.txt", "a");
if (data == NULL) {
printf("Unable to open file.");
scanf("%c");
system("clear");
}
system("clear");
printf("\t\t----------------------------\n"
"\t\t| |\n"
"\t\t| SIGN UP PAGE |\n"
"\t\t| |\n"
"\t\t----------------------------");
printf("\n\nName:");
scanf("%c"); // Dummy scanf
gets(new_user.name); // Getting name into the struct
printf("\nPassword.");
scanf("%lu", &new_user.password); // Getting pass into the struct
fprintf(data, "%s %lu\n", new_user.name, new_user.password); //Feeding data into FILE
system("clear");
printf("\n\nSign up complete. :) ");
printf("\n\nYou will now be directed to the sign in page. ");
printf("\nPress any key to contine...");
scanf("%c");
system("clear");
fclose(data);
}
void sign_in(void) {
}
I am getting the error on the first line of sign_up function where i am opening FILE.

scanf("%c") expects a pointer where the read character will be stored. scanf() doesn't know if you provided the pointer, it just read the destination address from the expected stack location. Effectively scanf() takes a random address and writes the character there.
Use getchar(); or char Dummy; scanf("%c",&Dummy);.

Related

C password database

I've created a program that let's you change the password from a file if you enter the previous password that was in that file.What I want to do is to be able to create a username that's gets assigned with a password.The username and the password should be written in the file without deleting anything that was there before.The program should also be able to validate the password for the username in the file.Here is my current code,but i can't manage to write multiple things in the given file.I don't want you to give me the code for my question, only the algorythm with some tips.Thank you!
#include<stdio.h>
#include <conio.h>
#include <fstream>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *passwords;
int p='*',i,j,count,triesLeft,a,numberofTries=0;
char password[5] = {0,0,0,0,0};
char passwordCheck[5] = {0,0,0,0,0};
passwords = fopen("passwords.txt","r");
printf("You have 3 tries to enter your password!\n");
for(count=0;count<3;count++)
{
numberofTries++;
triesLeft = 3 - count;
printf("You have %d tries left!\n", triesLeft);
printf("Enter your password: ");
scanf("%s", &passwordCheck);
fscanf(passwords,"%s",&password);
if(strcmp(password, passwordCheck) == 0)
{
numberofTries--;
printf("Press 0 if you want to set up a new password, press 1 to stop the program\n");
scanf("%d", &a);
if(a==0)
{
passwords = fopen("passwords.txt","w");
printf("New password:");
for(i=0;i<5;i++)
{
password[i] = getch();
putchar(p);
}
for(j=0;j<5;j++)
{
fprintf(passwords,"%c",password[j]);
}
}
else if(a==1)
{
printf("Old password still in place");
}
break;
}
else
{
printf("Wrong password!");
}
}
if(numberofTries == 3)
{
printf("You are out tries!");
}
fclose(passwords);
}
Have a look at the fopen documentation. The magic phrase here is "access mode". As you open the file, the FILE pointer points to a certain position inside of the file. By setting the appropriate access mode, you can choose where the position pointer will be placed when the file is opened. Maybe the function fseek is interesting for you, too. It allows you to move that pointer.
A few more tips for your code:
Make sure that you don't use to many unneccessary variables, since
they make your code confusing.
When you use fopen, always check wether the pointer is set correctly
(check for NULL), otherwise your program may crash with a
segmentation fault if it is unable to find or access the file.
In C everything that differs from 0 or NULL is true. That applies for
pointers as for numeric values. Feel free to use the negation
operator "!" in combination with such tests.

Why isn't my code terminating within a loop when checking for 'exit' string?

My program is supposed to exit when the user types in exit similar to how its done in a shell. First I checked online to see if syscall could be called in a loop, but then I noticed the indices of the characters in the array are wrong. Why are these changing; when I ran the program and typed in exit I had my program shoot out the 3rd index for testing purposes and it returned 'e'. So I thought it might've been flipped and flipped all values and my exit still did not work. Any thoughts on what the underlying issue may be?
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main() { //Memory allocation
char * entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='t' && entry[1]=='i' && entry[2]=='x' && entry[3]=='e')
{
//printf("Exiting");
exit(0); //exit(system call)
break;
printf("Inside of exit");
}
printf("msh> you typed %s %c %c %c %c",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}
I am sorry I don't have enough reputation points to add a comment, but #lundman is correct. I don't think you need to create a pointer to entry. Also, you are checking for "exit" in the reverse order. I tried and edited the code; this seems to work:
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main()
{ //Memory allocation
char entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='e' && entry[1]=='x' && entry[2]=='i' && entry[3]=='t')
{
printf("Inside of exit");//printf("Exiting");
exit(0); //exit(system call)
}
printf("msh> you typed %s %c %c %c %c\n",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}

C - Price look-up program

I was asked to make a C program that act as a 'price lookup' where a user enter a product name and the program will print it's name and price which is stored in a file. If the item is not present in the file, the program will let the user know. The program will keep looping as long as the user wants to search. I did the coding using Dev C++, however after i run the code, the program got stuck after a few loops, and it's random. Could you guys detect any problem with my coding, or is it just the problem with Dev C++? I include my code below. Your help is greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *items;
char *mode="r";
char pName[50];
float pPrice;
char p1Name[50];
int value=0;
char respond='Y';
char s[50];
items=fopen("Product_Name_Price.txt", mode);
if(items==NULL)
{
fprintf(stderr, "Can't open file Product_Name_Price.txt!\n");
exit(1);
}
printf("File has been successfully opened\n");
do
{
printf("Enter the name of the product you wish to look for\n");
scanf("%s", &p1Name);
while(strcmp(p1Name, pName) !=0)
{
fscanf(items,"%s %f", pName, &pPrice);
//printf("%s\t%.2f\n", pName, pPrice);
//value=strcmp(p1Name, pName);
if(strcmp(p1Name, pName) == 0)
{
printf("%s\t%.2f\n", pName, pPrice);
}
}
/*
else
{
printf("No data in system\n");
}
*/
printf("Do you wish to look up for more item? (Y/N)\n");
scanf("%s", &respond);
}while(respond=='Y'|| respond=='y');
printf("This program is closing\n");
fclose(items);
}
Your program has undefined behaviour because your scanf("%s", &response) reads into response as if it were an array of sufficient size for the string being read — that size is at least 2 (including null terminator), but response is just one character. You blew up your stack and corrupted memory and then all bets are off.
You could write scanf("%c", &response) instead to actually read a single character, though you'd be better off switching to modern, safer tools if you're writing a C++ program.

Whats wrong with fread in this program?

I'm intermediate student of C. I'm trying to make a bank management program but first I need to make a login program, so I created one of the following. As I've recently learned about file I/O in C and don't know much about fread and fwrite. I have a file (data.txt) which format if as following.
user1 1124
user2 3215
user3 5431
In the following program I've asked user to input user name and pin(4-digit password) and copy file data into a structure then compare these two for verifying information.
What is wrong with my program and how to make fread work properly. And is the formating in data.txt file all right or should I change it.
Thanks in advance...
#include<stdio.h>
#include<ctype.h>
#include<string.h>
struct user_account {
char u_name[30];
int u_pin;
} log_in;
int login()
{
int start;
int i, n;
int t_pin[4]; // TEMPORARY INT PIN for storing pin inputed by user
char t_name[30]; // TEMPORARY STRING for storing name inputed by user
FILE *fp;
fp = fopen("data.txt","rb"); // Opening record file
if(fp == NULL)
{
puts("Unable to open file!");
return 1;
}
start : {
printf("User Name : ");
scanf("%s",&t_name);
printf("Pin Code : ");
for(i = 0; i < 4; i++) { // This loop is for hiding input pin
n = getch();
if(isdigit(n)) {
t_pin[i] = n;
printf("*"); }
else {
printf("\b");
i--;
}
}
fread(&log_in,sizeof(log_in),1,fp);
// Comparing user name and pin with info in the structure copied from the file
if(strcmp(log_in.u_name, t_name) == 0 && log_in.u_pin == t_pin)
puts("Login successful! Welcome User");
else {
printf("\nIncorrect Information!\n");
printf("Press any key to log in again...");
getch();
system("cls");
goto start; }
}
}
int main()
{
int login();
return 0;
}
The problem is that you have an ASCII/text file but you are trying to use fread to read directly into a structure; this requires a binary formatted file. fread cannot do format conversion. Use fscanf instead:
fscanf(fp, "%s %d", &log_in.u_name, &log_in.u_pin);
Problems that I see:
The following line is incorrect.
scanf("%s",&t_name);
You need to use:
scanf("%29s",t_name);
fread is not the right solution given the file format. fread works when the file is in binary format.
Given the format of your input file, you need to use:
scanf("%29s %d", log_in.uname, &log_in.u_pin);
Comparing the pins using log_in.u_pin == t_pin should produce a compiler error. The type of log_in.u_pin is int while the type of t_pin is int [4]. You will have to change your strategy for getting the integer value from t_pin.
You can use something like:
int pin = 0;
for (i = 0; i < 4; ++i )
{
pin = 10*pin + t_pin[i];
}
However, for that to work, you have store the proper integer values in t_pin. When the character you read is '1', you have to store 1. Either that, or you will have to change the above for loop to:
pin = 10*pin + t_pin[i]-'0';
The way are using goto start to loop in your function is not correct. You haven't read all the user ID and pins to from the input file and compared them. The way you have it, you will end up doing:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Read the user name and pin again.
Check against the next entry in the file. If they don't match...
etc.
You want to:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
etc.
a) fread is used to read fixed sized (in bytes) records. While that is an option, you might find that fscanf is more suited to your use case.
b) goto has its uses, arguably, but in your particular case a while loop is far more appropriate as it make the intention clearer and is less susceptible to misuse.
c) The crux of your issue is reading the file. You only read in and check against a single record from your file per pass and once all records are read you will be getting EOF rather than additional records.
You have a few options. You might read the entire user table into a list prior to your login loop. When a user logs in you must iterate through the list until a match or end of list is found. Alternatively you might loop through the entire file on each user attempt looking for a match and seek to the back to the beginning of the file when you are done. In either case you must check for and handle read errors.
d) Finally when a non-digit is entered you will probably find that backspace isn't what you had in mind. Also you might consider allowing the user to press backspace while entering the pin.

junk characters from stdin after reading from file in C

After succesfully reading a re-directed file to my program from the console, I ask a user to enter a word, then use scanf() to read in the word.
The problem i'm having is that scanf() is immediately reading in junk characters and then the program continues. It doesn't even pause to let the user enter anything in the console. It doesn't happen when I don't open a file. EVERYTHING else works perfectly. What could be the issue:
**I tried everything suggested, still can't get it to work. I've made a new project that is just for getting this part to work, here it is. Ignore that scanf is only looking for a single character, even though I ask for a word. I did this just to see if the program would actually pause and allow me to enter something, but it doesn't. Just enters some garbage and program ends.
main(){
int n,i;
char ch;
char line[80];
while(fgets(line, 80, stdin) != NULL){
for(i=0;i<80;i++){
ch=line[i];
if(ch=='\n'){
printf("%c",ch);
break;
}
else{
printf("%c",ch);
}
}
}
printf("Please enter a word: ");
scanf("%c",&ch);
}
You can't re-direct stdin from a file and then also use the keyboard for input (that I know of). If you want to do that, it's simpler to have the program take the input file as a command-line argument and then run it like so: prog myfile.txt. Also, leave yourself a pad with fgets() -- use one less than the allocated array for maxlen. It's always safest with C char arrays to use one less than the allocated length for anything requiring a maximum length in case the maximum length is not including the '\0' terminating character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char *argv[])
{
FILE *f;
int i;
char line[80];
if (argc<2)
{
printf("Usage: %s <inputfile>\n",argv[0]);
exit(10);
}
/* Open file and echo to stdout */
f=fopen(argv[1],"r");
if (f==NULL)
{
printf("Cannot open file %s for input.\n",argv[1]);
exit(20);
}
while (fgets(line, 79, f) != NULL)
printf("%s",line);
fclose(f);
/* Get user input from stdin */
printf("Please enter a word: ");
if (fgets(line,79,stdin)==NULL)
{
printf("Nothing entered. Program aborted.\n");
exit(30);
}
/* Remove CR/LF from end of line */
for (i=strlen(line)-1;i>=0 && (line[i]=='\n' || line[i]=='\r');i--)
;
line[i+1]='\0';
printf("The word entered is: '%s'\n",line);
return(0);
}
sscanf is used to input from a stream or a buffer, and in unix stdin is considered as file so u are supposed to use fscanf which inputs from a file so use fscanf(stdin,"%s",testword);

Resources