Reading a text file line by line in c - c

I try to read the file that I wrote the first three line, line by line. However, it enters infinity loop. How can I stop it at the end of the file?
while(fscanf(infile, "%[^\n]", ch) != EOF)
printf("%s", ch);
Tiffany;Evans Smith;F;22/01/1989;
Alex;Williams;M;23/06/1988;
Clay;Bristol;F;30/12/1989;

There are multiple ways of reading a text file line by line. Hopefully, the following code answers your question.
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *infile;
char data[BUFSIZ];
infile=fopen("filename","r");
while((fgets(data,BUFSIZ,infile)!=NULL))
puts(data);
}

if you want to use fscanf, you can use this code :
int ret;
while(ret = fscanf(infile,"%s",str))
{
if (ret == EOF)
break;
if(ret >0 )
{
cout << str <<endl;
}
else
{
break;
}
}
here, int ret is:
EOF, if the pointer is reached end of file.
0, if no input matched with the variable
>0, number of matched variables with the file input

Related

Printing the first 10 line of a file in C

I'm new to programming in C. And I'm trying to print the first 10 lines of a text file. When I run my program with a text file containing 11 lines of text, only the first line is displayed. I'm not sure why it does that, but I suspect there is something wrong in my while loop. Can someone please help me?
#include <stdio.h>
int main(int argc, char *argv[]){
FILE *myfile;
char content;
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL){
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
content = fgetc(myfile);
while (content != EOF){
max++;
if (max > 10)
break;
printf ("%c", content);
content = fgetc(myfile);
}
fclose(myfile);
return 0;
}
You have been already advised to use fgets. However, if your file has lines of unknown length, you may still want to use fgetc. Just make sure you count only newlines, not all characters:
int max = 0;
int content;
while ((content = fgetc(myfile)) != EOF && max < 10){
if (content == '\n') max++;
putchar(content);
}
fgetc() returns the next character in the file, not the next line. You probably want to use fgets() instead, which reads up to the next newline character into a buffer. Your code should probably end up with something like:
// allocate 1K for a buffer to read
char *buff = malloc(1024);
// iterate through file until we are out of data or we read 10 lines
while(fgets(buff, 1024, myfile) != NULL && max++ < 10) {
printf("%s\n", buff);
}
free(buff);
// close your file, finish up...
Read more about fgets() here: https://www.tutorialspoint.com/c_standard_library/c_function_fgets.htm
fgetc function reads the next character not the next ine. for reading the number of lines you should use fgets function. this function reads the full string till the end of the one line and stores it in a string.
your code Shuld be as:-
#include <stdio.h>
int main(int argc, char *argv[])
{
FILE *myfile;
char content[200];
int max = 0;
// Open file
myfile = fopen(argv[1], "r");
if (myfile == NULL)
{
printf("Cannot open file \n");
exit(0);
}
// Read the first 10 lines from file
fgets(content, 200, myfile);
while (content != EOF)
{
max++;
if (max > 10)
break;
printf("%s", content);
fgets(content, 200, myfile);
}
fclose(myfile);
return 0;
}

How to take first row from this list of text?

I have a list of columns containing text but I just to fetch first upper row from this list. How to do that?
#include <stdio.h>
int main()
{
FILE *fr;
char c;
fr = fopen("prog.txt", "r");
while( c != EOF)
{
c = fgetc(fr); /* read from file*/
printf("%c",c); /* display on screen*/
}
fclose(fr);
return 0;
}
Your stop condition is EOF, everything will be read to the end of the file, what you need is to read till newline character is found, furthermore EOF (-1) should be compared with int type.
You'll need something like:
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fr;
int c;
if(!(fr = fopen("prog.txt", "r"))){ //check file opening
perror("File error");
return EXIT_FAILURE;
}
while ((c = fgetc(fr)) != EOF && c != '\n')
{
printf("%c",c); /* display on screen*/
}
fclose(fr);
return EXIT_SUCCESS;
}
This is respecting your code reading the line char by char, you also have the library functions that allow you to read whole line, like fgets() for a portable piece of code, or getline() if you are not on Windows, alternatively download a portable version, and, of course you can make your own like this one or this one.
For whatever it's worth, here's an example that uses getline
#include <stdio.h>
int main()
{
FILE *fr;
char *line = NULL;
size_t len = 0;
ssize_t nread;
if (!(fr = fopen("prog.txt", "r"))) {
perror("Unable to open file");
return 1;
}
nread = getline(&line, &len, fr);
printf("line: %s, nread: %ld\n", line, nread);
fclose(fr);
return 0;
}
Some notes:
getline() can automatically allocate your read buffer, if you wish.
getline() returns the end of line delimiter. You can always strip it off, if you don't want it.
It's ALWAYS a good idea to check the status of I/O calls like "fopen()".
just replace EOF as '\n'(new line char). Than your code will read until reaching the new line. Here is what it looks like:
#include <stdio.h>
int main()
{
FILE *fr;
char c = ' ';
fr = fopen("prog.txt", "r");
while(c != EOF && c != '\n')
{
c = fgetc(fr); /* read from file*/
if(c != EOF){
printf("%c",c); /* display on screen*/
}
}
fclose(fr);
return 0;
}
I have not tested it yet but probably work. Please let me know if there is some problem with the code i will edit it.
Edit1:char c; in line 5 is initialized as ' ' for dealing with UB.
Edit2:adding condition (c != EOF) to while loop in line 7, for not giving reason to infinite loop.
Edit3:adding if statement to line 10 for not printing EOF which can be reason for odd results.

Write user input to a file and then read it

I have to recieve user input with this style:
U word word2 word3
U word word2 word3
R word
R word
X
I want to write it to a file and then read what was written but the program is in a endless loop, and the file is being created but its empty, it seems to me the program never leaves the while loop that writes to a file for some reason.
void write_to_file(FILE *fp){
char buffer[37];
while(fgets(buffer, 37, stdin)){
fprintf(fp, "%s", buffer);
}
fclose(fp);
}
void read_from_file(FILE *fp){
char buffer[37];
char tipo;
char input_a[6];
char input_b[26];
while(fgets(buffer, 37, fp)) {
sscanf(buffer, "%c %s %[^\n]", &tipo, input_a, input_b);
switch(tipo) {
case 'U' :
// do stuff
break;
case 'R' :
// do stuff
break;
case 'X' :
exit(0);
break;
default :
printf("Invalid Operation\n");
}
}
}
int main(){
FILE *fp = fopen("input.txt","a+");
write_to_file(fp);
read_from_file(fp);
return 0;
}
I opened the file with a+ because in case the file already exists i want to write after the last line
Thanks in advance.
the program is in a endless loop ? Its because of below while() loop
while(fgets(buffer, 37, stdin)) {
}
As man 3 fgets says
fgets() return s on success, and NULL on error or when end
of file occurs while no characters have been read.
you can end this loop by hitting ctrl+d but if you press ctrl+d your main process a.out gets terminated. One way to solve this problem is give one extra \n or ENTER as input at last and then chen the return value of fgets().
Here is the sample code
void write_to_file(FILE *fp){
char buffer[37], *ptr = NULL;
while((ptr = fgets(buffer, 37, stdin))!=NULL) { /* It return NULL upon reaching EOF */
if(*ptr != '\n') { /* at last user enters \n, compare here, if true , break the loop */
fprintf(fp, "%s", buffer);
}
else
break;
}
fclose(fp);
}

Inserting text into a txt file

I'm trying to accomplish the following:
I have a text file with the last printable character "]" in a separate line.
This line is not necessary to be the last line of the file. Some blank lines (line returns) can be there.
The purpose of the project is to insert new text before the line with "]".
The way I try to implement this is to search the file from the end of the file to find the line number with the character "]" (char_line).
Copy line by line from the original file rules1.txt to rules2.txt up to the line char_line. Next step is to append the new text with "]" at the end.
After that, I can delete the original file and rename the new file from rules2.txt to rules1.txt.
The problem I have is that the program finds the line with the character "]" and I can do a printf and see the correct line number.
I am assigning char_line = "%d".
When I'm using if(i < char_line) the file is copied all the way to EOF.
If I assign a numerical value, char_line = 23, the file is copied up to line 22, which is what I want.
This is the part of the code which should find line number for "]", copy line by line rules1.txt to rules2.txt up the line with "]".
#include <stdio.h>
int main(void) {
int end, loop, line;
char str[64];
FILE *file;
FILE *write;
int char_line;
int ret;
file = fopen("rules1.txt", "r");
if (file == NULL) {
printf("Failed to open file\n");
return -1;
}
int ch, line_num = 0;
do {
ch = fgetc(file);
if(ch == '\n')
line_num++;
} while (ch != EOF);
// last line doesn't end with a new line!
// but there has to be a line at least before the last line
if(ch != '\n' && line_num != 0)
line_num++;
fclose(file);
line = line_num-1;
start:
file = fopen("rules1.txt", "r");
if (file == NULL) {
printf("Failed to open file\n");
return -1;
}
for(end = loop = 0;loop<line;++loop){
if(0==fgets(str, sizeof(str), file)){//include '\n'
end = 1;//can't input (EOF)
break;
}
}
if(!end)
if (strncmp ("]", str, 1) == 0){
char_line ="%d";
goto next;
} else if(line >1){
line == line--;//WTF?
fclose(file);
goto start;
} else //What to do here?
next:
file = fopen("rules1.txt", "r");
write = fopen("rules2.txt", "w");
char linec [64]; /* line size */
int i = 0;
while (fgets(linec, sizeof(linec), file)) { /* read line from file */
i++;
if(i < char_line) {
fprintf (write , linec); /* write line to file */
}
}
fclose(file);
fclose(write);
return(0);
}
You have declared int char_line; and later you code
char_line ="%d";
This is nonsense. Since a literal string is some char[] array (better think of it as some constant array), decayed to a pointer, and assigning a pointer to an int does not make sense at all. On many machines (x86-64 notably), a pointer has 64 bits but an int has only 32 bits.
Please, compile your code with all warnings and debug info, so gcc -Wall -Wextra -g with GCC, improve your code to get no warnings, then use the debugger gdb.
Take several days to read some good books on C programming. Be aware and work hard to avoid undefined behavior. Use the debugger to run your program step by step and query its state to understand what is happening.
Read the documentation of every standard function you are using such as fgets.
You probably want a loop that reads every line, and copies sometimes that line to another file.

How to detect last extra Empty Line and Ignore it in C (using getc)

Hello I am using this code for reading floating numbers in txt. If end of txt file has extra blank empty line program reads it 0.00000 and this affect my calculation Last empty line
(# means end of the calculation I added comment line if it exist update comment line)
I try "getline" and other function I can't fix it
fptr = fopen(fileName,"r+");
if(fptr == NULL){
printf("Error!! Cannot open file: %s \n", fileName );
return 1;
}
else {
printf("File opened successfully\n");
while((c = getc(fptr)) != '#' && c != EOF) {
fscanf(fptr,"%f" ,&arr[i]);
++i;
}
}
Check the return value of fscanf -- it should return 1 when it successfully reads a number and 0 on that blank line.
OP is reading a file, line by line and has 4 outcomes:
Successful translated to a number.
Line begins with a # or whitespace only.
No more input (end-of-file).
Something else.
Suggest new approach: read line by line as text and then attempt various parsings. It is important to check the return value of *scanf() to help determine success.
printf("File opened successfully\n");
float /* or double */ arr[N];
size_t i = 0;
char buffer[100];
while (fgets(buffer, sizeof buffer, fptr)) {
double x;
char sof[2];
if (sscanf(buffer, "%lf" ,&x) == 1) {
if (i < N) {
arr[i++] = x;
} else {
puts("No room");
}
} else if (sscanf(buffer, "%1s" , sof) != 1 || sof[0] == '#') {
; // quietly ignore white-space only lines and that begin with #
} else {
puts("Unexpected input");
}
}
fclose(fptr);
puts("Done");

Resources