calculation of the length of the file doesn't work - c

#include "stdio.h"
#include "stdlib.h"
int main()
{
FILE *fp;
int noOfLines =0;
char fname[]="Rtl_Prod_Id.txt";
printf(fname);
fp=fopen(fname,"r");
char ch;
//looping for every line
do {
ch=fgetc(fp);
if (ch=='\n')
noOfLines++;
} while(ch!=EOF);
//line before the last line
if (ch!='\n'&&noOfLines!=0)
noOfLines++;
fclose(fp);
printf("%d",noOfLines);
return 0;
}
I am just trying to calculate the number of lines in my file . The Same doesn't not return me any result .
What are the possible mistakes which i am doing
Environment : AIX and Compiler : CC
Thanks
Edit : My program compiles succesfully but while execute the .Out file it doesn't turn up anything
P.S : Although i got the answer . thanks to https://stackoverflow.com/users/434551/r-sahu . I had change char ch; to int ch; . but i wonder why ? What is wrong in char declaration ? . As i going to check for '\n' and EOF characters why integer then ?

The problem is that char on AIX is actually unsigned char.
fgetc() returns an int value and -1 is (typically) used to signal EOF. However, because unsigned char cannot be negative (EOF becomes 255), so the comparison ch != EOF will always be true and this causes an endless loop.
Defining int ch; fixes the problem; btw, this should have shown up during compilation if you use -Wall (show all compiler warnings).

This is a wild shot but changing the line
char ch;
to
int ch;
is appropriate. The return type of fgetc is int, not char.

You should use <...> instead of "..." to include system header files such as stdio.h or stdlib.h.
You should check the return value of fopen for possible error.
The return type of fgetc() is int, not char.
There is a logical flaw in your last line adaption. After the before do {} while loop, ch is EOF, it never will be '\n'. You need another flag to remember if there is any characters after the last '\n', and set it properly in your do {} while loop.
Here is a fixed version of your code, a little more flexible:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *fp;
int noOfLines, isRem, ch;
if (argc > 1) {
fp = fopen(argv[1],"r");
if (fp == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
}
else {
fp = stdin;
}
noOfLines = 0;
isRem = 0;
//looping for every line
do {
ch = fgetc(fp);
if (ch != EOF)
isRem = 1;
if (ch == '\n') {
noOfLines++;
isRem = 0;
}
} while (ch != EOF);
//line before the last line
if (isRem)
noOfLines++;
if (argc > 1)
fclose(fp);
printf("%d\n", noOfLines);
exit(EXIT_SUCCESS);
}
Testing:
$ wc -l t000.c
44 t000.c
$ ./a.out t000.c
44
$ echo -e "abc\ndef" | ./a.out
2
$ echo -ne "abc\ndef" | ./a.out
2

I had change char ch; to int ch; . but i wonder why ? What is wrong in
char declaration ? . As i going to check for '\n' and EOF characters
why integer then ?
EOF has a value of -1, and is of type INT, hence ch must be of type INT too.
Also, the prototype of getchar() is
int getchar(void);
so the return of getchar() must always be checked with an integer type.
There is an inherent confusion of EOF, read more about it here

Related

Check if file has only alphanum characters in C

Run command sequence:
gcc -Wall main.c -o a.out
./a.out < inputfile.txt
I want to read from file like ./a.out < inputfile.txt and after iterating char by char, print OK if all the characters are alphanumeric or ERROR otherwise. I can't seem to get this to work.
inputfile.txt
the brown fox jumped over the dog
this is another string
here is another string
main.c
int main() {
char c;
while (!feof(stdin)) {
c = getchar();
if (!isalnum(c)) {
printf("ERROR!\n");
exit(1);
}
}
printf("OK\n);
return 0;
}
As the others said - spaces and new lines are not alnum characters. Use isalnum() + isspace() in this case. In addition to that consider using some kind of a flag instead of using exit() function:
#include <stdio.h>
#include <ctype.h>
int main()
{
int c;
char ok='Y';
while(c = getchar())
{
if(c == EOF) break;
if(!isalnum(c) && !isspace(c))
{
ok = 'N';
break;
}
}
printf("%c\n", ok);
return 0;
}
RTFM: http://www.cplusplus.com/reference/cctype/
I swear this is the last time when I'm gonna help out people who can't even debug their codes.
A space is not an alphanumeric character.
See the table in this page for what is or isn't "isalnum".
You're using feof wrong. feof returns true when the EOF indicator has already been set, i.e: when you have already read an EOF. So when stdin reaches end-of-file you still get one loop iteration with EOF, which isn't an alpha-numeric character. In order to make sure you can properly distinguish EOF from any valid character you should declare c as an int. I suggest:
int c = getchar();
while(c != EOF){
if(!isalnum(c)){
printf("ERROR!\n");
exit(1);
}
c = getchar();
}
printf("OK\n");

Read characters from a file and store them in a variable in C

I am trying to read character by character from a file and store the characters in a variable.
Only the content from the first line of the file is required so I am using \n or EOF to stop reading. It is required to store SPACE also.
Here is my program:
#include<stdio.h>
#include<string.h>
void main()
{
FILE *fp;
char ch;
char txt[30];
int len;
fp=fopen("~/hello.txt","r");
ch=fgetc(fp);
while(ch != EOF || ch!="\n")
{
txt[len]=ch;
len++;
ch=fgetc(fp);
}
puts(txt);
}
But I am getting a warning while compiling like comparison between pointer and integer. And when I run it I am getting a segmentation fault.
You're comparing to the wrong thing. Try:
ch != '\n'
^ ^
Also, as spotted in other answers, you're using len without initializing it.
Finally, you do realize fgets can do that as well. You could rewrite the thing to:
if (fgets(txt, sizeof txt, fp))
...
1) len is not initiated
int len=0;
2) From fgetc() page:
int fgetc ( FILE * stream );
so the fgetc() return int and not char so you have to define ch as int
int ch;
3) In addition of the cnicutar remark, the while condition should be checked with the && and not with ||:
while(ch != EOF && ch!='\n')
4) You have to add null terminator charachter at the end of your txt buffer after finishing reading from file.
Add this line after the while loop
txt[len]='\0';
BTW you can read the first line with fscanf() it's more easier. Just use the following code
fscanf(fp, "%29[^\n]", txt);
The "%[^\n]" means that fscanf will read all characters from fp except the '\n' charachter and it will stop reading if it gets this charachter. So the fscanf will read all characters from fp till it find '\n' character and save them into the buffer txt with null terminator charchter at the end.
The "%29[^\n]" means that fscanf will read all characters from fp till it find '\n' character or till it reach 29 readed charchters and save them into the buffer txt with null terminator charchter at the end.
len is not initialised so you're probably attempting to write way beyond the end of txt. The fix is simple - initialise it to 0 on declaration
int len = 0;
In addition to the error pointed out by cnicutar, you should also check the return value from fopen before using fp.
#include<stdio.h>
#include<string.h>
void main()
{
FILE *fp;
char ch;
char txt[30];
int len = 0;
fp=fopen("~/hello.txt","r");
if(!fp) {
printf("Cannot open file!\n");
return;
}
ch=fgetc(fp);
while(ch != EOF && ch!= '\n' && len < 30)
{
txt[len] = ch;
len++;
ch=fgetc(fp);
}
txt[len] = 0;
puts(txt);
}
This program may help you to solve your problem.
#include<stdio.h>
int main()
{
FILE *fp;
int ch;
char txt[300];
int len=0;
fp=fopen("tenlines.txt","r");
do{
ch=fgetc(fp);
txt[len]=ch;
len++;
} while(ch!=EOF && ch!='\n');
fclose(fp);
puts(txt);
return 0;
}

getc(fp) causing trouble

Here is my code.
#include<stdlib.h>
#include<stdio.h>
int main(int argc,char** argv)
{
char a;
a=9;
FILE * fp;
fp=fopen(argv[1],"r");
while(a!= EOF)
{
a=fgetc(fp);
printf("\n%d",a);
}
}
The output to this is alright but at the end I am getting a weird character with -1 (since I am printing integer value.
How to stop it at EOF only?
Also what is this character?
Besides the methods in the other answers, you can also do like this:
while ((a = fgetc(fp)) != EOF)
{
printf("%d\n", a);
}
Now you have a few alternative solutions. :)
Edit: As R.. so kindly reminds us, you also have to change the type of a to int.
You are printing the EOF character (the -1) as you do not check if EOF was encountered immediately after fgetc(). Change the structure of the loop to:
int a; /* not char, as pointed out by R... */
for (;;)
{
a = fgetc(fp);
if (EOF == a) break;
printf("\n%d", a):
}
You need to make a have type int, as that type is the return type of fgetc(), and is needed to represent EOF correctly.
Why don't you stop the while with this condition:
do {...}while(a != EOF)
I suppose that a got EOF value AFTER read it.
So, you do the cycle an extra time

How to detect a new line of any file using C program

I am reading a file of integers. I want to save integers from each line to a new array. For this I want to detect a new line of a file. If anybody knows this please help.
The file to be read is as follows
1 2 4 5 6
7 3 2 5
8 3
9 7 6 2
Why not use fgets() to get one line at a time from the file? You can then use sscanf() instead of fscanf() to extract the integers.
#include <stdio.h>
int main ( int argc, char **argv ) {
FILE *fp = fopen ( "d:\\abc.txt", "r");
char line[1024];
char ch = getc ( fp );
int index = 0;
while ( ch != EOF ) {
if ( ch != '\n'){
line[index++] = ch;
}else {
line[index] = '\0';
index = 0;
printf ( "%s\n", line );
}
ch = getc ( fp );
}
fclose ( fp );
return 0;
}
Use fgets() to read a single line of input at a time. Then use strtol() to parse off an integer, using its "end pointer" feature to figure out where to try again, and loop until you've parsed all the values.
Using getc() for this action is fine but do not forget that getc() returns type is int. Retype to char "works" but you can have a problem with non strict-ASCII input file because EOF = -1 = 0xFF after retype to char (on most C compilers), i.e. 0xFF characters are detected as EOF.
#include<stdio.h>
void main()
{
FILE *p;
int n;
int s=0;
int a[10];
p=fopen("C:\\numb.txt","r");
if(p!=NULL)
printf("file opened");
while((n=getc(p))!=EOF)
{ if(n!=NULL && n!='\n')
{
printf("\n%d",n);
a[s]=n;
++s;
}
}
fclose(p);
getchar();
}
I'm not sure of the int to char and vice versa conversion but program works for non zero numbers. I tried on visual basic.
If you use reading char by char then recognizing whitespace with '32' and 'enter' by '13' and/or '10'

What is the easiest way to count the newlines in an ASCII file?

Which is the fastest way to get the lines of an ASCII file?
Normally you read files in C using fgets. You can also use scanf("%[^\n]"), but quite a few people reading the code are likely to find that confusing and foreign.
Edit: on the other hand, if you really do just want to count lines, a slightly modified version of the scanf approach can work quite nicely:
while (EOF != (scanf("%*[^\n]"), scanf("%*c")))
++lines;
The advantage of this is that with the '*' in each conversion, scanf reads and matches the input, but does nothing with the result. That means we don't have to waste memory on a large buffer to hold the content of a line that we don't care about (and still take a chance of getting a line that's even larger than that, so our count ends up wrong unless we got to even more work to figure out whether the input we read ended with a newline).
Unfortunately, we do have to break up the scanf into two pieces like this. scanf stops scanning when a conversion fails, and if the input contains a blank line (two consecutive newlines) we expect the first conversion to fail. Even if that fails, however, we want the second conversion to happen, to read the next newline and move on to the next line. Therefore, we attempt the first conversion to "eat" the content of the line, and then do the %c conversion to read the newline (the part we really care about). We continue doing both until the second call to scanf returns EOF (which will normally be at the end of the file, though it can also happen in case of something like a read error).
Edit2: Of course, there is another possibility that's (at least arguably) simpler and easier to understand:
int ch;
while (EOF != (ch=getchar()))
if (ch=='\n')
++lines;
The only part of this that some people find counterintuitive is that ch must be defined as an int, not a char for the code to work correctly.
Here's a solution based on fgetc() which will work for lines of any length and doesn't require you to allocate a buffer.
#include <stdio.h>
int main()
{
FILE *fp = stdin; /* or use fopen to open a file */
int c; /* Nb. int (not char) for the EOF */
unsigned long newline_count = 0;
/* count the newline characters */
while ( (c=fgetc(fp)) != EOF ) {
if ( c == '\n' )
newline_count++;
}
printf("%lu newline characters\n", newline_count);
return 0;
}
Maybe I'm missing something, but why not simply:
#include <stdio.h>
int main(void) {
int n = 0;
int c;
while ((c = getchar()) != EOF) {
if (c == '\n')
++n;
}
printf("%d\n", n);
}
if you want to count partial lines (i.e. [^\n]EOF):
#include <stdio.h>
int main(void) {
int n = 0;
int pc = EOF;
int c;
while ((c = getchar()) != EOF) {
if (c == '\n')
++n;
pc = c;
}
if (pc != EOF && pc != '\n')
++n;
printf("%d\n", n);
}
Common, why You compare all characters? It is very slow. In 10MB file it is ~3s.
Under solution is faster.
unsigned long count_lines_of_file(char *file_patch) {
FILE *fp = fopen(file_patch, "r");
unsigned long line_count = 0;
if(fp == NULL){
return 0;
}
while ( fgetline(fp) )
line_count++;
fclose(fp);
return line_count;
}
What about this?
#include <stdio.h>
#include <string.h>
#define BUFFER_SIZE 4096
int main(int argc, char** argv)
{
int count;
int bytes;
FILE* f;
char buffer[BUFFER_SIZE + 1];
char* ptr;
if (argc != 2 || !(f = fopen(argv[1], "r")))
{
return -1;
}
count = 0;
while(!feof(f))
{
bytes = fread(buffer, sizeof(char), BUFFER_SIZE, f);
if (bytes <= 0)
{
return -1;
}
buffer[bytes] = '\0';
for (ptr = buffer; ptr; ptr = strchr(ptr, '\n'))
{
++count;
++ptr;
}
}
fclose(f);
printf("%d\n", count - 1);
return 0;
}

Resources