Whenever I attempt to write to a file, I am getting a segmentation fault. I don't have any access to software that can tell me where it's coming from since I'm at school. If anyone could help me out that would be great.
//OLMHash.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "OLMHash.h"
int main()
{
createAccount();
return 0;
}
struct account createAccount()
{
struct account *newAccount;
newAccount = (struct account *)malloc(sizeof(struct account));
printf("Enter userid: ");
scanf("%s", newAccount->userid);
printf("\nEnter password: ");
scanf("%s", newAccount->password);
char *output = malloc(sizeof(char) * 255);
strcpy(output, newAccount->userid);
strcat(output, "\t");
strcat(output, newAccount->password);
FILE* fp;
fp = fopen("accountslist.txt", "r");
fputs(newAccount->userid, fp);
free(output);
}
-
//OLMHash.h
struct account
{
char userid[32];
char password[12];
};
struct account createAccount();
You opened the file for reading instead of writing, and you did not check the action succeeded. Try
fp = fopen("accountslist.txt", "w");
if(fp == NULL) {
// get out code
exit(1);
}
When calling fopen, I was opening it for reading rather than writing. I physically created the file that way I can leave it as "reading"
Related
I'm a beginner in data structures with C, I have taken C programming but I've only touched a little bit on structures in the course and I have not kept up with it.
Anyways, I'm trying to make a program that will read data into an array of structures from a file and print out the contents of the array you have populated. I need help figuring this out.. I'm honestly not too sure if I'm doing this correctly either... :/
Any help is greatly appreciated, and thank you in advance! :)
This is what I tried so far
Here's my code:
FYI - The file I'm trying to open is DataFile.txt
#include<stdio.h>
#include <stdlib.h>
#define SIZE 10
#define ARRAY_SIZE 30
//Struct contains 3 fields, name, age, salary
typedef struct
{
char name[SIZE];
int age;
int salary;
} data;
data a[ARRAY_SIZE];
FILE * fp = fopen("DataFile.txt", "r");
if (fp == NULL)
{
printf("Error %s.\n", strerror(errno));
exit(1);
}
int GetData()
{
int i = 0;
fscanf(fp, "%s", a[i].name);
while(fp && i<ARRAY_SIZE)
{
fscanf(fp, "%d", &a[i].age);
fscanf(fp, "%d", &a[i].salary);
i++;
}
return i;
}
void ShowData( int records_read)
{
//Print text file data on screen
for(int i=0;i<records_read;i++)
{
printf("%s %d %d\n", a[i].name, a[i].age, a[i].salary);
}
}
int main()
{
char name[256];
int i = 0;
int records_read;
//Call the method, getData
i = GetData();
//Prompt and read input from the user
printf("Pick a number from 1 to 10:");
scanf("%d", &records_read);
//Call the method, showData
ShowData(records_read);
fclose(fp);
return 0;
}
The program works if I don't put this part of the code in:
FILE * fp = fopen("DataFile.txt", "r");
if (fp == NULL)
{
printf("Error %s.\n", strerror(errno));
exit(1);
}
BUT the output is just a list of zeros..
A quick answer: At first, try to split FILE * fp = fopen("DataFile.txt", "r"); into two parts as one is the variable declaration FILE * fp = NULL; and the other one is the assignment expression fp = fopen("DataFile.txt", "r");. And then keeps the part of the variable declaration out of all the functions, while moves both the part of the assignment and the if-statement if (fp == NULL){...} into function GetData(). The code might work in this case.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct student
{
int stuNum;
int point;
};
int newStudent(FILE* dataf, FILE* indexf);
int main(void)
{
FILE* datafile;
FILE* indexfile;
indexfile = fopen("indexDosyasi.txt", "a+");
datafile = fopen("veriDosyasi.bin", "wb+");
newStudent(datafile, indexfile);
fclose(datafile);
fclose(indexfile);
return 0;
}
int newStudent(FILE* dataf, FILE* indexf)
{
indexf = fopen("indexfile.txt", "a+"); // txt file
dataf = fopen("datafile.bin", "wb"); // binary file
if (dataf == NULL)
{
printf("error");
return -1;
}
struct student* last = (struct student*)malloc(sizeof(struct student));
printf("number of student \n");
scanf("%d", last->stuNum);
fprintf(indexf, "%d\t", last->stuNum);
fwrite(last, sizeof(struct student), 1, dataf);
// fwrite(&last->stuNum,sizeof(struct student),1,dataf);
return 0;
}
Hi , i am trying student add system with c , my datafile have to be binary file and my indexfile have to be txt file , stuNum and point have to be int value but i cant add stunum and point into datafile and indexfile , i dont understand how can i add ? i read a lot answer about this question but i didnt find answer i want .When i run this code and enter the student number is 875,it says 66955608268424 in the indexfile(txt) and it says �*~ in the datafile(binary).i cant understand where is mistake?
Can you help me?
Try this way:
int newStudent(...)
{
write(fileName, "what you want to write", strlen("what you want to write"))
}
And if it doesn't works, try to tranform your int to a character string. I thing it is the itoa() or atoi() function.
i would like to know how can i list all the current logged user and save it to a text file and list all files info on the current directory and save it as well using c. i have tried system("w"), system("ls -l") to list the users but it wont save using fprintf and the only output i get is 0 and nothing for ls -l. i'm relatively new into programming and linux. please help.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main()
{
char opt;
printf("Enter an Option A/B: ");
scanf("%c", &opt);
if (opt == 'A')
{
int list;
time_t tm;
time(&tm);
int i,j;
i = system("w");
j = system("ls -l");
printf("The Date and Time are: %s", ctime (&tm));
printf("\n");
FILE *fptr;
fptr = fopen("file1.txt", "w");
fprintf(fptr, "%s", ctime (&tm));
fprintf(fptr, "%i", i);
fprintf(fptr, "%j", j);
fclose(fptr);
}
else
{
printf("bye");
}
return 0;
}
Try this code with popen(), fgets read the file line at a time. You can replace printf function with anything you like.
#include <stdio.h>
...
FILE *fp;
int status;
char path[PATH_MAX];
fp = popen("ls *", "r");
if (fp == NULL)
/* Handle error */;
while (fgets(path, PATH_MAX, fp) != NULL)
printf("%s", path);
status = pclose(fp);
if (status == -1) {
/* Error reported by pclose() */
...
} else {
/* Use macros described under wait() to inspect `status' in order
to determine success/failure of command executed by popen() */
...
}
code source: https://pubs.opengroup.org/onlinepubs/009695399/functions/popen.html
After write data to the binary file, I changed the mode to "r" to read the file. The name of who is correct, but color and education are empty. Age is returned as a large integer number, which is I guess the address of the variable. So, what is wrong here?
Update: The answer of Retired Ninja and Thornkey almost solve my problem. The rest is if input of age is 26, but not other numbers, the program will not write correct input to file. Anyone know what is wrong here?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 100
typedef struct Person{
char name[MAXLEN];
int age;
char color[MAXLEN];
char education[MAXLEN];
} Person;
void create_person(Person *who){
printf("name: ");
fscanf(stdin, "%s", who->name);
printf("age: ");
fscanf(stdin, "%d", &(who->age));
printf("color: ");
fscanf(stdin, "%s", who->color);
printf("education: ");
fscanf(stdin, "%s", who->education);
}
void print_record(Person *who){
printf("name: %s\n", who->name);
printf("age: %d\n", who->age);
printf("color: %s\n", who->color);
printf("education: %s\n", who->education);
}
void load_db(FILE *fp, Person *who){
int result = fread(who, sizeof(who), 1, fp);
if(!result)
//printf("result%d", result);
printf("cannot load database");
}
FILE *connect_db (char *file_name, char *mode, Person *who){
FILE *fp = (FILE *)malloc(sizeof(100));
// open stream and load database from the file
if(strcmp(mode, "w") == 0){
fp = fopen(file_name, mode);
//load_db(conn); // load data from file
}else if(strcmp(mode, "r") == 0){
fp = fopen (file_name, mode);
load_db(fp, who); // load data from file
}else{
printf("incorrect mode");
}
return fp;
}
// save database to file
int save_db (FILE *fp, Person *who){
int result = fwrite(who, sizeof(who), 1, fp);
if(result){
return 0; // successfully save db
}
printf("cannot save db");
}
int main(int argc, char *argv[])
{
char answer[MAXLEN];
Person person;
Person *who = &person;
FILE *fp;
create_person(who);
fp = connect_db("record2.dat", "w", who);
save_db(fp, who);
print_record(who);
free(fp);
fclose(fp);
return 0;
}
fread() reads individual bytes. You want to read in numbers which you have printf'd.
Your files will look like this:
name: Samuel Thornkey
age: 24
colour: blue
education: PHD in computer science
But when you use fread, the program directly reads bytes from the file and fills them into the record. Your person will then contain:
char name[MAXLEN]: first MAXLEN characters i.e. "name: Samuel Thornkey\n age: 24\ncolour: blue\n" or something similar
int age: the rest of the characters, encoded as bytes, hence very large number
char color[MAXLEN]: empty
char education[MAXLEN]: empty
Instead, use fscanf:
fscanf(fp,"name:%s ",&who->name);
fscanf(fp,"age:%d ",&who->age);
and so on.
It's likely to be this:
free(fp);
fclose(fp);
You are not permitted to free memory that wasn't given to you by malloc (or realloc).
And, yes, you may think you've allocated it inside connect_db but (1) that's totally unnecessary, and (2) you overwrite the pointer when you call fopen.
In addition, save_db is using the size of the who pointer which will most likely not be the same as the type it points to.
So, make the following changes:
get rid of the call to malloc, just use FILE *fp; within connect_db.
get rid of the free(fp) within main.
in save_db, use sizeof(Person) rather than sizeof(who).
Here's a fixed version that may be of some help to you. It successfully fills in a Person, prints it, and writes it to the file. Then it reads the data back from the file into a different Person and prints it.
The structure is similar to what you had, but I made all the reading/writing explicit so you'd see the steps. In general it isn't a good idea to have functions that perform extra duties you might not always want. I also made create_person require no input for faster testing. Your input code looked okay, I just didn't want to type it every time.
One thing to keep in mind, if you plan to write binary data to a file you should open the file in binary mode ("wb" or "rb") to avoid line ending translation on systems that perform that on text files.
You might also consider that a file written on one system may not be readable on a different system if the size of the Person structure changes due to different alignment or int being a different size. Probably not an issue for you, but if it becomes one you might look into a different serialization scheme.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXLEN 100
typedef struct Person
{
char name[MAXLEN];
int age;
char color[MAXLEN];
char education[MAXLEN];
} Person;
void create_person(Person *who)
{
strcpy(who->name, "Fred Smith");
who->age = 21;
strcpy(who->color, "Red");
strcpy(who->education, "Some School");
}
void print_record(Person *who)
{
printf("name: %s\n", who->name);
printf("age: %d\n", who->age);
printf("color: %s\n", who->color);
printf("education: %s\n", who->education);
}
void load_db(FILE *fp, Person *who)
{
int result = fread(who, sizeof(*who), 1, fp);
if(!result)
printf("cannot load database");
}
FILE *connect_db(char *file_name, char *mode, Person *who)
{
FILE *fp = NULL;
if(strcmp(mode, "w") == 0)
{
fp = fopen(file_name, mode);
}
else if(strcmp(mode, "r") == 0)
{
fp = fopen(file_name, mode);
}
else
{
printf("incorrect mode");
}
return fp;
}
int save_db(FILE *fp, Person *who)
{
int result = fwrite(who, sizeof(*who), 1, fp);
if(result)
{
return 0;
}
printf("cannot save db");
return -1;
}
int main(int argc, char *argv[])
{
FILE* fp = NULL;
Person who1;
Person who2;
create_person(&who1);
print_record(&who1);
fp = connect_db("record2.dat", "w", &who1);
save_db(fp, &who1);
fclose(fp);
fp = connect_db("record2.dat", "r", &who2);
load_db(fp, &who2);
print_record(&who1);
fclose(fp);
return 0;
}
I have question about reading data from file to structures
when I tried to run this code i get unhandled exception Access violation reading location 0xcccccce0, The error occur inside the getData function, Why am I getting this error, how Should I fix the code ?
this is my input file
4
A,10
B,12
C,60
D,120
tutorY
my intention in the getData function was to first read the first line to get then number 4, then use that number to allocate for student structure and then read the next four lines of the file in to student structure fields and then read the last line into tutorname feild in the TUTOR structure.
thank in advance
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "queue.h"
#include "stack.h"
#define RECORDS_SIZE 100
#define NAME_SIZE 20
typedef struct Student
{
char nameStudent[NAME_SIZE];
int TimeIn;
int TimeUpdate;
}STUDENT;
typedef struct TUTOR
{
char nameTutor[NAME_SIZE];
int TutorTIme;
STUDENT *ptr;
}TUTOR;
QUEUE *queue1;
STACK *stack1;
void getData(STUDENT *studentArr[RECORDS_SIZE], TUTOR tutorArr[1]);
int main (void)
{
STUDENT *studentArr[RECORDS_SIZE];
TUTOR tutorArr[1];
FILE *fp = NULL;
getData(studentArr, tutorArr);
return 0;
}
void getData(STUDENT *studentArr[RECORDS_SIZE], TUTOR tutorArr[1])
{
FILE *fp;
char fileName[NAME_SIZE];
char buffer[RECORDS_SIZE];
int first = 0;
int count = 1;
printf("Enter file name: ");
gets(fileName);
fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("Error! The file does not exist!\n");
}
fscanf(fp,"%d",&first);
*studentArr = (STUDENT*) malloc(first*sizeof(STUDENT));
while( fgets(buffer, first +1, fp) != NULL)
{
if (count <= first)
{
sscanf(buffer, "%[,]%d", studentArr[count]->nameStudent, studentArr[count]->TimeIn);
printf("%s,%d", studentArr[count]->nameStudent, studentArr[count]->TimeIn);
}
else
sscanf(buffer, "%s", tutorArr[count].nameTutor);
count++;
}
return;
}
There's a couple of problems I have spotted.
The first fscanf reading first will read the first number then leave the rest of the line ("\n") to be picked up by the first call to fgets
More importantly, studentArr is an array of pointers, presumably one element for each student, but the malloc allocates only the first pointer in sudentArr, all the others contain garbage, which is causing the access violation.
fix like this
void getData(STUDENT **studentArr, TUTOR tutorArr[1]);//change
int main (void)
{
STUDENT *studentArr;//change
TUTOR tutorArr[1];
FILE *fp = NULL;//not use
getData(&studentArr, tutorArr);//change
return 0;
}
void getData(STUDENT **studentArr, TUTOR tutorArr[1])
{
FILE *fp;
char fileName[NAME_SIZE];
char buffer[RECORDS_SIZE];
int first = 0;
int count = 1;
printf("Enter file name: ");
gets(fileName);//has risk
fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("Error! The file does not exist!\n");
return;//add, can't continue
}
fscanf(fp,"%d\n",&first);//add, consumption '\n'
*studentArr = (STUDENT*) malloc(first*sizeof(STUDENT));
while( fgets(buffer, RECORDS_SIZE, fp) != NULL)//change buffer size
{
if (count <=first)//
{
sscanf(buffer, "%[^,],%d", (*studentArr)[count-1].nameStudent, &(*studentArr)[count-1].TimeIn);//add, `,` and -1 to count is 1 origin, `&` need for "%d"
printf("%s,%d\n", (*studentArr)[count-1].nameStudent, (*studentArr)[count-1].TimeIn);
++count;//need count up
}
else
sscanf(buffer, "%s", tutorArr[0].nameTutor);
}
return;//need allocate record size return to main
}
Some more problems:
count should be initialised to 0 not 1 because your array is zero-indexed.
You're not incrementing count in your loop
Allocate memory for each student inside the loop with studentArr[count] = new Student();
Prefer strtok to sscanf` to split the buffer into fields. Much easier to deal with the comma following the string.