I need to calculate the number of lines in a file , however , I must do that without
the "easy" functions such as : fopen , fscanf ,fgets ... and so on .
Meaning I can't do this :
int calculateLines(char *filename)
{
FILE *myFile;
char c;
int myLines = 0;
myFile = fopen(filename, "r");
if(myFile == NULL)
return 0;
while ((c = fgetc(f)) != EOF)
if(c == '\n')
myLines++;
fclose(f);
if(c != '\n')
myLines++;
return myLines;
}
For that , I can use only the system calls read , write , close , open & fork.
From what I've done so far , I think that :
open the file with open : someResult = wrapper_open(argv[1],O_RDONLY,0);
reading line after line with read : Can I manipulate read somehow to read line after line ? I've tried to check with its tutorial however came empty handed .
You can't really read line-by-line with read. Instead, you'd read in a block of data (which might contain an arbitrary number of lines, and probably some partial lines). Count the new-line characters in that block, then repeat the read/count process 'til you reach the end of the file.
Related
So I've been trying to experiement with some decryption algorithms and ciphers and tried to do some of them on my own. At them moment I'm writing in C an affine algorithm which I am trying to decrypt a line from a .txt file which I decrypted myself so here's where I think my problem appears since my code always pops text file corrupted and doesn't proceed to the next task.
file = fopen("encr_affine.txt", "r");
if(file)
{
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
fgets(str,100,file);
if ( fgets(str,100,file) == NULL )
{
fprintf(stderr, "Text file corrupted\n");
return -1;
}
What is the mistake here? Is it reading the whole line of the txt file or just the first char? And why it doesn't proceed on into the next tasks?
Thank you in advance
It always prints your Text file corrupted message because the file is always closed (or never open) when it gets there.
Look what this first part does:
file = fopen("encr_affine.txt", "r");
if(file)
{
while ((c = getc(file)) != EOF)
putchar(c);
fclose(file);
}
It opens the file, then (if it's really open), it reads the entire file, byte by byte, then prints it all to stdout. It then closes the file.
Then you try to do stuff on a closed file:
fgets(str,100,file);
This would do nothing because the file is closed, and would return NULL. If the file were never opened, it would still return NULL due to an error.
But then you try it again:
if ( fgets(str,100,file) == NULL )
{
fprintf(stderr, "Text file corrupted\n");
return -1;
}
This fgets(str,100,file) always returns NULL because once again the file is closed.
Perhaps what you really want to do is to process the bytes one at a time in your first loop before printing them with putchar().
So we have this file called dictionary1.txt and it has words with their pronounciation right next to them. What I want to do is to get the first word from each line and print them onto another txt file that the program creates from scratch. My code does it but it also prints random Chinese letters in between English words, I don't know why.
Here's what the ouput file looks like: https://imgur.com/a/pZthP
(Pronounciations are seperated from the actual words in each line with a blankspace in dictionary1.txt)
My code:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
char line[100];
int i = 0;
FILE* fp1 = fopen("dictionary1.txt", "r");
FILE* fp2 = fopen("dictionary2.txt", "w");
if (fp1 == NULL || fp2 == NULL){
printf("ERROR");
return -1;
}
while (fgets(line, 100, fp1) != NULL){
while (line[i] != ' '){
fputc(line[i], fp2);
i++;
}
i=0;
fputc('\0', fp2);
}
return 0;
}
I tried fputc('\n', fp2) as well bu t no matter what I couldn't get onto the next line in the file I created from scratch. I also can't get rid of all the random Chinese letters.
EDIT: I figured it out. The .txt file I was working on was saved in Unicode formatting, which didn't work well with my program. I turned it into ANSI and now it works like a charm.
\n is not the right line separator on all operating systems and all editors.
If you are editing your txt files on Notepad, try fputs ("\r\n", fp2);, where \r means carriage return (cursor returns at the first character of the line) and \n new line.
Generally speaking, Windows uses '\r\n' as line separator, the '\n' character is displayed as something else than end line, at least in Notepad. Linux and Mac OS use different line separators. You may also want to try fprintf(fp2, "\n");
Check this out
\n and \r seem to work everywhere. Why is line.separator more portable?
If you don't mind using C++, you could try to create an output stream os and write os << endl
Note that some compilers may automatically convert '\n' into the corresponding operating system end line character/caracther sequence, whereas some may not.
Another thing, change the while loop condition into line[i] != ' ' && line[i] != '\0' and close the file fp2 using fclose.
.txt file was saved using Unicode formatting. I turned it into ANSI and everything was suddenly fixed.
for example I have test.txt with
test1
test2
at the end of each line I would like to add some text
my code is:
fp = fopen("test.txt", "w");
while ((ch=getc(fp)) != EOF)
if (ch == '\n')
fprintf(fp, "newText");
my output is:
test1
newText
The outcome should be:
test1newText
test2newText
You cannot do it with a single file.
Here is what you need to do:
Open an auxiliary file for temporary output
Read the actual file line by line
For each line write the copy of the line into the auxiliary output
After writing the line write the suffix that you would like to append
Go to the next line until you process the whole file
Once you finished processing the whole file, close both files, and move the auxiliary file in place of the original input.
How to avoid a new line?, I successfully copy [the text] but when I try to add some text at the end of each line, it starts from new line
This is because you include the end-of-line character in your copied text.
If you read character-by-character, do not copy '\n's when you see them; if you read with fgets, check the last character, and skip it if it happens to be '\n' (fgets includes it in its return value).
You can’t read from your output file like that. It is possible to open a file for reading and writing, but it’s an advanced topic and isn’t really appropriate for text files.
The normal approach is to write to another file, and then replace the original if desired. Note that you’ll have to emit all the characters you read and your extra text.
If this is the whole function of the program, consider making it a filter (by using the standard streams); this is what’s expected by experienced users and saves some error checking.
eventually, I have succeed
if (!strcmp(fileName, SWM_DEBUG))
{
fp = fopen(fileName, "r");
fpOut = fopen("tmp.txt", "w");
while ((ch = fgetc(fp)) != EOF)
{
if (ch == '\n')
fprintf(fpOut, "TEST");
fputc(ch, fpOut);
}
}
Thanks for your support ☺
You need to change the fopen call to read from the file and use the fputc function to re-output the character you read, like this:
fp = fopen("test.txt", "r");
while ((ch=fgetc(stdin)) != EOF) {
if (ch == '\n') {
fprintf(fp, "newText");
}
fputc(ch, fp);
}
fprintf(fp, "newText");
As pointed out elsewhere, you can't simultaneously read and write a file in the way you were trying to do, so i've changed it to read from stdin to illustrate the code
I have a text file. I have to check to ensure that the file is ending with a Carriage return. If it is not ending with one then I would like to insert one. The file now being of the correct format I can use it for further parsing. It should work in both Windows & Linux environments.
Try something like this (not tested):
FILE *file = fopen(path, "r+");
char c;
fseek(file, -1, SEEK_END);
fread(&c, 1, 1, file);
if (c != '\r') { /* This will work on Win/Linux and also on a Mac */
fseek(file, 0, SEEK_END);
fprintf(path, "\r");
}
fclose(file);
Note: Are you sure you mean 0x0D? In Linux, lines are ended by 0x0A (\n) and in Windows by the combination 0x0D 0x0A (\r\n).
see i have prepare one file
FILE *b = fopen("jigar.txt","w");
fprintf(b,"jigar\r");
fclose(b);
now i have again open that file for checking
b = fopen("jigar.txt","r");
char f;
go to end of file to last
while(fscanf (b, "%c", &f) != EOF);
go 1 byte previous
fseek( b,-1,1);
read that byte
fscanf(b,"%c",&f);
check it
if(f == 13) \\ here instead of 13 you can writr '\r'
printf("\r is detected");
else
write \r to file...
#include <stdio.h>
void main()
{
FILE *file = fopen("me.txt", "r+"); // A simple text file created using vim
char buffer[100] ;
fseek(file, -2, SEEK_END); // Fetches the last 2 characters of the file
fread(buffer,1,2,file); // Read the last 2 characters into a buffer
printf("\n Character is %s",buffer); // Will print the entire contents of the buffer . So if the line ends with a "\n" we can expect a new line to be printed
//Since i am interested to know how the line feeds & Carriage returns are added to the end of the file , i try to print then both . I have run this code under Suse Linux and if i press enter key after the last line in the file i get two "\n" in the output . I confirmed this using GDB . I would like to run in a Windows environment and check how the behavior changes if any .
printf(" --is %c",buffer[1]);
printf(" --is %c",buffer[2]);
if(buffer[1]=='\r' || buffer[2]=='\n')
//take action
else
// take another action
fclose(file);
}
Here's my dilemma. I have a file, and wish to read in all characters up until the program hits a '#', and ignore everything on that line after the '#'. For example
0 4001232 0 #comment, discard
This is frustrating, as it feels like there is a very simple solution. Thanks!
FILE *f = fopen("file.txt", "r");
int c;
while ((c = getc(f)) != '#' && c != EOF)
putchar(c);
Read a line using fgets, read through this line till you get a '#' character.
Read an another line...
There are plenty of ways and examples of how to do it. Usually, the idea is to have a variable that holds the state (before #, after # , after \n etc.) and run in a while loop until EOF. an example you can see here it's a program to remove C comments, but the idea is the same.
filePointer = fopen("person.txt", "r");
do
{
read = fgetc(filePointer);
//stop when '#' read or when file ends
if (feof(filePointer) || read == '#')
{
break;
}
printf("%c", read);
} while (1);
fclose(filePointer);
also you better check if file opened succesfully
if (filePointer == NULL)
{
printf("person.txt file failed to open.");
}
else
{
file operations
}
The solution depends on how you are "reading" that.
I could, for example, just remove all of those comments with sed 's/#.*//' <infile >outfile in bash.
EDIT: However, if I was parsing it manually, I could simply (in my loop for parsing it) have
if(line[i]=='#') {
continue;
}
which would stop parsing that line by exiting the loop.