How to separate and store elements from a string in c? - c

I have to open a .txt file. Suppose that the content of the file is:
08123, (12/10/2010,M), (01/09/1990,D)
I want to store in different parameters of the string 08123, "12/10/2010" and 'M', for example:
int code = 08123;
char date[10] = '12/10/2010';
char day = 'M';
Also, the last argument finishes with ). How can I iterate it until the line ends?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct date {
char date[11];//+1 for '\0'.
char day;
} Date;
typedef struct rec {
int code;
int dc;//number of Date
Date *dates;
} Record;
Record *parse_rec(char *line){
static const char *sep = ", ";
static const int seplen = 2;//strlen(sep);
Record *rec = malloc(sizeof(*rec));
if(rec){
int i, count = 0;
char *p;
for(p=strstr(line, sep);p;p = strstr(p+seplen, sep)){
++count;
}
rec->dc = count;
rec->dates = malloc(count*sizeof(Date));
rec->code = atoi(line);
line = strstr(line, sep) + seplen;
for(i=0;i<count;++i){
sscanf(line, "(%[^,],%c", rec->dates[i].date, &rec->dates[i].day);
line = strstr(line, sep) + seplen;
}
}
return rec;
}
int main(void){
char line[1024];
FILE *fp = fopen("data.txt", "r");
fgets(line, sizeof(line), fp);
fclose(fp);
Record *rec = parse_rec(line);
printf("code: %05d\n", rec->code);
for(int i=0;i < rec->dc; ++i){
printf("date : %s\n", rec->dates[i].date);
printf(" day : %c\n", rec->dates[i].day);
}
free(rec->dates);
free(rec);
return 0;
}

Related

Strange characters when reading from file in C

So I am just trying to learn C and have decided to program a simple calendar where you can add events etc. It is working almost perfectly however, when it tries to read from the file containing the information, the first line contains some strange characters : �<�}�U1.
Code is as follows:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void createCalendar(char filename[]) {
FILE *cptr;
cptr = fopen(filename, "w");
char dates[177/sizeof(char)] = "";
for(int i = 1; i < 32; i++) {
char strtowrite[7/sizeof(char)] = "";
sprintf(strtowrite, "%d - \n", i);
strcat(dates, strtowrite);
}
fprintf(cptr, "%s", dates);
fclose(cptr);
}
void addToDay(char filename[], int day, char event[]) {
FILE *cptr;
cptr = fopen(filename, "r");
char *line = NULL;
size_t len = 0;
ssize_t read;
char dates[177/sizeof(char) + strlen(event)/sizeof(char)];
int i = 1;
while ((read = getline(&line, &len, cptr)) != -1) {
if (i==day) {
char strtowrite[7/sizeof(char) + strlen(event)/sizeof(char)];
sprintf(strtowrite, "%d - %s\n", i, event);
strcat(dates, strtowrite);
}
else {
strcat(dates, line);
}
i += 1;
}
printf("%s", dates);
fclose(cptr);
cptr = fopen(filename, "w");
fprintf(cptr, "%s", dates);
fclose(cptr);
}
int main() {
createCalendar("january");
addToDay("january", 12, "event");
}
and the first line of output is: í¬_<89>lU1 - (in the file)
Try this
char dates[177/sizeof(char) + strlen(event)/sizeof(char)] = {0};
in your addToDay function when declaring the dates variable. I think that you do not set the memory there, so there might be some junk in that memory location.

Number of words in n strings read from a file

So i am trying to determine number of words from n strings.The problem I have is that the when I read the number of the strings from the file it somehow count as a string I guess.I am trying to get rid of the first line of the output but can't tell how.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int numar_cuvinte(char *propozitie, char *copie, int numar_propozitii, FILE *f)
{
fgets(propozitie,49,f);
strcpy(copie,propozitie);
char *delimitatori = " ";
char *token = strtok(copie,delimitatori);
int numar_cuvinte = 0;
while(token!=NULL)
{
numar_cuvinte++;
token = strtok(NULL,delimitatori);
}
return numar_cuvinte;
}
int main()
{
FILE *f;
char*name_file = "in.txt";
f=fopen(name_file,"r");
if(f == NULL)
printf("Can't oppen %s",name_file);
int nr_strings;;
fscanf(f,"%d",&nr_strings);
char *propozitie = (char*)malloc(50*sizeof(char));
char *copie = (char*)malloc(50*sizeof(char));
for(int i = 0 ; i <= nr_strings ; i++)
printf("String : %s has %d words \n\n",propozitie,numar_cuvinte(propozitie,copie,nr_strings,f));
free(propozitie);
free(copie);
fclose(f);
return 0;
}

INI file reader function is addressing wrong values to my structure, How do I solve this?

This is for a project for university (small replica of a Catan game) and I'm struggling a bit with this part, we have the read an INI file with fairly simple formatting, it only has some comments starting with ';' and then it's just tags with a value in front:
xdim=4
ydim=5
N=D
S=L2
E=S10
W=D
etc...
I have this function to read from an INI file and address the read values to the correct struct element. But it seems like it doesn't even read the file, the struct is a simple struct with xdim and ydim, after I call the func xdim is '&d&d&d&d etc...' and ydim is 0
I've tried placing in some printf's just to see if the values from the INI file itself where being read wrong, but nothing is printed.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 128
typedef struct UNIT { /**struct used in an array for the rest of the INI values*/
char N[4];
char S[4];
char W[4];
char E[4];
char Building;
}UNIT;
typedef struct{ /**This is declared in main and passed to the functions*/
UNIT *grid;
unsigned int xdim;
unsigned int ydim;
} MAP_CONFIG;
void set_config_val(MAP_CONFIG *config, const char *key, int val) {
if (config == NULL)
return;
if (strcmp(key, "xdim") == 0){
printf("here");
config->xdim = val;
}
else if (strcmp(key, "ydim") == 0){
printf("here");
config->ydim = val;
}
else{
;
}
}
void read_config(MAP_CONFIG *config,FILE *f) {
char str[MAX];
char *token;
const char *delim = "=\n";
while (1) {
fgets(str, MAX, f);
if(feof(f)!= 0) break;
puts(str);
if (strchr(str, '=')!=NULL) {
char varname[MAX];
int value;
token = strtok(str, delim);
strcpy(varname, token);
token = strtok(NULL, delim);
value = atoi(token);
printf("&d", token);
set_config_val(config, varname, value);
}
}
config = malloc(sizeof(MAP_CONFIG));
config->grid = calloc(config->xdim * config->ydim, sizeof(UNIT));
close(f);
return;
}
open file function:
FILE *openFile(char *nome, char *mode) {
FILE *f;
printf("Opening file %s\n", nome);
f = fopen(nome, mode);
if (f == NULL) {
fprintf(stderr, "*** It was not possible to open the file %s.", nome);
exit(1);
}
return f;
}
test main im using:
int main(int argc, char **argv) {
MAP_CONFIG map;
MAP_CONFIG *mapa = &map;
FILE *f;
char *filename;
for (int i = 0; i < argc; i++)
printf("Parametro %d: %s\n", i, argv[i]);
if (argc >= 2) {
filename = argv[1];
}
else {
printf("Opening base map file..\n");
filename = "mapa.ini";
}
f = openFile(filename, "r");
read_config(mapa, f);
printf("%d %d", map.xdim, map.ydim);
return 0;
}
I just want it to read the xdim and ydim, and then repeat the process to an array of structs for each struct to get the correct value of the N,S,E,W present in the INI file... Help!

get "Bus error 10" : a program to take a file's data and calculate

This task is to get the first line as a title then calculate data from a file ,the minus number is by parentheses. It will print the title and he sum of these data. each line is terminated by newline character. I don't know what the problem is. I don't know how to deal with "Bus error 10". Maybe because of the allocation of memory, I have no idea... Can anyone help me?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Our definition of a structure to represent department data.
struct dept {
int id;
char *name;
int balance;
struct dept *next;
};
typedef struct dept dept_t;
// For (a)
dept_t *create_dept(int dept_id, char *dept_name, int dept_balance);
// For (b)
dept_t *load_dept(int id);
// For (c)
void free_dept(dept_t *dept);
// For (d)
void print_dept(dept_t *dept);
int main(int argc, char *argv[])
{
dept_t *d = load_dept(51423);
print_dept(d);
free_dept(d);
}
// (a)
dept_t *create_dept(int dept_id, char *dept_name, int dept_balance)
{
dept_t *d = malloc(sizeof(dept_t));
d->id = dept_id;
d->name = dept_name;
d->balance = dept_balance;
d->next = NULL;
return d;
}
// (b)
char *prompt(FILE *fp)
{
char ch;
// skip leading whitespace
do
{
fscanf(fp, "%c", &ch);
if(feof(fp))
{
return NULL;
}
} while(ch == '\n');
// read in until whitespace
int cur_size = 8;
char *str = malloc(sizeof(char) * cur_size);
int cur_pos = 0;
str[cur_pos] = ch;
cur_pos++;
do
{
fscanf(fp, "%c", &ch);
if(feof(fp))
{
str[cur_pos] = '\0';
return str;
}
str[cur_pos] = ch;
cur_pos++;
if(cur_pos >= cur_size - 1)
{
cur_size = cur_size * 2;
str = realloc(str, sizeof(char) * cur_size);
}
} while(ch != '\n');
str[cur_pos - 1] = '\0';
return str;
}
dept_t *load_dept(int id)
{
FILE *fp;
char *filename;
int balance = 0;
char *name;
char *string;
int i;
dept_t *d;
filename = malloc(sizeof(char)*10);
sprintf(filename,"%d.txt",id);
if((fp = fopen(filename,"r")) == NULL)
{
fprintf (stdout,"Can't open \"%s\"file.\n",filename);
exit(1);
}
name = prompt(fp);
int value;
for(i=0;i<6;i++)
{
string = prompt(fp);
if (string[0]=='(')
{
value = atoi(&string[1]);
balance = balance - value;
}
else
{
value = atoi(string);
balance = balance + value;
}
}
free(string);
free(filename);
if(fclose(fp)!=0)
{
fprintf(stderr,"Error closing file\n");
}
d = create_dept(id,name,balance);
return d;
}
// For (c)
void free_dept(dept_t *dept)
{
free(dept->name);
free(dept);
}
// For (d)
void print_dept(dept_t *dept)
{
printf("Department: %s",dept->name);
printf(" %d",dept->balance);
}
Since, as user3629249 noted, the function: prompt() can return a null pointer, you should change
for(i=0;i<6;i++)
{
string = prompt(fp);
to
while (string = prompt(fp))
{
(then less than 6 data lines won't cause a fault).

Segmentation fault (code dumped) error in C

I was trying to run this code and it is saying "Segmentation fault (code dumped)" how I can fix my code to make this error go away. here is my code so if someone could help me out that would be awesome! How can i fix my void SEARCH
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct _data {
char *name;
long number;
};
int SCAN(FILE *(*stream)){
int count = 0;
char line[256];
while (fgets(line, sizeof(line), *stream)) {
count++;
}
return count;
}
struct _data* BlackBoxLOAD(FILE **stream, int size){
struct _data* BlackBox = (struct _data*)malloc(sizeof(struct _data)*size);
int count = 0;
char line[256];
while (fgets(line, sizeof(line), *stream)) {
char* token = strtok(line, " ");
struct _data* temp = (struct _data*)malloc(sizeof(struct _data));
temp->name = token;
token = strtok(NULL, " ");
temp->number = atoi(token);
BlackBox[count] = *temp;
count++;
}
return BlackBox;
}
void SEARCH(struct _data *BlackBox, char *string, int size){
int i = 0;
for (i = 0; i<size; i++){
if (strcmp(BlackBox[i].name, string) == 0)
return i;
}
return -1;
}
void FREE(struct _data *BlackBox, int size){
free(BlackBox);
return;
}
int main(int argc, char **argv) {
int i = 0, size = 0;
FILE *stream = fopen("hw5.data", "r");
int noOfLines = SCAN(&stream);
size = noOfLines;
struct _data *BlackBox = BlackBoxLOAD(&stream, size);
fclose(stream);
for (i = 1; i<argc; i++){
if (argv[i] == "") {
printf("*******************************************");
printf("* You must include a name to search for. *");
printf("*******************************************");
}
int pos = SEARCH(BlackBox, argv[i], size);
if (pos == -1) {
printf("*******************************************");
printf("The name was NOT found.");
printf("*******************************************");
}
else{
printf("*******************************************");
printf("The name was found at the %d entry.", pos);
printf("*******************************************");
}
}
FREE(BlackBox, size);
}
There are just way too many bugs in this code, but here's the most obvious:
char* token = strtok(line, " ");
struct _data* temp = (struct _data*)malloc(sizeof(struct _data)*1000);
temp->name = token;
You're setting temp->name to the value of token. But token points into line, which is getting modified and will soon cease to exist because you created it on a stack that's about to go away.
You can't save a pointer to a chunk of memory that you're about to reuse.
After the following line has been executed
int noOfLines = SCAN(&stream);
stream is at the end of the file. You need to rewind it before you can read the data. Add the line:
frewind(stream);
after the call to SCAN.
As an aside, you should change the argument type of SCAN and BlackBoxLOAD to FILE*.
int SCAN(FILE *stream){
struct _data* BlackBoxLOAD(FILE *stream, int size){
That will make the calls easier and the functions don't have to dereference stream.
Function definition:
int SCAN(FILE *stream){
int count = 0;
char line[256];
while (fgets(line, sizeof(line), stream)) {
// Just stream, not *stream
count++;
}
return count;
}
Function call:
int noOfLines = SCAN(stream);
// Just stream, not &stream.

Resources