Skip to main content

C: IO cautions

This morning I was trying to do some basic file IO with the new learnt file related functions, here are a few cautions to take care of.

List of functions :
1) FILE * fopen(const char* filename, const char* mode)
2) int fclose(FILE *stream)
3) int fprintf(FILE *stream, const char* format,....)
4) fgets(char *str,int n, FILE *stream)

1. Watch the mode of using your file related functions
Opening with fopen and mode w would always overwrite whatever was in the file beforehand. Therefore, in order to maintain the original content, use the r mode for reading only, meaning that no writing can be done to the file, or a mode for appending data to the original end of the file. The modes would only support one of reading, appending or writing at a time, where as with a + sign added to the end, it would have multiple functions.

r+ mode would support both reading and writing , similar for “w+” and a+.

Constraints for each:
r modes would only work if the desired file exists
w modes would erase whatever was in the file (!!!)
a modes would only append to the very end

2. Always remember to close file pointer
An awkward situation arose when I was attempting to manipulate the content of multiple files in one C program.

The intention of the program was to enter lines of text into a file, then reading from that file to printout whatever was entered in the previous step. The issue was the appending/overwriting of text was smooth, but the program could not print anything read from the program.

After asking the tutor in the morning session, it turns out that every time a new file is opened, the previous file needs to be closed to ensure the proper functioning of fgets.

3. The new line @ EOF in fgets
This problem was discovered when I was trying to match the expected output as shown on Edstem(internal studying platform for Usyd), where the printing should have no extra line after encountering an EOF in fgets.

It turned out that this issue only arises when reading from the command line in terminal as standard input, where fgets treats a plain enter key as the invalid condition.

After odd hours of searching, the only valid solution (at least it looks correct) was to move the cursor on the terminal up by one line.

Referencing from this post :

printf("\033[XA"); // Move up X lines;
printf("\033[XB"); // Move down X lines;
printf("\033[XC"); // Move right X column;
printf("\033[XD"); // Move left X column;
printf("\033[2J"); // Clear screen

By moving the cursor up by 1 line, using

printf(\033[1A);

The extra line encountered by fgets would disappear and the standard output would begin from the last line with valid strings.

According to this post :

These commands are called terminal control sequences and there are a few extra ones which we can play around with on the terminal.

Code
Effect
"\033[2J"
Clear the screen.
"\033[H"
Move the cursor to the upper-left corner of the screen.
"\033[r;cH"
Move the cursor to row r, column c. Note that both the rows and columns are indexed starting at 1.
"\033[?25l"
Hide the cursor.
"\033[K"
Delete everything from the cursor to the end of the line.
"\033[0m"
Reset special formatting (such as colour).
"\033[30m"
Black text.
"\033[31m"
Red text.
"\033[32m"
Green text.
"\033[33m"
Yellow text.
"\033[34m"
Blue text.
"\033[35m"
Magenta text.
"\033[36m"
Cyan text.
"\033[37m"
White text.




Comments

Popular posts from this blog

Understanding database [6] : Clustered Index

A clustered index is what is good for a range search over a range of search key values, and the index entries and the rows are ordered the same way, which is different from unclustered indexes (secondary indexes). To use a clustered index, we use the index to locate the first index entry at the start of the range, which where the first row is located at. If the index is clustered, subsequent rows will be stored in successive locations with the ordering , therefore it may minimize the page transfers and maximizes cache hits. For one table, there may only be one clustered index, whereas there can be as many unclustered indexes as you may want  to create. Unclustered indexes aren ’ t as good as clustered, but they might become necessary when it comes to finding for other attributes apart from the primary key. Smaller topics : Dense index & Sparse index When we say sparse index, we mean that there is an index entry for each page of the data file. With this structuring

Understanding database [9] : Choosing indexes

Understanding database 9 : Choosing indexes When choosing indexes, we choose the best plan that suits for the queries, and look for additional indexes that may potentially upgrade upon that. Before creating, we must also consider the impact on updates in the workload, such that indexes take disk space. For a query, the WHERE clause are the main focus point to make indexes on, where exact matches suggest a hash index and range queries suggest a tree index. Clustering is extremely helpful when it comes to range queries, and may also help with equality queries if there are duplicates. Search keys with multiple attribute should be considered if a WHERE clause contains multiple conditions, and the order of attributes is important for range queries. Searching may become ‘index-only’ with such indexes.