Greetings,
We've been learning about arrays, strings, simple pointers, files,
and other cool things in this C Course. I made myself an exercise
to check what I've been learning. I wanted to make a program that
would create a sequential text file with newline delimited "records"
which had Tab delimited "fields" in it. Then I wanted to make a
program that would read the created file, and output formatted text
to the screen. Since plain text configuration files are so important
in Linux, maybe this is a step towards understanding text files a
little better? 8^D
Here is what I've learned so far. I've included several files:
1. crsqtxfi.c -- Creates a sequential text file of "records"
that are newline delimited, with "fields"
that are Tab delimited.
2. rdsqtxfi.c -- Reads the sequential text file created with [1].
Prints a header. Outputs formatted text to screen.
3. seqtxtfi.txt -- sample text file created by [1] and read with [2].
This file has newline delimited "records" and Tab
delimited "Fields".
Neither of the above programs are bullet-proof in any way. They are
meant for learning purposes. If suitable, they may be included in
the developing C Course. They may be freely modified to suit any
purpose. I have tested these programs on my computer, and they worked
for MY purposes. YMMV. Use at your own risk.
Compile line: gcc progname.c -o progname -Wall -ansi -pedantic
Add the -g option for debugging with gdb.
Happy Programming!
--
K
/*****************************************************************/
/* crsqtxfi.c -- create a sequential text file of records */
/* each "record" ends with a newline */
/* the delimiter between "fields" is a Tab */
/* a C Beginner's program: */
/* IF THE COMMENTS ARE WRONG PLEASE CORRECT THEM! */
/* This is meant to be a learning/teaching program. */
/* This program sacrifices elegance for readability */
/* If suitable, this may be added to the C course. */
#include <stdio.h>
#include <string.h>
#define FILENAME "seqtxtfi.txt"
int main(void)
{
char fld1[25];
char fld2[20];
char fld3[15];
char fld4[15];
FILE *fp;
printf("Enter Ctrl-D to end input.\n");
if ((fp = fopen(FILENAME, "w")) == NULL)
printf("File could not be opened\n");
else
{
printf("Enter Field 1 : ");
fgets(fld1, sizeof(fld1), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld1[strlen(fld1)-1] ='\t';
printf("Enter Field 2 : ");
fgets(fld2, sizeof(fld2), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld2[strlen(fld2)-1] ='\t';
printf("Enter Field 3 : ");
fgets(fld3, sizeof(fld3), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld3[strlen(fld3)-1] ='\t';
printf("Enter Field 4 : ");
fgets(fld4, sizeof(fld4), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld4[strlen(fld4)-1] ='\0';
while (!feof(stdin))
{
fprintf(fp, "%s%s%s%s\n", fld1, fld2, fld3, fld4);
printf("Enter Ctrl-D to end input.\n");
printf("Enter Field 1 : ");
fgets(fld1, sizeof(fld1), stdin);
if (feof(stdin)) break;
fld1[strlen(fld1)-1] ='\t';
printf("Enter Field 2 : ");
fgets(fld2, sizeof(fld2), stdin);
if (feof(stdin)) break;
fld2[strlen(fld2)-1] ='\t';
printf("Enter Field 3 : ");
fgets(fld3, sizeof(fld3), stdin);
if (feof(stdin)) break;
fld3[strlen(fld3)-1] ='\t';
printf("Enter Field 4 : ");
fgets(fld4, sizeof(fld4), stdin);
if (feof(stdin)) break;
fld4[strlen(fld4)-1] ='\0';
}
end:
fclose(fp);
}
return 0;
}
/*****************************************************************/
/* rdsqtxfi.c -- read sequential text file */
/* -- file has newline delimited "records" */
/* -- records have tab delimited "fields" */
/* a C Beginner's program: */
/* IF THE COMMENTS ARE WRONG PLEASE CORRECT THEM! */
/* This is meant to be a learning/teaching program. */
/* This program sacrifices elegance for readability */
/* If suitable, this may be added to the C course. */
#include <stdio.h>
#include <string.h>
#define FILENAME "seqtxtfi.txt"
int main(void)
{
char record[100], /* array to hold each "record" */
*fld1, *fld2, *fld3, *fld4; /* pointers to "fields" */
FILE *fin; /* pointer to input file */
fin = fopen(FILENAME, "r"); /* open the file to read */
/* print a header */
printf("%-25s %-20s %-15s %-15s\n",
"Field 1\t", "Field 2\t", "Field 3\t", "Field 4\n");
/* the while loop is used to read in the file that fin points to */
/* use fgets() to read the file. fgets() reads up to a newline */
/* fgets() includes the newline in the string it reads and tacks */
/* a '\0' onto the end of the string. It should be familiar. */
while (fgets(record, sizeof(record), fin))
{
/* strtok() will be looking for a newline at the end of record */
if (record[strlen(record) - 1] != '\n')
/* make sure the newline is there */
record[strlen(record) - 1] = '\n';
/* use strtok() to get each "field". strtok()'s usage is: */
/* char *ptr = strtok(char *s1, const char *s2); */
/* the first call of strtok() searches the string s1 for the */
/* `token' s2. If found, it replaces the token with '\0' and */
/* sets a pointer to the next character */
fld1 = strtok(record, "\t");
/* after that each call has a NULL pointer as the 1st argument */
/* & starts searching for another token from the saved pointer */
/* if strtok() can't find the token, it returns a null pointer */
/* strtok() is a tricky function to use. 8^D */
fld2 = strtok(NULL, "\t");
fld3 = strtok(NULL, "\t");
fld4 = strtok(NULL, "\n");
/* finally, print each string using printf() for formatting */
printf("%-25s %-20s %-15s %-15s\n", fld1, fld2, fld3, fld4);
}
fclose(fin);
return 0;
}
/*****************************************************************/
Record 1, Field 1\t Field 2\t Field 3\t Field 4\n
Record 2, Field 1\t Field 2\t Field 3\t Field 4\n
Record 3, Field 3\t Field 2\t Field 3\t Field 4\n
Record 4, Field 1\t Field 2\t Field 3\t Field 4\n
Record 5, Field 1\t Field 2\t Field 3\t Field 4\n
Record 6, Field 1\t Field 2\t Field 3\t Field 4\n
Record 7, Field 1\t Field 2\t Field 3\t Field 4\n
Record 8, Field 1\t Field 2\t Field 3\t Field 4\n
Record 9, Field 1\t Field 2\t Field 3\t Field 4\n
/*****************************************************************/
We've been learning about arrays, strings, simple pointers, files,
and other cool things in this C Course. I made myself an exercise
to check what I've been learning. I wanted to make a program that
would create a sequential text file with newline delimited "records"
which had Tab delimited "fields" in it. Then I wanted to make a
program that would read the created file, and output formatted text
to the screen. Since plain text configuration files are so important
in Linux, maybe this is a step towards understanding text files a
little better? 8^D
Here is what I've learned so far. I've included several files:
1. crsqtxfi.c -- Creates a sequential text file of "records"
that are newline delimited, with "fields"
that are Tab delimited.
2. rdsqtxfi.c -- Reads the sequential text file created with [1].
Prints a header. Outputs formatted text to screen.
3. seqtxtfi.txt -- sample text file created by [1] and read with [2].
This file has newline delimited "records" and Tab
delimited "Fields".
Neither of the above programs are bullet-proof in any way. They are
meant for learning purposes. If suitable, they may be included in
the developing C Course. They may be freely modified to suit any
purpose. I have tested these programs on my computer, and they worked
for MY purposes. YMMV. Use at your own risk.
Compile line: gcc progname.c -o progname -Wall -ansi -pedantic
Add the -g option for debugging with gdb.
Happy Programming!
--
K
/*****************************************************************/
/* crsqtxfi.c -- create a sequential text file of records */
/* each "record" ends with a newline */
/* the delimiter between "fields" is a Tab */
/* a C Beginner's program: */
/* IF THE COMMENTS ARE WRONG PLEASE CORRECT THEM! */
/* This is meant to be a learning/teaching program. */
/* This program sacrifices elegance for readability */
/* If suitable, this may be added to the C course. */
#include <stdio.h>
#include <string.h>
#define FILENAME "seqtxtfi.txt"
int main(void)
{
char fld1[25];
char fld2[20];
char fld3[15];
char fld4[15];
FILE *fp;
printf("Enter Ctrl-D to end input.\n");
if ((fp = fopen(FILENAME, "w")) == NULL)
printf("File could not be opened\n");
else
{
printf("Enter Field 1 : ");
fgets(fld1, sizeof(fld1), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld1[strlen(fld1)-1] ='\t';
printf("Enter Field 2 : ");
fgets(fld2, sizeof(fld2), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld2[strlen(fld2)-1] ='\t';
printf("Enter Field 3 : ");
fgets(fld3, sizeof(fld3), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld3[strlen(fld3)-1] ='\t';
printf("Enter Field 4 : ");
fgets(fld4, sizeof(fld4), stdin);
if (feof(stdin)) goto end; /* this goto moves forward */
fld4[strlen(fld4)-1] ='\0';
while (!feof(stdin))
{
fprintf(fp, "%s%s%s%s\n", fld1, fld2, fld3, fld4);
printf("Enter Ctrl-D to end input.\n");
printf("Enter Field 1 : ");
fgets(fld1, sizeof(fld1), stdin);
if (feof(stdin)) break;
fld1[strlen(fld1)-1] ='\t';
printf("Enter Field 2 : ");
fgets(fld2, sizeof(fld2), stdin);
if (feof(stdin)) break;
fld2[strlen(fld2)-1] ='\t';
printf("Enter Field 3 : ");
fgets(fld3, sizeof(fld3), stdin);
if (feof(stdin)) break;
fld3[strlen(fld3)-1] ='\t';
printf("Enter Field 4 : ");
fgets(fld4, sizeof(fld4), stdin);
if (feof(stdin)) break;
fld4[strlen(fld4)-1] ='\0';
}
end:
fclose(fp);
}
return 0;
}
/*****************************************************************/
/* rdsqtxfi.c -- read sequential text file */
/* -- file has newline delimited "records" */
/* -- records have tab delimited "fields" */
/* a C Beginner's program: */
/* IF THE COMMENTS ARE WRONG PLEASE CORRECT THEM! */
/* This is meant to be a learning/teaching program. */
/* This program sacrifices elegance for readability */
/* If suitable, this may be added to the C course. */
#include <stdio.h>
#include <string.h>
#define FILENAME "seqtxtfi.txt"
int main(void)
{
char record[100], /* array to hold each "record" */
*fld1, *fld2, *fld3, *fld4; /* pointers to "fields" */
FILE *fin; /* pointer to input file */
fin = fopen(FILENAME, "r"); /* open the file to read */
/* print a header */
printf("%-25s %-20s %-15s %-15s\n",
"Field 1\t", "Field 2\t", "Field 3\t", "Field 4\n");
/* the while loop is used to read in the file that fin points to */
/* use fgets() to read the file. fgets() reads up to a newline */
/* fgets() includes the newline in the string it reads and tacks */
/* a '\0' onto the end of the string. It should be familiar. */
while (fgets(record, sizeof(record), fin))
{
/* strtok() will be looking for a newline at the end of record */
if (record[strlen(record) - 1] != '\n')
/* make sure the newline is there */
record[strlen(record) - 1] = '\n';
/* use strtok() to get each "field". strtok()'s usage is: */
/* char *ptr = strtok(char *s1, const char *s2); */
/* the first call of strtok() searches the string s1 for the */
/* `token' s2. If found, it replaces the token with '\0' and */
/* sets a pointer to the next character */
fld1 = strtok(record, "\t");
/* after that each call has a NULL pointer as the 1st argument */
/* & starts searching for another token from the saved pointer */
/* if strtok() can't find the token, it returns a null pointer */
/* strtok() is a tricky function to use. 8^D */
fld2 = strtok(NULL, "\t");
fld3 = strtok(NULL, "\t");
fld4 = strtok(NULL, "\n");
/* finally, print each string using printf() for formatting */
printf("%-25s %-20s %-15s %-15s\n", fld1, fld2, fld3, fld4);
}
fclose(fin);
return 0;
}
/*****************************************************************/
Record 1, Field 1\t Field 2\t Field 3\t Field 4\n
Record 2, Field 1\t Field 2\t Field 3\t Field 4\n
Record 3, Field 3\t Field 2\t Field 3\t Field 4\n
Record 4, Field 1\t Field 2\t Field 3\t Field 4\n
Record 5, Field 1\t Field 2\t Field 3\t Field 4\n
Record 6, Field 1\t Field 2\t Field 3\t Field 4\n
Record 7, Field 1\t Field 2\t Field 3\t Field 4\n
Record 8, Field 1\t Field 2\t Field 3\t Field 4\n
Record 9, Field 1\t Field 2\t Field 3\t Field 4\n
/*****************************************************************/