Why this piece of code don't work? (C Basic IO) - c

I recently write a piece of code that count the number of lines in a text file, however, something the while loop part just don't work properly and loop forever. Anyone can help me to find out what is the problem with that piece of code?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
int main() {
fp=fopen("C:\\Users\\Alan\\Desktop\\text.txt","r");
int i=0;
while(!feof(fp)){
i++;
}
fclose(fp);
printf("The Number Of Sentence In That File: %d",i);
getch();
}

The problem is that there is no advance by calling feof(fp), so the execution halts at the beggining of the file. You need to explicitly call something like, getchar(), fscanf(), fgetc(), etc. Here is an example
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
int main() {
fp=fopen("test.txt","r");
int i=0, ch=0;
while((ch = fgetc(fp)) > 0){
if(ch == '\n')
i++;
}
fclose(fp);
printf("The Number Of Sentence In That File: %d\n",i);
getchar();
}

For what you want you can try something like this -
char *s;
s=malloc(255);
while(fscanf(fp,"%254s",s)==1)
{
i++;
}
...
free(s);
This will give desired output.
Also -
while(!feof(fp))
feof to control loop is always wrong .And you should never use feof in loop . Refer here

Your loop does not terminate because you are not doing anything with the file within the loop.
Instead of using feof to control the loop, I would propose to use getline().
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
int main() {
fp=fopen("C:\\Users\\Alan\\Desktop\\text.txt","r");
int i = 0;
char *line = NULL;
size_t len = 0;
while (getline(&line, &len, fp) != -1)
i++;
free(line);
fclose(fp);
printf("The Number Of Sentence In That File: %d\n",i);
}
Note: In this case line is set to NULL and len is set 0, hence getline() will allocate a buffer for storing the line. This buffer should be freed before the program returns.
Update
You can use the return value of getline, if you also want to know the number of chars in the file:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
FILE *fp;
int main() {
fp=fopen("C:\\Users\\Alan\\Desktop\\text.txt","r");
int i = 0;
int j = 0;
int read = 0;
char *line = NULL;
size_t len = 0;
while ((read = getline(&line, &len, fp)) != -1) {
i++;
j += read;
}
free(line);
fclose(fp);
printf("The Number Of Lines In That File: %d\n", i);
printf("The Number Of Chars In That File: %d\n", j);
}

Related

How to read line by line using system call in C

In my program, I can currently read char by char a file with given name "fichier1.txt", but what I'm looking for is to store a line(line char pointer here) and then display it that way :
-ligne 1 : content line 1
-line 2 : content line 2
-ect...
I've tried to store char by char but since it's a pointer and I'm yet that much familiar with pointers I'm not able to store a line and then reuse the pointer to store the char of the next line.
I have to say that it's part of a school projet and I have to use POSIX standard.
#include<stdio.h>
#include<stdlib.h>
#include<errno.h>
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include <pthread.h>
#include<string.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(){
int read_fd, write_fd;
off_t offset = 0;
char lu;
struct stat statFd;
char *fichier = "fichier1.txt";
read_fd = open(fichier,O_RDONLY);
stat(fichier, &statFd);
if(read_fd == -1){
perror("open");
exit(EXIT_FAILURE);
}
int i = 0;
char * line; // variable to store line
while(lseek(read_fd,offset, SEEK_SET) < statFd.st_size)
{
if(read(read_fd, &lu, 1) != -1)
{
printf("%c",lu);
offset++;
} else {
perror("READ\n");
close(read_fd);
close(write_fd);
exit(EXIT_FAILURE);
}
}
return 0;
}
I'd like to use open() function and not fopen()
Since you are able to read character after character from the file, the logic in while loop will be used to store an entire line (up to 199 characters, you can increase it though) at once in an array & then display it:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
FILE *fptr=fopen( "fichier1.txt","r");
int i;
char arr[200]; //THIS ARRAY WILL HOLD THE CONTENTS OF A LINE TEMPORARILY UNTIL IT IS PRINTED
int temp_index=0,line_number=1;;
memset(arr,'\0',sizeof(arr));
while((i=getc(fptr))!=EOF)
{
if(i!='\n')
{
arr[temp_index++]=i;
}
if(i=='\n')
{
printf(line %d: %s\n",line_number++,arr);
temp_index=0;
memset(arr,'\0',sizeof(arr));
}
}
return 0;
}
Calling lseek at every iteration may be inefficient and may fail on devices which are incapable of seeking. I would write a program along these lines below if I don't need to store lines.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
int lc = 0; /* line count */
int c; /* character read */
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while ((c = fgetc(fp)) != EOF) {
printf("line %d: ", ++lc);
while (c != '\n' && c != EOF) {
putchar(c);
c = fgetc(fp);
}
putchar('\n');
}
return 0;
}
Or, a program using fgets to read a line at once:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
int main (void)
{
int lc = 0; /* line count */
char buf[4096]; /* buffer to store the line read */
bool newline = true;
FILE *fp = fopen("fichier1.txt", "r");
if (fp == NULL) {
perror("fopen");
return EXIT_FAILURE;
}
while (fgets(buf, sizeof buf, fp) != NULL) {
if (newline)
printf("line %d: ", ++lc);
printf("%s", buf);
newline = strchr(buf, '\n');
}
return 0;
}

Something weird using fgets

If I'm printing the whole string everything looks good, whitespace and indenting looks perfect (I'm loading the source file with this code).
But if I'm trying to print a single character in the buffer I'm getting letters where there are not supposed to be any.
For example, if I print buffer[2] I'm getting letters where it should be whitespace, but if I print the whole string the letters aren't there.
Here is my code that's not working:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char *buffer = (char*) malloc(100*sizeof(char));
FILE *myFile;
myFile = fopen("thisSourceFile.c", "r");
if (!myFile) {
printf("could not open file");
}
else {
while(fgets(buffer,100,myFile)) {
printf("%c \n",buffer[2]);
}
}
fclose(myFile);
free(buffer);
buffer = NULL;
return 0;
}
OUTPUT:
n
n
n
t
h
I
y
f
p
l
w
p
}
r
u
e
As you can se it is printing letters where it should by whitespace. Those letters are not there if I print the whole string.
If you're interested in parsing a source file and processing each character, this might be a solution.
But there are two constants; charsand num_lines_to_read.
M.M mentions in the comments below that isprint() isn't fully portable and comes with some quirks to be careful of.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void) {
const int chars = 100; /* Num chars per line to read */
const int num_lines_to_read = 3; /* Num lines to read */
char *buffer = (char*) malloc(chars*sizeof(char));
int i = 0, j = 0;
FILE *myFile;
myFile = fopen("thisSourceFile.c", "r");
if (myFile == NULL) {
printf("could not open file");
fclose(myFile);
return 1;
}
for(i=0; i<num_lines_to_read; i++)
{
if(fgets(buffer,chars,myFile) != NULL)
{
while(isprint((unsigned char) buffer[j]))
{
printf("%c", (buffer[j]));
j++;
}
j=0;
}
}
fclose(myFile);
free(buffer);
return 0;
}
Example output (itself!):
#include <stdio.h>#include <stdlib.h>#include <ctype.h>

Read txt file line by line into char array C

I know this question has been asked a few times, but never in a way that helps me figure out my problem. Essentially, I am reading four text files, all single words separated by a new line, and wanting to store these in a char array. I first count the number of lines in the file and then create a new char array, but for the life of me, I cannot figure out how to get it to read correctly. The last two lines are just to test if it has read the entire file correctly and they always come back a NULL and the question mark symbol.
I want each line to be at the next index in the char array.
Any help would be awesome! Thank you ahead of time.
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
void countAnagrams(char* fileName);
void main ()
{
char *fileNames[] = {"AnagramA.txt","AnagramB.txt","AnagramC.txt","AnagramD.txt"};
countAnagrams(fileNames[0]);
countAnagrams(fileNames[1]);
countAnagrams(fileNames[2]);
countAnagrams(fileNames[3]);
}
void countAnagrams(char* fileName)
{
int anagramCount = 0;
int ch, lines = 0;
//Count number of lines in file
FILE *myfile = fopen(fileName, "r");
do
{
ch = fgetc(myfile);
if(ch == '\n')
lines++;
}while(ch != EOF);
char contents[lines];
int i = 0;
for(i=1;i<lines;i++)
{
fscanf(myfile,"%s",contents[i]);
}
fclose(myfile);
printf("%.12s\n",fileName);
printf("number of lines: %d\n", lines);
printf("first thing: %s\n", contents[0]);
printf("last thing: %s\n", contents[lines-1]);
}
Here's a slight modification of your code that might help you.
The main points:
You can use getline() instead of fscanf(). fscanf() can be used to read line-by-line, but it needs an explicit check for the end of line condition. getline() does this automatically.
As kaylum pointed out, it's necessary to rewind() the file pointer back to the beginning of the file after counting the number of lines.
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>
void countAnagrams(char* fileName);
void main ()
{
char *fileNames[] = {"AnagramA.txt","AnagramB.txt","AnagramC.txt","AnagramD.txt"};
countAnagrams(fileNames[0]);
countAnagrams(fileNames[1]);
countAnagrams(fileNames[2]);
countAnagrams(fileNames[3]);
}
void countAnagrams(char* fileName)
{
int anagramCount = 0;
int ch, lines = 0;
//Count number of lines in file
FILE *myfile = fopen(fileName, "r");
do
{
ch = fgetc(myfile);
if (ch == '\n')
lines++;
} while (ch != EOF);
rewind(myfile);
char *contents[lines];
int i = 0;
size_t len = 0;
for(i = 0; i < lines; i++)
{
contents[i] = NULL;
len = 0;
getline(&contents[i], &len, myfile);
}
fclose(myfile);
printf("%.12s\n",fileName);
printf("number of lines: %d\n", lines);
printf("first thing: %s\n", contents[0]);
printf("last thing: %s\n", contents[lines-1]);
}
I think that the problem is char contents[lines] and then fscanf(myfile,"%s",contents[i]) and the printf-s after. contents[i] is char type, and you want to read an array of chars into one char. contents needs to be declared as char* contents[lines] to be able to read a char array into contents[i].

Reading text file in C

My professor gave us the code to get input from a text file. The issue is it will not compile properly for me. I'm not sure where he (or I) went wrong. I have not modified his code in any way and my txt file is in the same directory as the code.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fp;
char ch;
fp = fopen("IronHeelShort.txt", "r");
printf("Data inside file : ");
while(1)
{
ch = fgetc(fp);
printf("%c", ch);
if (ch == EOF)
break;
}
getch();
}
chshould be an int anyway
The function fgetc() will always return an int, to handle all the char values and EOF which is negative.
Here reading your file will prematurely end when finding character 0xFF.
For the compiling issue, change getch() into getchar()
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
FILE *fp;
char ch;
fp = fopen("C:/emule/c/0.html", "r");
printf("Data inside file : ");
while (1)
{
ch = fgetc(fp);
printf("%c", ch);
if (ch == EOF)
break;
}
_getch();
}
UPD
#include <stdio.h>
#include <stdlib.h>
void main() {
FILE *input = NULL;
char c;
input = fopen("D:/c/text.txt", "rt");
if (input == NULL) {
printf("Error opening file");
scanf("1");
exit(0);
}
while (fscanf(input, "%c", &c) == 1) {
fprintf(stdout, "%c", c);
}
fclose(input);
scanf("1");
}

Parsing double from file in C

I have the following code to read tabulated numbers from a file, but fscanf returns with -1. Whar am I doing wrong?
Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <errno.h>
int main(int argc, char** argv) {
FILE *in;
if (argc != 2) {
fprintf(stderr,"Wrong number of parameters.\n");
fprintf(stderr,"Please give the path of input file.\n");
return 1;
}
if((in = fopen(argv[1],"r")) == NULL) {
fprintf(stderr,"\'%s\' cannot be opened.\n",argv[1]);
}
int lines = 0;
char c;
while( (c=fgetc(in)) != EOF) {
if(c == '\n') {lines++;}
}
printf("%d lines\n",lines);
int i = 0;
double a, b;
double x[lines], y[lines];
for(i; i < lines; i++) {
if(fscanf(in,"%lf %lf", &a, &b) != 2) {
fprintf(stderr,"Wrong input format.\n");
}
printf("%lf %lf",a,b);
}
return (EXIT_SUCCESS);
}
You read entire file to find the number of lines..so at the end file pointer has reached the end.. What do you think happens when you call 'fscanf' again ??
You need to reset your file pointer to start again
printf("%d lines\n",lines);
rewind(in);
int i = 0;
You already read the file completely using fgetc so by the time you call fscanf the reading pointer is already at the end of the file.
You can manually place the read pointer at the beginning by using
fseek(in, 0, SEEK_SET);
in front of your loop.

Resources