Learning how to Read and output Lines in a file in C - c

I'm trying to write a program that will read a file, and will output the lines of file. It will start with the last line, then will print the second to last line then the last line, second to last line then third to last line and so on and so forth. I almost have it figured out, but
It's the condition of the loop,
change while((c = fgetc(myFile) != EOF)) to while((c = fgetc(myFile)) != EOF)
around the code (c = fgetc....) is off.
Can someone help me fix this?
Thanks.
void tail(FILE* myFile, int num) //Tail function that prints the lines
according to the user specified number of lines
{
int start, line = 0, counter = 0;
char c, array[100];
while((c = fgetc(myFile) != EOF))
{
if(c=='\n')
line++;
}
start = line - num; //Start location
fseek(myFile, 0, SEEK_SET); //Goes to the start of the file
while(fgets(array, 100, myFile) != NULL)
{
if(counter >start)
{
printf("%s",array); //Prints the string
}
counter++;
}
fclose(myFile); //Closes the file
}

The first issue I see is this idiom:
while((c = fgetc(myFile) != EOF))
has the parens wrong, it should be:
while ((c = fgetc(myFile)) != EOF)
Also, this count:
start = line - num; //Start location
has an off-by-one error:
int start = line - num - 1; // Start location
Beyond that, your array seems too small for general text line processing:
char c, array[100];
Putting it all together with a few style tweaks, we get:
// Tail function that prints the lines
// according to the user specified number of lines
void tail(FILE *myFile, int num)
{
int line = 0;
char c;
while ((c = fgetc(myFile)) != EOF)
{
if (c == '\n')
{
line++;
}
}
int start = line - num - 1; // Start location
(void) fseek(myFile, 0, SEEK_SET); // Go to the start of the file
int counter = 0;
char array[1024];
while (fgets(array, sizeof(array), myFile) != NULL)
{
if (counter > start)
{
fputs(array, stdout); // Print the string
}
counter++;
}
fclose(myFile); // Close the file
}

Related

Read file in columns in C

So, I have a file like this:
12345 name1 18 500.000000
12345 name2 18 500.000000
And I wanted to read the file and each column go to a different variable. So I coded this:
void updateStruct() {
char c;
int lines, i;
accounts account[accMAX];
FILE *acc = fopen("acc.dat", "r+");
if (acc == NULL)
return;
for (c = getc(acc); c != EOF; c = getc(acc))
if (c == '\n')
lines += 1;
fscanf(acc, "%d %s %d %f", &account[0].number, account[0].name,
&account[0].age, &account[0].balance);
}
Somehow, the fscanf() doesn't attribute any value to the variables. What am I doing wrong?
The for loop leaves the file pointer at the end of the file. Call rewind to position the file pointer back at the start of the file before calling fscanf.
The for loop to compute the number of lines reads the whole file. fscanf() fails to convert anything and returns EOF.
You must rewind the position to the beginning of file with rewind(acc) or fseek(acc, 0L, SEEK_SET).
Note also that variable c must have type int for the EOF test to function correctly. Furthermore you should also count the last line that may or may not have a newline.
Here is a modified version:
accounts *updateStruct(int *countp) {
int c, last, lines, i;
FILE *acc = fopen("acc.dat", "r");
if (acc == NULL)
return NULL;
last = EOF;
while ((c = getc(acc)) != EOF) {
if (c == '\n')
lines += 1;
last = c;
}
if (last != '\n') { // last line did not have a newline
lines += 1;
}
rewind(acc);
accounts *account = calloc(lines, sizeof(account));
if (account == NULL) {
fclose(acc);
return NULL;
}
for (i = 0; i < count;) {
if (fscanf(acc, "%d %s %d %f", &account[i].number, account[i].name,
&account[i].age, &account[i].balance) != 4) {
// invalid line: skip to the newline
while ((c = getc(acc)) != EOF && c != '\n')
continue;
if (c == EOF)
break;
} else {
i++;
}
}
fclose(acc);
*countp = i;
return account;
}

C programming- read from text file

it's about reading from a text file.
I have 3 command line arguments:
name of text file
delay time
how many line(s) want to read.
I want to read that text file by user specified line numbers till text file ends.
For example, the first time I read 5 lines and then the program asks how many line(s) do you want to read?. I would enter 7 it reads lines 5 to 12.
This would repeat until the end of the file.
#include <stdlib.h>
#include <stdio.h>
#include<time.h>
#include <string.h>
void delay(unsigned int mseconds)
{
clock_t goal = mseconds + clock();
while (goal > clock());
}
int countlines(const char *filename) {
FILE *fp = fopen(filename, "r");
int ch, last = '\n';
int lines = 0;
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
lines++;
last = ch;
}
fclose(fp);
if (last != '\n')
lines++;
}
return lines;
}
int main(int argc, char *arg[])
{
FILE *ptDosya;
char ch;
ch = arg[1][0];
int s2;
int satir = 0;
int spaceCounter=0;
int lineCount, x = 0;
lineCount = atoi(arg[3]);
s2 = atoi(arg[2]);
printf("dosya %d satir icerir.\n", countlines(arg[1]));
ptDosya = fopen(arg[1], "r");
if (ptDosya != NULL)
{
while (ch != EOF&& x < lineCount)
{
ch = getc(ptDosya);
printf("%c", ch);
if (ch == '\n')
{
delay(s2);
x++;
}
}
while (x < countlines(arg[1]))
{
printf("satir sayisi giriniz:");
scanf("%d", &lineCount);
// i don't know what should i do in this loop..
x=x+lineCount;
}
}
else {
printf("dosya bulunamadi");
}
printf("\n\nend of file!\n");
fclose(ptDosya);
return 0;
system("PAUSE");
}
Your delay function uses a busy loop. This is unnecessarily expensive in terms of computing power. It would be very unwelcome to do this on a battery operated device. Furthermore, clock() does not necessarily return a number of milliseconds. The unit used by the clock() function can be determined using the CLOCKS_PER_SEC macro. Unfortunately, there is no portable way to specify a delay expressed in milliseconds, POSIX conformant systems have usleep() and nanosleep().
Your line counting function is incorrect: you count 1 line too many, unless the file ends without a trailing linefeed.
Here is an improved version:
int countlines(const char *filename) {
FILE *fp = fopen(filename, "r");
int ch, last = '\n';
int lines = 0;
if (fp != NULL) {
while ((ch = fgetc(fp)) != EOF) {
if (ch == '\n')
lines++;
last = ch;
}
fclose(fp);
if (last != '\n')
lines++;
}
return lines;
}
There are issues in the main() function too:
You so not verify that enough arguments are passed on the command line.
You do not check for EOF in the main reading loop.
You do not repeat the process in a loop until end of file, nor do you even ask the question how many line(s) do you want to read? after reading the specified number of lines...
First, if the file cannot be found, the countlines method returns zero. You should use that value to write the error message, and skip the rest of the code.
Second, in the next loop, you use
if (ch != '\n') {
printf("%c", ch);
} else {
printf("\n");
delay(s2);
x++;
}
Why the two printf statements? They will print the same thing.
Perhaps something like this:
ch = getc(ptDosya);
/* exit the loop here if you hit EOF */
printf("%c", ch); /* Why not putc() or putchar() ? */
if (ch == '\n') {
x++;
if ( x == lineCount ) {
x = 0;
lineCount = requestNumberOfLinesToRead();
} else {
sleep(s2); /* instead of delay(). Remember to #include unistd.h */
}
}

Counting number of lines in the file in C

I'm writing a function that reads the number of lines in the given line. Some text files may not end with a newline character.
int line_count(const char *filename)
{
int ch = 0;
int count = 0;
FILE *fileHandle;
if ((fileHandle = fopen(filename, "r")) == NULL) {
return -1;
}
do {
ch = fgetc(fileHandle);
if ( ch == '\n')
count++;
} while (ch != EOF);
fclose(fileHandle);
return count;
}
Now the function doesn't count the number of lines correctly, but I can't figure out where the problem is. I would be really grateful for your help.
Here is another option (other than keeping track of last character before EOF).
int ch;
int charsOnCurrentLine = 0;
while ((ch = fgetc(fileHandle)) != EOF) {
if (ch == '\n') {
count++;
charsOnCurrentLine = 0;
} else {
charsOnCurrentLine++;
}
}
if (charsOnCurrentLine > 0) {
count++;
}
fgets() reads till newline character or till the buffer is full
char buf[200];
while(fgets(buf,sizeof(buf),fileHandle) != NULL)
{
count++;
}
fgetc() is an issue here because you encounter EOF first and exit your do while loop and never encounter a \n character so count remains untouched for the last line in your file.If it happens to be there is a single line in your file that the count will be 0

Unable to get File I/0 working in period counter function -c

int periodCount(const char *filename) {
FILE * fp;
int n = 0;
if( (fp=fopen(filename,"r")) != NULL) {
while(fgetc(fp)!= EOF) {
if(fgetc(fp)=='.') n++;
fclose(fp);
}
}
return n;
}
Here is my code, it simply should count the number of periods in the file named filename, which contains 15 periods, yet when I try to print 'n' at the end of the program, it seems to only be reading 1 of the periods. I know that the problem is probably within the while loop, but I'm not sure why it's doing it.
You're closing the file after the first character. Also you're skipping every other character as a result of not storing the return from fgetc(). Change to:
int periodCount(const char *filename) {
FILE * fp;
int n = 0, c = 0;
if( (fp=fopen(filename,"r")) != NULL) {
while( (c = fgetc(fp)) != EOF) {
if( c == '.' )
n++;
}
fclose(fp); /* <---- move this line here */
}
return n;
}
Your fclose(fp) should be outside the while loop.
As it is, the code is reading (& discarding) the first character; reading the 2nd character & comparing it to '.'; and closing the file.
There are two problems:
You have two calls to fgetc() but you only test whether one of them returned a dot.
You close the file stream in the body of the loop.
You need something more like:
if ((fp = fopen(filename,"r")) != NULL)
{
int c;
while ((c = fgetc(fp)) != EOF)
{
if (c == '.')
n++;
}
fclose(fp);
}

Count paragraph in file

i am working in file system in that i am counting paragraph from the file but
i am not getting please suggest me how can i do that i tried this but not getting what i want
int main()
{
FILE *fp=fopen("200_content.txt ","r");
int pCount=0;
char c;
while ((c=fgetc(fp))!=EOF)
{
if(c=='\n'){pCount++;}
else{continue;}
}
printf("%d",pCount);
return 0;
}
You should declare c as int instead of char.
Also, remember to fclose(fp); before main() returns.
A paragraph contains two subsequent '\n's, use a variable for counting the two '\n's, like this,
int main()
{
FILE *fp=fopen("200_content.txt ","r");
int pCount=0;
char c;
int newln_cnt=0;
while ((c=fgetc(fp))!=EOF)
{
if(c=='\n')
{
newln_cnt++;
if(newln_cnt==2)
{
pCount++;
newln_cnt=0;
}
}
else{continue;}
}
printf("%d",pCount);
return 0;
}
You code counts the number of newline '\n' characters, not empty line which demarcates the paragraphs. Use fgets to read lines from the file. I suggest this -
#include <stdio.h>
// maximum length a line can have in the file.
// +1 for the terminating null byte added by fgets
#define MAX_LEN 100+1
int main(void) {
char line[MAX_LEN];
FILE *fp = fopen("200_content.txt", "r");
if(fp == NULL) {
printf("error in opening the file\n");
return 1;
}
int pcount = 0;
int temp = 0;
while(fgets(line, sizeof line, fp) != NULL) {
if(line[0] == '\n') {
// if newline is found and temp is 1 then
// this means end of the paragraph. increase
// the paragraph counter pcount and set temp to 0
if(temp == 1)
pcount++;
temp = 0;
}
else {
// if a non-empty line is found, this means
// the start of the paragraph
temp = 1;
}
}
// if the last para doesn't end with empty line(s)
if(temp == 1)
pcount++;
printf("number of para in the file is %d\n", pcount);
return 0;
}
For starters, I assume that you consider a new line to be a new paragraph.
i.e.
This is line 1.
This is line 2.
has 2 paragraphs.
What your code does is neglect the case where there is an EOF and not a newline character (\n) after This is line 2.
One way to fix this is to use an extra char variable.
int main()
{
FILE *fp=fopen("200_content.txt ","r");
int pCount=0;
char c; // char that checks
char last_c; //record of the last character read in the loop
while ((c=fgetc(fp))!=EOF)
{
if(c=='\n'){pCount++;}
last_c = c;
else{continue;} //this line is redundant. You can remove it
}
if (last_c != '\n') pCount++; //if EOF at the end of line and not '\n'
printf("%d",pCount);
return 0;
}
void analyze_file(const char *filename) {
FILE* out_file;
out_file = fopen(filename,"r");
int size;
if(out_file == NULL)
{
printf("Error(analyze_file): Could not open file %s\n",filename);
return;
}
fseek(out_file,0,SEEK_SET);
char ch,ch1;
int alpha_count = 0,num_count = 0,non_alnum =0,charac=0;
int word_count =0,line=0;
int para=0;
while(!feof(out_file))
{
ch = fgetc(out_file);
if (isalpha(ch))
alpha_count++;
else if(isdigit(ch))
num_count++;
else if(!isalnum(ch) && ch!='\n' && !isspace(ch))
++non_alnum;
else if(ch=='\n')
{ line++;
ch1 = fgetc(out_file);// courser moves ahead , as we read
fseek(out_file,-1,SEEK_CUR); // bringing courser back
}
else if(ch == ch1)
{para++; //paragraph counter
word_count--;
}
if(ch==' '||ch=='\n')
{
word_count++;
}
if(ch==EOF)
{
word_count++;line++;para++;
}
}
non_alnum -=1;// EOF character subtracted.
charac = alpha_count + non_alnum + num_count;
fclose(out_file);
printf("#Paragraphs = %d\n",para);
printf("#lines = %d\n",line);
printf("#Words = %d\n",word_count);
printf("#Characters = %d\n",charac);
printf("Alpha = %d\n",alpha_count);
printf("Numerical = %d\n",num_count);
printf("Other = %d\n",non_alnum);
printf("\n");
return;
}

Resources