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().
Related
I was reading "C: How to program" on chapter 11 (File handling) and came with this algorithm, to append a string to a file named info.txt but it isn't working at all. What am I doing wrong?
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main(void)
{
FILE *fp = fopen("info.txt","w");
char buff[100];
if(fp == NULL){
fprintf(stdout,"Error opening file\n");
exit(1);
}
while(!feof(stdin)){
fprintf(stdout,"Type a string/\nEOF ends input\n");
if(!fgets(buff,sizeof buff,stdin)){
fprintf(stderr,"Error reading string");
exit(2);
}
buff[strcspn(buff,"\n")] = 0;
fprintf(fp,"%s",buff);
}
fclose(fp);
}
I guess you are inserting EOF wrongly. As it is answered here, EOF is inserted using CTRL+D in Unix systems and using CTRL+Z in Windows.
Using exactly your code it works for me, so I guess you are trying to insert EOF using CTRL+C, or another command, which closes the application and leaves the file empty.
Also, if you want it to append always, even if you close the program and open it again, you should use the mode append "a" instead of write "w" [reference]
FILE *fp = fopen("info.txt","a");
I am trying to encrypt(simple bit manuplation algorithm) a file, for that I created three different version
create new file in the process of encryption or decryption and deletes the old one and renames it
encryption or decryption happens on the same file, using two different File *, one opening the file in rb and another opening the same file in rb+.
encryption or decryption happens on the same file, only one FILE* is used, file opened in rb+ mode.
First two versions works as expected they don't use fseek(), but I am encountering problem in version3
code for v3:
FILE *inputFile= NULL,*outputFile = NULL;
char *inName = "file.txt",*outName;
/* I am using same source file for all three version controlled by #if, so the following assignment is necessary*/
outName = inName;
inputFile = fopen(inName,"rb+");
if(inputFile == NULL)
{
perror(inName);
exit(EXIT_FAILURE);
}
/* I am using same source file for all three version controlled by #if, so the following assignment is necessary*/
outputFile = inputFile;
long int currentLocation;
unsigned char targetChar;
int intChar;
long int offset,temp;
while(currentLocation = ftell(inputFile),(intChar = fgetc(inputFile))!= EOF)
{
targetChar = intChar;
/*#if encryption
encrypt(&targetChar);
#else
decrypt(&targetChar);
#endif // encryption*/
/* going back in the file to the starting position of currently read character*/
temp = currentLocation;
currentLocation = ftell(inputFile);
offset = temp - currentLocation; // the offset is always -1 throughout the program(gdb)
if(fseek(inputFile,offset,SEEK_CUR)==-1)
{
perror(outName);
exit(EXIT_FAILURE);
}
// writing the encrypted or decrpted character to the file
if(fputc(targetChar,outputFile) == EOF)
{
perror(outName);
exit(EXIT_FAILURE);
}
}
fclose(inputFile);
fclose(outputFile);
for the first two character fgetc() is working properly the its is not reading at all, meanwhile the currentLocation is steadily increment.
if the file has following content
Hello world !!
output is
Heelo world !!
or
Heeeeeeeeeeeeeeeeeeeeeeeee ...
the number of e depends on how long the program runs, its an infinite loop.
I am using fseek() to move backwards , does this clear EOF(causing the infinite loop condition) even though I am doing only backward fseek() ? and I checked in debugger the fgetc() is not reading more than two characters but the currentLocation is moving in the increment of 1, why fgetc() is not reading more than two characters?
if(fputc(targetChar,outputFile) == EOF)
{
perror(outName);
exit(EXIT_FAILURE);
}
fflush(outputFile);//need flush
}
fclose(inputFile);
//fclose(outputFile);//double close!
I am trying to read from a file in C using fgets() however I have run into the following problem:
Although I can open the file successfully using fopen():
if ( file=fopen(filename, "r") == NULL )
{
printf("Couldn't open specified file. Please try again.");
exit(1);
}
I can't read anything from it. I am using the following loop, although nothing is printed and the execution terminates successfully.
while ( (fgets(inputLine, 1023, file)) != NULL)
{
printf("Hello world");
}
This is independent of the actual filename, filesize or file contents. Nothing seems to work and nothing is shown up as an error in the debugger. A sample file I have tried is the following directly copied and pasted:
test.txt
#include <stdio.h>
int main ()
{
printf("Hello World");
}
Do you have any guess as to why this is happening?
NOTE: I have taken the loop code from this S'O question so I guess it's right.
This is incorrect:
if ( file=fopen(filename, "r") == NULL )
Try:
if ( (file=fopen(filename, "r")) == NULL )
They way you have written it is equivalent to file = 0 (assuming the file is succesfully opened. If not, it is the same as file = 1). This is not what you want.
Apart from the fact you are doing a mistake in the condition of fopen, there is also a potential problem with snippets such as:
while ( (fgets(inputLine, 1023, file)) != NULL)
{
printf("Hello world");
}
By default, the standard output stream stdout is line-buffered. This means that you should add a \n or a call to fflush to force the data to being effictively written.
fflush(stdout);
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.
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.