Reading File - fgets reading \n where is not - c

I'm making this code to read files that contain a matrix or multiple ones.
There is also a first line which contains some info about the matrix above each one.
This is the code:
void loadfile(char *filename, maps **head, maps **tail){
FILE *file;
maps *aux;
char buffer[MAX_CHAR];
bool flag = true;
int current_line = 1;
/* open file */
file = openfile(filename, "r");
while(fgets(buffer, MAX_CHAR, file) != NULL){
while(strcmp(buffer, "\n") == 0){
fgets(buffer, MAX_CHAR, file);
flag = true;
printf("HERE\n");
}
if(flag == true){
printf("Dayum\n");
aux = emptymap();
settings(buffer, aux);
managelist(head, tail, aux);
flag = false;
current_line = 1;
}else{
fillboard(buffer, aux, current_line);
current_line++;
}
}
/* close file */
fclose(file);
}
For some files it works okay, like this one:
But for others like this, it doesn't:
It gets stuck in this while loop without any reason:
while(strcmp(buffer, "\n") == 0){
fgets(buffer, MAX_CHAR, file);
flag = true;
printf("HERE\n");
}
I need help, because I really don't understand why is this happening!

Your inner call to fgets (inside the while(strcmp) loop) is not checked. And, quoting C11 (N1570) 7.21.7.2/3:
If end-of-file is encountered and no
characters have been read into the array, the contents of the array remain unchanged and a
null pointer is returned.
So if the buffer contains just '\n' and that was the last character in the file, you'll be stuck in the loop forever because the buffer will not be overwritten.

Related

How can I get my C program to read more than one line of text from a file?

I am trying to write a program that reads lines of texts from an input file, rearrange the letters in the words and then writes them to an output file. So far I have this:
void processFile(FILE* ifp, FILE* ofp) {
char line[1024];
char word[1024];
char* lineptr = line;
char temp;
printf("Begin file processing\n");
while (fgets(line, BIGLINE, ifp) != NULL){
while(sscanf(lineptr,"%s",word) == true)
{
if (strlen(word) >= 4){
temp = word[1];
word[1] = word[2];
word[2] = temp;
}
fputs(word,stdout);
fputs(word,ofp);
fputs(" ",stdout);
fputs(" ", ofp);
lineptr += strlen(word) + 1;
}
}/*while*/
printf("End file processing\n");} /* processFile */
Right now the output file reads:
<rpe><div calss="text_to_html">Project Gtuenberg The Avdentures of Sehrlock Hlomes, by Atrhur Cnoan Dyole
But I need it to read all of the lines in my test file
<pre><div class="text_to_html">Project Gutenberg The Adventures of Sherlock Holmes, by Arthur Conan Doyle
This eBook is for the use of anyone anywhere at no cost and with
almost no restrictions whatsoever. You may copy it, give it away or
re-use it under the terms of the Project Gutenberg License included
with this eBook or online at <a href="http://www.gutenberg.net"
class="_blanktarget">www.gutenberg.net</a>
</div></pre>
I also need to make sure that if I put any text file as the input file it would read all of the lines instead of just the first. How can I do this with what I have already?
As I noted in a comment, your primary problem is that you need to reset lineptr inside the while (fgets(…) != NULL) loop before starting the inner loop. You'd be less likely to run into this problem if you placed all variables so they had the minimum possible scope — so temp should be defined inside the if block, while word and lineptr should be defined between the outer and inner loops. You're marginally unlucky that the first line you're processing is the longest line; it means that lineptr is left pointing at a null byte.
You should use sizeof(line) rather than BIGLINE in the call to fgets(). The use of true where the count is 1 is not appropriate either (though not technically incorrect).
Those changes yield:
#include <stdio.h>
#include <string.h>
static void processFile(FILE *ifp, FILE *ofp)
{
char line[1024];
printf("Begin file processing\n");
while (fgets(line, sizeof(line), ifp) != NULL)
{
char word[1024];
char *lineptr = line;
while (sscanf(lineptr, "%s", word) == 1)
{
if (strlen(word) >= 4)
{
char temp = word[1];
word[1] = word[2];
word[2] = temp;
}
fputs(word, stdout);
fputs(word, ofp);
fputs(" ", stdout);
fputs(" ", ofp);
lineptr += strlen(word) + 1;
}
putchar('\n');
}
printf("End file processing\n");
}
int main(void)
{
processFile(stdin, stderr);
return 0;
}
When compiled from rf79.c into rf79 and run with standard error redirected to /dev/null, I get the output:
$ ./rf79 < data 2>/dev/null
Begin file processing
<rpe><div calss="text_to_html">Project Gtuenberg The Avdentures of Sehrlock Hlomes, by Atrhur Cnoan Dyole
Tihs eoBok is for the use of aynone aynwhere at no csot and wtih
amlost no rsetrictions wahtsoever. You u may cpoy it, gvie it aawy or
r-euse it udner the trems of the Porject Gtuenberg Lciense icnluded
wtih tihs eoBok or olnine at <a herf="http://www.gutenberg.net"
calss="_blanktarget">www.gutenberg.net</a>
<d/iv></pre>
End file processing
$
This looks like what you want.

Opening Files in C

Full Edit:
I am getting frustrated, I don't know what am I doing wrong in here
I still have so many stuff to do in the code but I can't even open a file to continue my work.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
void main()
{
char letter;
FILE *fp;
fp=fopen("‪‪‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
if(fp==NULL)
{
printf("error");
getch();
exit(1);
}
while(fscanf(fp,"%d",&letter)!=EOF)
putchar(letter);
getch();
fclose(fp);
}‪
Picture of the path: http://imgur.com/a/YwFYy
Still prints error
Ok, firstly let's take a look at your file path. There are two ways to acces a file from your local storage:
relative addresses if the file has the same root folder as your application
absolute addresses if the file is in a determined place on your machine's storage
I see that you are trying to use an absolute address to read from your file. Your path is correct but you have to take care about string formatting in C because the \ character could be interpreted as something else.
I would suggest to use this instead ( double back-slash )
input=fopen("‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
This will prevent string formatting interpretations.
Secondly, EOF is just a predefined macro constant and i think it is equal to -1 so your while(! (-1) ) code is not a good ideea for reading until the end of the file.
In order to read from a file until you reach the its end i would consider this property of fscanf() :
fscanf() returns EOF when it reaches the end of the file.
while(fscanf(input,"%ch",&letter) != EOF) {
putchar(letter);
}
This way of reading from a file should do the job.
To read everything from a text file and store its contents into a buffer:
First, you should count how many characters there are in the text file:
size_t get_file_len(FILE *fp)
{
size_t num = 0;
while (fgetc(fp) != EOF)
num++;
return (fseek(fp, 0, SEEK_SET) == 0 ? num : 0);
}
Then allocate memory for a buffer large enough and read all the characters:
char *load_text(const char *path)
{
char *buf = NULL;
FILE *fp = NULL;
size_t num = 0;
size_t i = 0;
int c = 0;
/* open the file in text mode */
fp = fopen(path, "r");
if (!fp)
return NULL;
/* if the file was empty or if an error occurred, return error */
if ((num = get_file_len(fp)) == 0) {
fclose(fp);
return NULL;
}
buf = malloc(num + 1);
if (!buf) {
fclose(fp);
return NULL;
}
while ((c = fgetc(fp)) != EOF)
buf[i++] = (char)c;
/* ensure that the string is null-terminated */
buf[i] = '\0';
fclose(fp);
return buf;
}
Also, in C, all escape sequences begin with a '\' (backslash), so if you wanted to write a backslash in a string or a char you should write it as a '\\' (double backslash):
input=fopen("‪C:\\Users\\LENOVO\\Desktop\\data.txt","r");
pretty simple here :
while(!feof(input)){
fscanf(input,"%c",&letter);
putchar(letter);
}
and remember to close file using fclose(input);

Problems with readdir() and fgets

I'm writing a code where I can be given a directory of .txt files, and specific strings that appear throughout each file, and do some simple comparisons. code chunk will be posted below.
So, My task:Open directory>open file>compare strings>open next file(repeat)
Until I run out of files.
What is wrong:My code currently prints the first file name( full path name) infinitely until it crashes, nothing is printed to fp1. It is supposed to only print the file name once, but it never gets past that first file, where, obviously, I would like it to go through all the files in the directory.
I'm sorry that I'm fairly new to C so I might be unclear as to how these functions actually operate.
Please correct me if I'm wrong, I want to see if I understand correctly.
while ((in_file = readdir(FD))!= NULL){
Should basically traverse through a directory and "look" the name of each file.
I then do some very inefficient work around, which you will probably laugh at me for, and I manage to get the full path name of the first file in the directory.
I then assign that path name to entry_file pointer, where it gets opened by fgets().
I believe fgets() should read each line individually until it sees a EOF character
Now, I had this section working before I added the directory stuff, where I was just opening one file by using fopen() with its full path name, and I haven't touched it. So I don't think my problem is here, but nothing is being printed to fp1 at all, so I really don't know.
I then do some simple string comparisons and try to print matches to fp1
When it reaches the end of the file, it should close the file, and then go back up to readdir() and repeat the process with the next file
Thank you so much for any help. I probably sound like an idiot, but I just have no idea what could cause this.
Yes, I realize its very messy, and I have many unused and pointless variables. I've been trying to figure this out for days, trying many different methods.
int main(void)
{
char str1[10000];
char str2[] = { "Measure L1 current Tank Heater ON: Passed" };
char str3[] = { "Measure L1 current Tank Heater ON: Failed" };
char str4[] = { "Measure L1 current Manifold Heater ON: Passed" };
char str5[] = { "Measure L1 current Manifold Heater ON: Failed" };
char str6[] = { "Measure L1 current (verify heaters off) Manifold: Passed" };
char str7[] = { "Measure L1 current (verify heaters off) Manifold: Failed" };
char sn[] = { "Serial Number: 1" };
DIR* FD;
struct dirent* in_file;
int lcount = 0;//line counter
char *ret;
int linenum = 0;//temp line count
char mes[500];//measurement
double val = 0;//value
char unit[500];//units
char pathstr1[38] = ("C:/Users/liam.king/Desktop/TestFiles/");
char pathstr2[200];
DWORD retval = 0;
char buffer[BUFSIZE] = ("");
char buf[BUFSIZE] = ("");
char** lppPart = {NULL};
FILE *fp, *fp1, *filewrite;
FILE *entry_file;
//fp = fopen("C:/Users/liam.king/Desktop/TestFiles/ProBlueUnit_UpgradeRev4_Report[1022230.SA15E14082][9 39 00 AM][5 19 2015].txt", "r");
fp1 = fopen("C:/Users/liam.king/Desktop/ProBlueTestWrite.txt", "a");
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "w+");
if (fp1 == NULL){
printf("Invalid file name");
return 0;
}
if ((FD = opendir(LONG_DIR_NAME))==NULL)
{
printf("Error: Failed to open directory\n");
return 0;
}
else{
printf("Directory opened successful\n");
}
while ((in_file = readdir(FD))!= NULL){
if (strcmp(in_file->d_name, ".") == 0 || strcmp(in_file->d_name, "..") == 0)
continue;
fprintf(filewrite, "%s", pathstr1);
fprintf(filewrite,"%s", in_file->d_name);
fclose(filewrite);
filewrite = fopen("C:/Users/liam.king/Desktop/FileWrite.txt", "r");
fscanf(filewrite, "%[^\n]%*c", pathstr2);
printf("%s\n", pathstr2);//check file name is correct
entry_file = fopen(pathstr2, "r");
fclose(filewrite);
if (entry_file != NULL){
//printf("SUCCESSFULL OPENING\n");
//fprintf(fp1, "Does this work?\n");
}
else if (entry_file == NULL){
printf("Error: Failed to open entry file\n");
return 0;
}
while (fgets(buffer, 256, entry_file) != NULL){//string being stored in str1 from file *entry_file
lcount++;
ret = strstr(str1, sn);
if (ret != NULL){
fprintf(fp1, "%s\n", str1);
}
ret = strstr(str1, str2);
if (ret != NULL){// compares str1 and 2
fprintf(fp1, "Found"" %s ""at line %d\n", str1, lcount);//if same, declare match and what line found at.
linenum = lcount;
}
//comparing more strings
}
fclose(entry_file);
}
fclose(fp1);
return 0;
}
Since pathstr2 is declared as a local array, you should use this:
while ((in_file = readdir(FD)) != NULL) {
if (!strcmp(in_file->d_name, ".") || !strcmp(in_file->d_name, ".."))
continue;
snprintf(pathstr2, sizeof(pathstr2), "%s%s", pathstr1, in_file->d_name);
entry_file = fopen(pathstr2, "r");
...
while (fgets(buffer, sizeof(buffer), entry_file) != NULL) {
lcount++;
if (strstr(buffer, sn)) {
fprintf(fp1, "%s", buffer);
}
if (strstr(buffer, str1)) {
fprintf(fp1, "Found \"%s\" at line %d\n", str1, lcount);
linenum = lcount;
}
...
}
fclose(entry_file);
}
The tests you perform with strstr on the lines read from entry_file are not incorrect. You should specify buffer instead of str1 as the first argument.
Also note that strstr searches for the second string in the whole line. If the string should be starting at the beginning of the line, you should write:
if (!strncmp(buffer, str1, strlen(str1))) {
// line starts with str1
}

Reading each char line by line in C

I was looking for a solution on how to read char by char on each line from a txt file and I found one, but I don't get some parts of the code. This is it:
#include <stdio.h>
#include <stdlib.h>
void handle_line(char *line) {
printf("%s", line);
}
int main(int argc, char *argv[]) {
int size = 1024, pos;
int c;
char *buffer = (char *)malloc(size);
FILE *f = fopen("myfile.txt", "r");
if(f) {
do { // read all lines in file
pos = 0;
do{ // read one line
c = fgetc(f);
if(c != EOF) buffer[pos++] = (char)c;
if(pos >= size - 1) { // increase buffer length - leave room for 0
size *=2;
buffer = (char*)realloc(buffer, size);
}
}while(c != EOF && c != '\n');
buffer[pos] = 0;
// line is now in buffer
handle_line(buffer);
} while(c != EOF);
fclose(f);
}
free(buffer);
return 0;
}
It was written by someone from here, but I can't reply 'cause I need more points lol. The parts I don't understand are:
if(c != EOF) buffer[pos++] = (char)c;
What does buffer[pos++] do? does it actually increase the variable "pos"? also, why does it start at 1 instead of 0? (pos starts at 0).
I can't really get track of the variable "pos", and I don't know why here buffer[pos] is 0:
buffer[pos] = 0;
The way I read the code is:
declare the size of the buffer that contains every char of every line (I mean, buffer is just free'd at the end, so it keeps the information on every line right?), then declare the other variables and alloc the memory of the buffer.
Open the file myfile.txt, and if it's not null, make pos = 0, then make "c" to store the first character of the file (now the function points to the next char), then if c != EOF meaning the end of file is not reached, save the character "c" in the position 1 of the buffer (I get confused here, why 1 and not 0). Then realloc twice as memory as before if needed. Do that for every character in the line untile you reach EOF or a \n. Now make buffer[pos] = 0, I dont know what value "pos" has, and I assume he makes buffer[pos] = 0 to indicate the end of the line? idk. Print the line, do that until you reach the end of the file. Close the file, free the memory on buffer.
Help! thanks.
fgetc(fp) - Reads the next character from the specified input stream (fp) and advances the associated file position indicator (you do not need to). If successful, the function will return the character read; otherwise, the value EOF (-1) is returned.
Here is a very simple example of using fgetc() to read each character of a file (and write it to another file using fputc())
char filename1[]={"c:\\play\\_in.txt"};//change paths as needed
char filename2[]={"c:\\play\\_out.txt"};
int main(void)
{
FILE *fp1 = {0};
FILE *fp2 = {0};
int c=0;
fp1 = fopen(filename1, "r");
if(fp1)
{
fp2 = fopen (filename2, "w");
if(fp2)
{
c = fgetc(fp1);
while(c != EOF)
{
fputc(c, fp2);
c = fgetc(fp1);
}
fclose(fp2);
}
fclose(fp1);
}
return 0;
}

reading just one line from file in c code

My program reads the specific line from the file properly, however it reads the whole file form the line I specify onward. I am trying to print just one line at a time. How can I make it just read the one line?
The code:
int main()
{
int lineNumber = 5;
static const char filename[] = "Text.txt";
FILE *file = fopen(filename, "r");
int count = 0;
if ( file != NULL )
{
char line[256]; /* or other suitable maximum line size */
while (fgets(line, sizeof line, file) != NULL) /* read a line */
{
if (count == lineNumber)
{
printf("%s", line);
//in case of a return first close the file with "fclose(file);"
}
else
{
count++;
}
}
fclose(file);
}
}
After you've found the desired line, just use a break to exit the loop:
if (count == lineNumber)
{
printf("%s", line);
break;
}
if (count == lineNumber)
{
printf("%s", line);
//in case of a return first close the file with "fclose(file);"
count++;
}
increment count when you get the line you specify,otherwise count will not proceed to indicate next line. That is why your code printed all lines once you got the line you specified. Because the line number count wont increase once it becomes equal to linenumber. so add count++.
You can even break the loop since you don't require rest of the lines to be read after you get the specified line.

Resources