I want to save some struct into a file and read all of them or modify them. I tried like this, but this way I got only the last saved structs, and I don't know how to get all of them, or how to modify them later in the file.
I don't get any error just the last saved structs, but in the file I see all of them if I open with a text editor.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#define MAX_STRING_LEN 80
#define PHONE_NUMBER 15
struct order {
time_t systime;
char name[MAX_STRING_LEN];
char email[MAX_STRING_LEN];
int phonenumber;
int size;
};
//functions
void saveToFiles(struct order *current);
void dbList(struct order *current);
//save into file
void saveToFiles(struct order *current) {
FILE * file=fopen("db.txt", "a");
if(file != NULL) {
fwrite(current, sizeof(struct order), 1, file);
// fwrite("\n", sizeof("\n"), 1, file); //If I broke the line then all of the reading get some numbers, without any meaning
fclose(file);
}
}
//list the db
void dbList(struct order *current) {
int option;
printf("list: \n 1 - ful list\n 2 - just names\n 3 - just size\n 0 - exit");
scanf(" %i", &option);
if(option == 0) {
exit(1);
}
if(option == 1) {
//loadList(1);
struct order *obj=malloc(sizeof(struct order));
FILE * file = fopen("db.txt","rb");
fseek(file, 0, SEEK_SET); //I tried to put the file read at the begining of the file
while(fread(obj, sizeof(struct order), 1, file)) {
printf("LOG: op1\n");
fread(obj, sizeof(struct order), 1, file);
printf("%s/%s/%d/%d\n", obj->name, obj->email, obj->phonenumber, obj->size);
}
if(feof(file)) {
printf("\n--END--\n");
}
else {
printf("Some error...");
}
}
}
//***
int main(k)
{
struct order current; //struct init
// current = malloc(sizof(*current));
int option = 1;
while(option != 0) {
printf(" " "\x1B[34m");
printf("0 exit \n 1 new \n 2 list \n \n " "\x1B[0m");
scanf(" %i", &option);
if(option == 1) {
getNewOrder(¤t);
}
if(option == 2) {
dbList(¤t);
}
}
return 0;
}
For write file, pls check if fseek() to SEEK_END and then do fwrite can help.
Related
I want to read data from txt file and save those data in variables not just print output. How do I save those data from text file in variables?
I tried like this and it did not work out:
int value1 ;
object2->value =&value1 ;
*(object2->value) = value1 ;
My txt file looks like this:
INT
A
5
and my code looks like this:
#include <stdio.h>
#include <stdlib.h> // For exit()
struct variable {
char type[10];
char name[10];
int value;
};
int main(){
struct variable *object2=malloc(sizeof(struct variable));
FILE * file= fopen("input.txt", "rb");
if (file != NULL) {
fread(object2, sizeof(struct variable), 1, file);
fclose(file);
}
int value1 ;
object2->value =&value1 ;
*(object2->value) = value1 ;
printf("%d\n",value1);
printf("%s/%s/%d\n",object2->type,object2->name,object2->value);
}
File format:
CHAR
B
6
INT
A
5
FLOAT
C
7
This is my solution:
#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h>
#define BUFF_SIZE 1024
#define NAME_TYPE_SIZE 10
#define VALUE_SIZE 20
#define NOT_ENOUGH_MEMORY 1
#define CANT_OPEN_FILE 2
#define FILE_ENDED 3
#define TOO_BIG_STR 4
#define CANT_FORMAT_VALUE 5
#define NOT_FOUND_LINE 6
#define SEARCH_NAME "A"
#pragma warning(disable : 4996) // for vs
struct variable {
char type[NAME_TYPE_SIZE];
char name[NAME_TYPE_SIZE];
int value;
};
int find_var_in_file(char* file_path, char* find_name, struct variable* dest);
int main()
{
struct variable* object2 = malloc(sizeof(struct variable));
if (NULL == object2)
{
printf("not enough memory");
return NOT_ENOUGH_MEMORY;
}
int error = find_var_in_file("input.txt", SEARCH_NAME, object2);
if (CANT_OPEN_FILE == error)
{
return printf("can't open file");
}
if (error == 0)
{
// Printing data to check validity
printf("read: type: %s name: %s value: %d", object2->type, object2->name, object2->value);
int a = object2->value;
// do stuff with a
}
else
{
if (error == NOT_FOUND_LINE)
{
printf("not find the var \"" SEARCH_NAME "\" in the file");
}
else
{
printf("error reading the file. error code: %d", error);
}
}
free(object2);
return 0;
}
int read_line(char* buffer, int buffer_size, char* dest, int dest_size, FILE* stream)
{
if (!fgets(buffer, buffer_size, stream))
{
return NOT_FOUND_LINE;
}
int read_len = strlen(buffer);
if ('\n' == buffer[read_len - 1])
{
if (read_len == 1)
{
return NOT_FOUND_LINE;
}
buffer[read_len - 1] = '\0'; // remove "\n" in the end
}
if (dest_size <= strlen(buffer)) // last chat is null
{
return TOO_BIG_STR;
}
strcpy(dest, buffer);
// clear the read
memset(buffer, '\0', read_len);
return 0;
}
int find_var_in_file(char* file_path, char* find_name, struct variable* dest)
{
char file_buffer[BUFF_SIZE] = { 0 }; // Buffer to store data
FILE* stream = fopen(file_path, "r");
if (NULL == stream)
{
return CANT_OPEN_FILE;
}
int error = 0;
while (1)
{
// read type
int read_type_result = read_line(file_buffer, BUFF_SIZE, dest->type, NAME_TYPE_SIZE, stream);
if (read_type_result != 0)
{
error = read_type_result;
break;
}
int read_name_result = read_line(file_buffer, BUFF_SIZE, dest->name, NAME_TYPE_SIZE, stream);
if (read_name_result != 0)
{
error = read_name_result;
break;
}
char value_buffer[VALUE_SIZE] = { 0 };
int read_value_result = read_line(file_buffer, BUFF_SIZE, value_buffer, VALUE_SIZE, stream);
if (read_value_result != 0)
{
error = read_value_result;
break;
}
if (0 == strcmp(find_name, dest->name))
{
if (1 != sscanf(value_buffer, "%d", &dest->value))
{
error = CANT_FORMAT_VALUE;
}
break;
}
}
fclose(stream);
return error;
}
You just need to call the function find_var_in_file like in main. I loop over all the lines of the file and search for the var name. If have formating error or not find the name of the var in the file return the error code.
If the file you are trying to read is a text file (which it is in your case), then use fgets() to read its content. Also, if its content has a consistent format, then consider using sscanf() to do your parsing.
I don't understand why you are using a pointer to struct variable to save data. You can simply use a struct variable object and access its fields with .
Your code should look something like that:
#include <stdio.h>
#include <stdlib.h> // For exit()
#include <string.h> // for strlen()
struct variable {
char type[10];
char name[10];
int value;
};
int main()
{
FILE *file = fopen("input.txt", "r");
if (!file) {
fprintf(stderr, "Could not read file\n");
return 1;
}
struct variable object2;
char buffer[1024];
while (fgets(buffer, 1024, file)) {
if (sscanf(buffer, "%9s %9s %d", object2.type, object2.name, &object2.value) != 3) {
fprintf(stderr, "Error parsing file\n");
fclose(file);
return 1;
}
printf("%s %s %d\n", object2.type, object2.name, object2.value);
}
fclose(file);
}
Now, if you want to store all the lines of your file into variables to use them later, then first you need to count the number of lines in your file (let's call it n) and second, allocate a dynamic array of size n.
fscanf(file,"%s\n%s\n%d\n",object2->type,object2->name,&object2->value);
I am trying to read text from a .txt file into arrays of a structure.
This is my code (I have played around with this a heap so apologies if it seems all over the place):
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <stdbool.h>
#include <time.h>
#include <string.h>
#include <ctype.h>
int main()
{
int i = 1;
int j = 0;
char temp[4];
struct userStruct { // a struct definition for the users;
char pin[5];
char first[26];
char last[26];
};
struct userStruct userList[10]; // an array of struct user to hold 10 users
struct userStruct * users;
users = &userList;
FILE * filePtr;
filePtr = fopen ("users.txt", "r");
if (filePtr != NULL)
{
fscanf(filePtr, "%s %s %s %s", users[i].pin[j], users[i].first[j], users[i].last[j], temp);
if (strcmp(temp, "\n"))
{
i++;
j++;
}
printf("PIN %s| First %s| Last %s|", users[i].pin[j], users[i].first[j], users[i].last[j]);
fclose(filePtr);
}
else
{
printf("Unable to open users.txt");
}
return 0;
}
The users.txt file contains the text:
1234 John Smith
5678 Barry Cool
Many thanks for the help.
You only want 3 conversion specifiers in the scanf. Try
if( 3 == fscanf(filePtr, "%4s %25s %25s", users[i].pin, users[i].first, users[i].last) ){ ...
The printf is also weird. Try:
printf("PIN %s| First %s| Last %s|", users[i].pin, users[i].first, users[i].last);
I'm currently working on a program that is suppose to read information from a text-file. The text-file contains a song list and I have created a struct that should be able to hold each song in a song list in my program.
I have divided the program in different files and they look something like this.
main.c
#include "FuncDek.h"
#include <locale.h>
#include <crtdbg.h>
int main()
{
//For swedish and check memory leak
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
setlocale(LC_ALL, "swedish");
//Create with starting size of 5
Song *ptr = (Song *)malloc(sizeof(Song) * 4);
int menuChoice = 0;
int nrOfSongs = 0;
//Read from file
readFromFile(ptr, &nrOfSongs);
system("pause");
do
{
system("cls");
menuChoice = menu();
switch (menuChoice)
{
case 1:
addSong(ptr, &nrOfSongs);
break;
case 2:
showList(ptr, nrOfSongs);
break;
case 0:
break;
default:
printf("\nFelaktigt val, försök igen\n");
system("pause");
break;
}
} while (menuChoice != 0);
free(ptr);
system("pause");
return 0;
}
FuncDek.h
#ifndef FUNCDEK
#define FUNCDEK
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char title[25];
char artist[25];
char year[4];
} Song;
int menu();
void addSong(Song *ptr, int *nrOfSongs);
void showList(Song *ptr, int nrOfSongs);
void readFromFile(Song *ptr, int *nrOfSongs);
#endif
and finally the FuncDek.c
#include "FuncDek.h"
#pragma warning(disable: 4996)
//Print all from list
void showList(Song *ptr, int nrOfSongs)
{
system("cls");
printf("Låtlista\n");
printf("-------------------------------\n");
for (int i = 0; i < nrOfSongs; i++)
{
printf("Title: %s", ptr[i].title);
printf("Artist: %s", ptr[i].artist);
printf("År: %s \n\n", ptr[i].year);
}
system("pause");
}
//Read from file
void readFromFile(Song *ptr, int *nrOfSongs)
{
FILE *fileOpen;
fileOpen = fopen("song.txt", "r+");
if (fileOpen == NULL)
{
printf("Something went wrong. Could't open file\n");
}
char line[100];
int counter = 0;
int nrOfSongsInList = 0;
/*Read all information to line*/
while (fgets(line, sizeof(line), fileOpen) != NULL)
{
if (counter == 0)
{
nrOfSongsInList = line[0] - '0';
counter++;
}
else if (counter % 2 == 1 && counter == 1)
{
strcpy(ptr[*nrOfSongs].title, line);
counter++;
}
else if (counter % 2 == 0)
{
strcpy(ptr[*nrOfSongs].artist, line);
counter++;
}
else if (counter % 3 == 0)
{
strcpy(ptr[*nrOfSongs].year, line);
counter = 1;
*nrOfSongs += 1;
}
}
fclose(fileOpen);
}
I can now read my text-file and store my songs in my stong struct and I have allocated memory for it.
My problems occure when I'm trying to use the showList function. I can print out the ptr[i].artist and ptr[i].title correct, but for some reason when I print the ptr[i].year it show the year + the title of the next song in the list.
My text-file looks like this and each row is ended with a '\n'.
4
Mr Tambourine Man
Bob Dylan
1965
Dead Ringer for Love
Meat Loaf
1981
Euphoria
Loreen
2012
Love Me Now
John Legend
2016
I can't understand why it prints out more than the year. I noticed that if I make the year array in my struct the same size as the other 2, the problem goes away. But I want to understand.
When I debugg in VS it says that it's stored the right values in the year arr.
Anyone know what I might have missed?
/* problem of qsorting
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define INPUT "doc.txt"
#define OUTPUT "output.txt"
#define MAX_SIZE 500
typedef struct student // here I declare stuctures
{
char name[20];
int index;
int code;
int grade;
char surname[20];
} student;
int cmpfunc (const void * a, const void * b) // initial part of qsort
{
return ( *(char*)a - *(int*)b );
}
int main()
{
int i=0, m=0;
int number=0;
FILE *fo;
FILE *fi;
char file[]={INPUT};
char file1[]={OUTPUT};
fo = fopen(file, "r"); // open the file
fi = fopen(file1, "w"); // open the file
student *studentPtr;
studentPtr = (student*) malloc(MAX_SIZE*sizeof(student));
// here I use mallocation
if(fo == NULL || studentPtr == NULL || fi == NULL)
{
perror("Error");
exit(1);
}
while (!feof(fo)) // reading of file
{
fscanf(fo,"%d %s %s %d %d",
&studentPtr[i].index,
studentPtr[i].name,
studentPtr[i].surname,
&studentPtr[i].code,
&studentPtr[i].grade);
i++;
}
i=m;
printf("please insert a number upto 7:\n");
// because there are only 7 raws in the file
scanf("%d",&number);
m=number;
if (number > 7)
{
printf("try again");
}
else
{
for(i=0;i<m;i++)
{
qsort(studentPtr[i].surname, 1, sizeof(char), cmpfunc); // ?
printf("%d %s %s %d %d\n", // printing out
studentPtr[i].index,
studentPtr[i].name,
studentPtr[i].surname,
studentPtr[i].code,
studentPtr[i].grade);
fprintf(fi,"%d %s %s %d %d\n", // writing in the file
studentPtr[i].index,
studentPtr[i].name,
studentPtr[i].surname,
studentPtr[i].code,
studentPtr[i].grade);
}
}
free(studentPtr);
fclose(fo);
fclose(fi);
return 0;
}
I am just beginner and sorry for obvious mistakes.
I cannot do qsorting properly.
i will attach txt file as a comment of this post.
could you guys tell me how to change first part of qsort not to get silly things, after that i will try to do that by myself
I'm trying to find if a record exists on a binary file by searching for a name.
Seems I'm not doing something right since the return of my "if" no matter the input it's always found when it doesn't exist.
The debugger states "if = A syntax error in expression", I'm not seeing it.
#ifndef DATA_PLAYER_H_INCLUDED
#define DATA_PLAYER_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Player
{
char nome[50];
int pontos;
}Players;
void ViewPont();
void SearchPont();
#endif // DATA_PLAYER_H_INCLUDED
--
#include "DATA_PLAYER.h"
void ViewPont()
{
Players pl;
FILE *fp;
int i, pontos;
fp = fopen("Pontuacoes.dat", "rb+");
while((fread(&pl, sizeof(Players),1, fp)) != 0 )
{
printf("%s %d\n", pl.nome, pl.pontos);
}
fclose(fp);
}
void SearchPont()
{
char nam[50];
char ch;
Players pl;
FILE * fp;
fp = fopen("Pontuacoes.dat","rb+");
printf("\n nome das pont\n");
fflush(stdout);
scanf("%s", nam);
printf("%s", nam);
while((fread(&pl, sizeof(Players),1, fp)) != 0)
{
if((strcmp(pl.nome, nam))==0);
{
printf("\nregisto encontrado\n");
}
}
fclose(fp);
}
Silly me..........
if(strcmp(pl.nome, nam) ==0);
-> ; that little detail....
if(strcmp(pl.nome, nam) ==0)