Printing to a file in C - c

How do I print to an empty .txt file I already have created?
I already print the results to the console, and now I want to print to a file named "Output.txt". I've tried a couple of things that haven't worked, but I think it was easier to create a duplicate printDictionary() specifically for printing to a file called printDictionaryToFile(). I'm a little lost on how to do it though. Can anyone correct me on where I went wrong? I already added an extra FILE type called *out for my output to a file.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stddef.h>
#define PUNC " \t\n\r,;.:!()[]{}?'\""
typedef struct node node;
typedef struct node {
char *word;
int count;
node *left;
node *right;
} node;
void insert(node ** dictionary, char * word) {
int result;
node * entry;
if (word == NULL || dictionary == NULL)
return;
if (*dictionary == NULL) {
entry= (node *) malloc(sizeof(node));
strcpy( entry->word= (char *) malloc(strlen(word) + 1), word);
entry->left= entry->right= NULL;
entry->count= 1;
*dictionary= entry;
return;
}
result = strcmp(word, (*dictionary)->word);
if ( result < 0 )
insert(&(*dictionary)->left, word);
else if (result > 0)
insert(&(*dictionary)->right, word);
else
++(*dictionary)->count;
return;
}
void printDictionary(node * dictionary) {
if (dictionary == NULL)
return;
printDictionary(dictionary->left);
printf( "%s = %d\n", dictionary->word, dictionary->count);
printDictionary(dictionary->right);
return;
}
void printDictionaryToFile( node * dictionary ) {
if (dictionary == NULL)
return;
printDictionaryToFile(dictionary->left);
fprintf(out, "%s = %d\n", dictionary->word, dictionary->count);
printDictionaryToFile(dictionary->right);
return;
}
void freeDictionary( node ** dictionary ) {
if (dictionary == NULL || *dictionary == NULL)
return;
freeDictionary(&(*dictionary)->left);
freeDictionary(&(*dictionary)->right);
free((*dictionary)->word);
free(*dictionary);
*dictionary= NULL;
return;
}
int main( int argc, char *argv[] ) {
FILE *fp, *out;
out = fopen("Output.txt", "w");
char b[1000], *s;
node *dictionary= NULL;
int i;
for (i= 1; i < argc; ++i) {
if ((fp = fopen(argv[i], "r")) == NULL) {
fprintf(stderr, "File %s can not be opened.\n", argv[i]);
continue;
}
for (s = fgets(b, sizeof(b), fp); s != NULL; s = fgets(b, sizeof(b), fp)) {
char *word;
for (word= strtok(b, PUNC); word != NULL; word = strtok(NULL, PUNC))
insert(&dictionary, strlwr(word));
}
fclose(fp);
}
printDictionaryToFile(dictionary);
printDictionary(dictionary);
freeDictionary(&dictionary);
return 0;
}

You can use the fprintf() function, which is quite similar to printf() in the way it works.
Here is an example:
FILE *fp;
int myInt = 5;
fp = fopen("Output.txt", "w");// "w" means that we are going to write on this file
fprintf(fp, "This is being written in the file. This is an int variable: %d", myInt);
fclose(fp); //Don't forget to close the file when finished
The output on your file would be this:
This is being written in the file. This is an int variable: 5
Worth to mention that opening the file using w as parameter will destroy the file's content every time you open it.

Related

when using fread() on a partial line, how do you move to the next line?

Im using fread() and fseek() togather to gather parts of a string. I'm not using fread() on the whole line though.
I'd take the whole line but to my knowledge you cannot use fseek() on a character array correct?
`int parse(const char *f, const struct stat *flightD, int type){
//file pointer
Airport_S *Air_Pts = (Airport_S *)malloc(sizeoftype(Airport_S));
FILE *fp;
//char need[10];
char airLineFile[2];
char chkAirPt[3];
fp = fopen(f, "r");
if(type == FTW_F){ // test for 'type' of FTW_F
//check to see if the file opened successfully
if(fp == NULL)
printf("Cannot open file %s", f)
return 1;
while (!(FEOF)){
//fgets(need,10,fp)
//must return zero to parent funtion to continue tree traversal
// ?? While current dir != originally called dir?
//open the file, read it's contents and assess them
fseek(fp, 5, SEEK_SET) //set FP to right before airport code
chkAirPt = fread(chkAirPt,sizeof(char),3, fp)
fseek(fp,0,SEEK_SET);
//combine the airline abbreviation with '.txt'
airLineFile = strcat(fread(airLineFile, sizeof(char), 2, fp),".txt");
//if the struct has no values in it, populate it with this first one.
if(Air_Pts->airport == NULL){
//Set info for very first node
Air_Pts->airPt=strcpy(Air_Pts->airport, chkAirPt);
fseek(fp,0,SEEK_SET);
Air_Pts->fltInfo->airLine=airLineFile;
Air_Pts->fltInfo->next = NULL;
Air_Pts->fltInfo->prev = NULL;
Air_Pts->next = NULL;
Air_Pts->prev = NULL;
//what is the file going to do after this?
}
else if(strcmp(Air_Pts->airport, chkAirPt) == 0){
if(strcmp(Air_Pts->fltInfo->airLine, airLineFile) == 0){
Air_Pts->fltInfo->occ++;
}
else
Air_Pts->fltInfo = addAirline(Air_Pts->fltInfo);
}
// some code
return 0;
else //anything other than a file -or- FTW_D
return 1;
}
}
}`
You are working too hard. Just read and discard the data you don't need. For example:
/* Sample input line: AA43 DTW2315 ... */
/* Read first two columns of each line of a text file into a struct */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct data {
char airport[32];
char flight[32];
struct data *next;
};
FILE * Fopen(const char *path, const char *mode);
void * xmalloc(size_t);
void
push(struct data **head, struct data new)
{
struct data *t = xmalloc( sizeof *t);
t->next = *head;
strncpy(t->airport, new.airport, sizeof t->airport);
strncpy(t->flight, new.flight, sizeof t->flight);
*head = t;
}
int
main(int argc, char **argv)
{
FILE *ifp = argc > 1 ? Fopen(argv[1], "r") : stdin;
struct data *head = NULL;
struct data this;
int line = 1;
int c = 0;
while( (c = fscanf(ifp, "31%s %31s", this.airport, this.flight)) == 2) {
push(&head, this);
/* Discard until the end of line */
while( (c = fgetc(ifp)) != EOF ) {
if( c == '\n') {
line += 1;
break;
}
}
}
/* Print all the records in reverse order */
for( ; head; head = head->next ) {
printf(" %s: %s\n", head->airport, head->flight);
}
return 0;
}
FILE *
Fopen(const char *path, const char *mode)
{
FILE *rv = fopen(path, mode);
if( rv == NULL ) {
perror(path);
exit(EXIT_FAILURE);
}
return rv;
}
void *
xmalloc(size_t s)
{
void *rv = malloc(s);
if( rv == NULL ) {
perror("malloc");
exit(EXIT_FAILURE);
}
return rv;
}

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!

Searching, inserting, outputing from binary search tree.

How can i do above things in one single programme with multiple duplicates keys and csv. type input data file?
EDIT: assumed KEY "," DATA "\n" (no whitespace, for brevity) and appended a short sketch at the end such that the OP has a start.
I cannot repair it because I don't know the input but I can point out some of the errors you made. See comments in code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXNAMELENTH 64
#define MAXDATALENTH 1465
typedef struct node {
char name[MAXNAMELENTH];
char data[MAXDATALENTH];
struct node *left;
struct node *right;
} node;
node *root;
node *search(node ** tree, char *key, int count, FILE * fp_out);
node *insertion(node * r, char *key, char *value);
void deltree(node * tree);
char *strtok_r(char *str, const char *delim, char **nextp);
int main(int argc, char *argv[])
{
node *root;
node *tmp;
FILE *fp;
FILE *outputfile;
FILE *keyfile;
FILE *fp_key;
int i;
int counter = 0;
int bufsize = MAXDATALENTH + MAXNAMELENTH;
int keyfilelen = MAXNAMELENTH;
char *keyread;
char *buffer, *saveptr;
char *line = NULL;
char *keyin = NULL;
char *valuein = NULL;
char inputkey[MAXNAMELENTH];
char *target_key = NULL;
char *keyline = NULL;
root = NULL;
/* Inserting nodes into tree */
buffer = (char *) malloc(bufsize * sizeof(char));
if (buffer == NULL) {
// use the proper macros, please
exit(EXIT_FAILURE);
}
// Check outputs! Always check outputs!
// I just assume that it has not been done here for simplicity
// and fear of posting-size limits (limit is 30k IIRC, that's a lot of code)
fp = fopen(argv[1], "r");
outputfile = fopen("outputfile.txt", "a");
// this is an infinite loop. How do you break out?
while (1) {
// fgets() returns NULL in case of EOF and error
// (yes, both, so check, e.g.: with ferror())
fgets(line, bufsize, fp);
buffer = line;
// I'm not fully sure, but I think you wanted a "=" instead of a ","
// Please switch on warnings for your compiler
keyin, strtok_r(buffer, ",", &saveptr);
// NUL delimited? Really? Are you sure strtok_r() can handle it?
valuein = strtok_r(NULL, "\0", &saveptr);
// insertion() returns a node
insertion(root, keyin, valuein);
}
/* Search node into tree */
// Wrong type: keyfile is a filepointer (FILE *), not a string (char *)
if (scanf("%s", keyfile) != EOF) {
// hu? Please switch on warnings for your compiler
keyfile = fopen(argv[4], "r");
// where's keyfile? Gone?
while ((fgets(keyline, keyfilelen, fp_key))) {
keyread = strtok_r(keyline, "\n", &saveptr);
search((&root), keyread, counter, outputfile);
}
// Please use braces, even here, thank you
if (keyline) {
free(keyline);
}
fclose(keyfile);
}
// This reads keys given as arguments at programstart,
// that's not what the teacher wanted
for (i = 3; argv[i] != NULL; i++) {
target_key = argv[i];
search((&root), target_key, counter, outputfile);
}
// This program does not read from stdin.
// Hint: stdin is also nothing more (although slightly less) than a file
// but it is already open and you don't close it
// (but it may not exist at all, so check first)
/* Deleting all nodes of tree */
deltree(root);
fclose(fp);
fclose(outputfile);
return 0;
}
node *insertion(node * r, char *key, char *value)
{
if (r == NULL) // BST is not created created
{
r = (node *) malloc(sizeof(node)); // create a new node
// insert data to new node
strcpy(r->name, key);
strcpy(r->data, value);
// make left and right childs empty
r->left = NULL;
r->right = NULL;
}
// if the data is less than node value then we must put this in left sub-tree
else if (strcmp(key, r->name) < 0) {
r->left = insertion(r->left, key, value);
}
// else this will be in the right subtree
else if (strcmp(key, r->name) > 0) {
r->right = insertion(r->right, key, value);
} else {
if (strcmp(value, r->data) > 0) {
r->left = insertion(r->left, key, value);
} else if (strcmp(value, r->data) < 0) {
r->right = insertion(r->right, key, value);
}
// what if both, name and data are equal?
}
// if you don't want to do anything with the returned
// node than don't return it. Just an int indicating error
// or something in the line
return r;
}
void deltree(node * tree)
{
if (tree) {
deltree(tree->left);
deltree(tree->right);
free(tree);
}
}
// searching does not compare the same way as inserting
node *search(node ** tree, char *key, int count, FILE * fp_out)
{
if (!(*tree)) {
return NULL;
}
if (strcmp(key, (*tree)->name) < 0) {
search(&((*tree)->left), key, count, fp_out);
count++;
} else if (strcmp(key, (*tree)->name) > 0) {
search(&((*tree)->right), key, count, fp_out);
count++;
} else if (strcmp(key, (*tree)->name) == 0) {
// won't print anything, because you return before the printing
return *tree;
fprintf(fp_out, "%s --> %s\n", key, (*tree)->data);
} else {
fprintf(fp_out, "%s --> NOTFOUND", key);
}
printf("%s --> %s\n", key, count);
// nothing to return here?
}
// Thank you for the proper reference!
// Seems to grow less and less usual these times.
/*
* public domain strtok_r() by Charlie Gordon
*
* from comp.lang.c 9/14/2007
*
* http://groups.google.com/group/comp.lang.c/msg/2ab1ecbb86646684
*
* (Declaration that it's public domain):
* http://groups.google.com/group/comp.lang.c/msg/7c7b39328fefab9c
*/
char *strtok_r(char *str, const char *delim, char **nextp)
{
char *ret;
if (str == NULL) {
str = *nextp;
}
str += strspn(str, delim);
if (*str == '\0') {
return NULL;
}
ret = str;
str += strcspn(str, delim);
if (*str) {
*str++ = '\0';
}
*nextp = str;
return ret;
}
EDIT: the sketch. Please be aware that I didn't do all of your homework, I left a bit "for the student", as the saying goes.
/*
*
* - Construct a binary search tree to store the information contained in the file specified
* in the command line argument. Each record should be stored in a separate Node.
*
* - Search the binary search tree for records, based on their keys. The keys are read in
* from stdin, i.e. from the screen.
*
* For testing, it is often convenient to create a file of keys to be searched, one per line, and redirect the input from this file.
*
* Use the UNIX operator < for redirecting input from a file.
*
* - Examples of use:
* ./yelp1 datafile outputfile then type in keys;
* or
* ./yelp1 datafile outputfile < keyfile
*
* - Your program will look up each key and output the information (the data found) to the output
* file specified by the second command line parameter.
*
* If the key is not found in the tree,you must output the word NOTFOUND.
*
* The number of key comparisons performed during both successful and unsuccessful lookups
* have to be written to stdout.
*
* - Remember that the entries in the file do not necessarily have unique keys.
* Your search must locate all keys matching the search key, and output all the data found.
*/
/*
* Tested with datafile produced by the following shellcode
*
* # KEY "," DATA
* counter=1;
* while [ $counter -le 100 ];
* do counter=$((counter + 1));
* echo $(pwgen 10 1)","$(pwgen 10 1) >> testtree.db
* done;
*
* # ten random KEY
* shuf -n10 testtree.db | sed -e 's/,[a-z]\+//g' > testtree10keys
*
* # ten random DATA
* shuf -n10 testtree.db | sed -e 's/[a-z]\+,//g' > testtree10datas
*
* Please insert doublettes manually
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// data produced has only 10 characters each (plus NUL)
#define MAXNAMELENTH 11
#define MAXDATALENTH 11
typedef struct node {
char name[MAXNAMELENTH];
char data[MAXDATALENTH];
struct node *left;
struct node *right;
} node;
node *root;
node *search(node ** tree, char *key, int *count, FILE * fp_out);
int insertion(node ** r, char *key, char *value);
void deltree(node * tree);
//char *strtok_r(char *str, const char *delim, char **nextp);
void bt_print(node * leaf);
int main(int argc, char *argv[])
{
node *root;
// node *tmp;
FILE *fp;
FILE *outputfile;
// FILE *keyfile;
// FILE *fp_key;
// int i;
int counter = 0;
int bufsize = MAXDATALENTH + MAXNAMELENTH + 2;
// int keyfilelen = MAXNAMELENTH;
// char *keyread;
char *buffer;
// char *saveptr;
// char *line = NULL;
char *keyin = NULL;
char *valuein = NULL;
// char inputkey[MAXNAMELENTH];
// char *target_key = NULL;
// char *keyline = NULL;
char *e;
int res;
char *comma;
root = NULL;
// must have at least one argument
if (argc < 2) {
fprintf(stderr, "Usage: %s datafile [< key-list]\n", argv[0]);
exit(EXIT_FAILURE);
}
/* Inserting nodes into tree */
buffer = malloc(bufsize);
if (buffer == NULL) {
fprintf(stderr, "Malloc failed\n");
exit(EXIT_FAILURE);
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
fprintf(stderr, "Opening \"%s\" for reading failed\n", argv[1]);
exit(EXIT_FAILURE);
}
outputfile = fopen("outputfile.txt", "a");
if (fp == NULL) {
fprintf(stderr, "Opening \"outputfile.txt\" for appending failed\n");
exit(EXIT_FAILURE);
}
while ((e = fgets(buffer, bufsize, fp))) {
if (e == NULL) {
if (ferror(fp)) {
// TODO: check errno for the exact kind of error
fprintf(stderr, "An eror occured during reading \"%s\"\n", argv[1]);
exit(EXIT_FAILURE);
} else if (feof(fp)) {
break;
}
}
// assuming strict KEY","DATA"\n" and without whitespace
// otherwise you need to check every step here!
// valuein points to the comma before DATA
valuein = strchr(buffer, ',');
// valuein points to DATA
valuein++;
// DATA is 10 characters large
valuein[10] = '\0';
// comma points to the comma before DATA
comma = strchr(buffer, ',');
// make *comma NUL
*comma = '\0';
keyin = buffer;
// ignoring return for now
//printf("%s,%s\n",keyin, valuein);
(void) insertion(&root, keyin, valuein);
}
bt_print(root);
// search-keys come from either stdin or get typed in.
// things typed in are also stdin
while ((res = scanf("%10s", buffer)) == 1) {
//printf("%s\n",buffer);
search(&root, buffer, &counter, outputfile);
printf("Misses for KEY \"%s\" = %d\n", buffer, counter);
counter = 0;
}
/* Deleting all nodes of tree */
deltree(root);
fclose(fp);
fclose(outputfile);
return 0;
}
void bt_print(node * leaf)
{
if (leaf) {
printf("%s,%s\n", leaf->name, leaf->data);
bt_print(leaf->left);
bt_print(leaf->right);
}
}
int insertion(node ** r, char *key, char *value)
{
if (*r == NULL) {
*r = malloc(sizeof(node));
if (r == NULL) {
return 0;
}
strcpy((*r)->name, key);
strcpy((*r)->data, value);
(*r)->left = NULL;
(*r)->right = NULL;
}
// Checks for returns omitted for clarity
else if (strcmp(key, (*r)->name) < 0) {
insertion(&(*r)->left, key, value);
}
// else this will be in the right subtree
else if (strcmp(key, (*r)->name) > 0) {
insertion(&(*r)->right, key, value);
} else {
if (strcmp(value, (*r)->data) > 0) {
insertion(&(*r)->left, key, value);
} else if (strcmp(value, (*r)->data) < 0) {
insertion(&(*r)->right, key, value);
}
// what if both, name *and* data are equal?
return 0;
}
return 1;
}
void deltree(node * tree)
{
if (tree) {
deltree(tree->left);
deltree(tree->right);
free(tree);
}
}
// search still cannot find multiple occurences of KEY
// Can you repair it?
node *search(node ** tree, char *key, int *count, FILE * fp_out)
{
node *tmp;
if (!(*tree)) {
printf("%s --> NOTFOUND\n", key);
fprintf(fp_out, "%s --> NOTFOUND", key);
return NULL;
} else {
if (strcmp(key, (*tree)->name) < 0) {
tmp = search(&((*tree)->left), key, count, fp_out);
(*count)++;
return tmp;
} else if (strcmp(key, (*tree)->name) > 0) {
tmp = search(&((*tree)->right), key, count, fp_out);
(*count)++;
return tmp;
} else {
// HINT 1: check (*tree)->left->name and (*tree)->right->name
// (recursively) and print it as long as key==name
// HINT 2: you don't need recursion, you can do it in a loop
printf("FOUND KEY %s --> DATA %s\n", key, (*tree)->data);
fprintf(fp_out, "%s --> %s\n", key, (*tree)->data);
return *tree;
}
}
}

How would I read a text file in C?

I have file.txt with
123456 2,00 beer
234567 2,50 milk
345678 3,30 ice cream
I want to put this info in my dynamic two-dimensional array:
char **dataBase;
dataBase = (char**)malloc(NUM_OF_PROD * sizeof(char*));
for(i = 0; i < NUM_OF_PROD; i++){
dataBase[i] = (char*)malloc(MAX_BUFFER* sizeof(char));
}
But I don't know how. We have here 3 lines. If it was a C++, I would use getline() but in this situation I can't find a solution.
I usually use the fgets() function to a file on a line-per-line basis (provided it is a text file).
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#define LINELEN 200
#define NAMELEN 40
struct PRICELIST
{
char item[NAMELEN];
float price;
unsigned int order_no;
struct PRICELIST *next;
struct PRICELIST *prev;
};
void list_print_node (struct PRICELIST *node)
{
printf ("%d %4.2f %s\n", node->order_no, node->price, node->item);
}
void list_print (struct PRICELIST *head)
{
printf ("Order # Price Item\n");
printf ("------------------------------\n");
while (head)
{
list_print_node (head);
head = head->next;
}
}
void list_delete (struct PRICELIST *head)
{
if (head)
{
/* recursive call */
list_delete (head->next);
free (head);
}
}
struct PRICELIST *list_read (char *filename)
{
FILE *file;
char line[LINELEN];
struct PRICELIST *pricelist, *node, *prev;
char *p;
size_t len;
file = fopen (filename, "r");
if (file == NULL)
{
perror (filename);
return NULL;
}
pricelist = NULL;
prev = NULL;
while (1)
{
if (fgets (line, sizeof(line), file) == NULL)
break;
/* eat the newline at the end of the buffer, be CR/CRLF agnostic .. */
len = strlen (line) - 1;
if (line[len] == '\r' || line[len] == '\n')
{
line[len] = '\0';
len --;
}
if (line[len] == '\r' || line[len] == '\n')
line[len] = '\0';
/* allocate a new node in the list */
node = malloc (sizeof (struct PRICELIST));
if (node)
{
/* now use sscanf() for getting single elements */
sscanf (line, "%d %f", &node->order_no, &node->price);
/* since the item name might contain spaces this is not so easy .. */
p = line;
while (isspace(*p)) p++;
while (isdigit(*p)) p++;
while (isspace(*p)) p++;
while (isdigit(*p)) p++;
while (ispunct(*p)) p++;
while (isdigit(*p)) p++;
while (isspace(*p)) p++;
strncpy (node->item, p, sizeof(node->item));
node->next = NULL;
/* if this is the first node of the list assign the head to it */
if (pricelist == NULL)
pricelist = node;
/* append the new node to the end of the linked list */
if (prev)
prev->next = node;
node->prev = prev;
/* save it for the next entry */
prev = node;
}
}
/* we are done with the file, close it */
fclose (file);
return pricelist;
}
/* let's test it */
int main (int argc, char *argv[])
{
struct PRICELIST *pricelist;
if (argc < 2)
{
printf ("Usage: %s filename\n", argv[0]);
return 0;
}
pricelist = list_read (argv[1]);
if (pricelist)
{
/* print the list */
printf ("This is the price list (filename '%s'):\n\n", argv[1]);
list_print (pricelist);
/* delete the list */
list_delete (pricelist);
}
return 0;
}
In the comments you mentioned you were only concerned about actually reading a file.
Here's how you'd go about reading a file (currently untested, binary mode):
#include <stdio.h>
int main()
{
FILE *file = fopen("path/to/your/file/yourfile.txt", "rb");
if(!file) return 1; //something went wrong!
long size = fseek(file, 0, SEEK_END);
char *buf = malloc(size);
fread(&buf, size, 1, file); //read all contents, once
fclose(file);
free(buf); //because this is just an example
return 0;
}
For more info on reading a file, just do a quick google search and you'll find almost everything you're looking for.
You can implement your own version of getline using fgetc and realloc.
#include <stdio.h>
#include <stdlib.h>
char *getline(FILE *file)
{
size_t size = 16; // Size of memory allocated for line
size_t len = 0; // Characters read
char *line = malloc(size);
// Return NULL if memory allocation fails
if (line == NULL)
return NULL;
for(;;) {
int c;
switch (c = fgetc(file)) {
// If End Of File is met, return the line up until this point
// if anything has been read
case EOF:
if (len == 0) {
free(line);
return NULL;
}
else {
line[len+1] = '\0';
return line;
}
case '\n':
line[len+1] = '\0'; // NUL terminate the string
return line;
default:
line[len++] = c;
}
// If the string plus NUL terminator is longer than size
// double the size of line
if (len + 1 >= size) {
size *= 2;
line = realloc(line, size);
// Return NULL if memory allocation fails
if (line == NULL)
return NULL;
}
}
}
There are also many free/open source implementations of the same function that can be found online. For instance this GPL 2 one. If you are on a POSIX system (e.g. OS X or Linux) there is already a version of getline found in stdio.h.

Reading variables from a TXT file with C

I have a text file that looks like this:
NAME=Myname //string without ""
The text file is a system file I can't change the file, I can't add "" to the variable
My question:
How can I read the variables in C?
Thanks.
Use fgets()/sscanf() and check results.
FILE = fopen("text_file.txt, "r");
...
char buffer[100];
char VarName[sizeof buffer];
char VarValue[sizeof buffer];
if (fgets(buffer, sizeof buffer, inf) == NULL)
Handle_EOForIOerror();
if (sscanf(buffer, "%[^\n=]=%[^\n]", VarNae, VarValue) != 2)
Handle_FormatError();
else
Sucess();
...
fclose(inf);
You could use some code like the following to read this sample file
char *key, *value;
FILE *fh;
fh = open("...", "r");
/* error check */
while (fscanf("%m[^=]=%ms", &key, &value) == 2) {
/* process key and value */
/* free key and value when you do not need them anymore */
free(key);
free(value);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct var {
char *var_name;
char *value;
} Var;
int main() {
char line[128];
FILE *fp = fopen("data.txt", "r");
char *p, *pp;
Var var;
fgets(line, sizeof(line), fp);
fclose(fp);
p = line;
pp = NULL;
//delete comment
while(NULL!=(p=strstr(p, "//"))){
pp = p;
p += 2;
}
if(pp != NULL)
*pp = '\0';
else
pp = strchr(line, '\0');
//trim end
while(isspace(pp[-1]==' '))
*--pp = '\0';
p=strchr(line, '=');
var.var_name = malloc( p - line +1);
*p='\0';//split
strcpy(var.var_name, line);
pp = strchr(p, '\0');
var.value = malloc(pp - p);
strcpy(var.value, p+1);
printf("%s=\"%s\";\n", var.var_name, var.value);
//free
return (0);
}

Resources