I'm not sure what I'm doing wrong, trying to write a simple program that encrypts after being ran once renames. When the method is ran twice it is supposed to do the same thing but instead it decrypts the file. The first version worked but it left the old version and made a new version and I wanted a program that I could run once to encrypt and again to decrypt allowing me to change the file extension in the process, for convenience.
When I run the program it crashes on fwrite().
#include <stdio.h>
#include <stdlib.h>
#define KEY '&'
int main(void)
{
FILE *fp; // file pointer
size_t size, test; // file size
char src_file[FILENAME_MAX], dst_file[FILENAME_MAX];
int orig_char, new_char;
int i = 0;
printf("Enter the name of the source file \"file.ext\": ");
scanf("%s", src_file);
if ((fp = fopen(src_file, "rb")) == NULL) { // open file
fprintf(stderr, "Can't open \"%s\"\n", src_file);
exit(EXIT_FAILURE);
}
fseek(fp, 0, SEEK_END); // find the end of file
size = ftell(fp); // file size
fseek(fp, 0, SEEK_SET); // set file position to start
unsigned char buffer[size], *temp = buffer; //buffer
test = fread(buffer, sizeof(buffer[0]), size, fp);
printf("size written: %d, size of file: %d\n", test, size);
if (test != size) {
fprintf(stderr, "Error: operation fwrite failed!\n");
exit(EXIT_FAILURE);
}
fclose(fp);
printf("Enter the name of the destination file \"file.ext\": ");
scanf("%s", dst_file);
if ((fp = fopen(src_file, "wb")) == NULL) {
fprintf(stderr, "Can't open \"%s\"\n", dst_file);
exit(EXIT_FAILURE);
}
puts("Test1");
for (i = 0; (size_t)i < size && orig_char != EOF; i++, temp++) {
orig_char = (int) *temp;
new_char = orig_char ^ KEY;
*temp = new_char;
}
puts("Test3");
test = fwrite(buffer, sizeof(buffer[0]), size, fp);
fclose(fp);
free(buffer);
if ((rename(src_file, dst_file)) != 0)
fprintf(stderr, "Failed to rename file, make sure file doesn't" \
"already exist!\n");
return 0;
}
Here is my final code in case anyone else comes across this problem, I cleaned it up a tad and added a loop feature for offsetting multiple files. I also added some error recovery.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define KEY '&'
int main(void)
{
FILE *fp; // file pointer
size_t size, test; // file size
char src_file[FILENAME_MAX], dst_file[FILENAME_MAX];
char ch = 'Y';
int orig_char, new_char;
int i = 0;
while (toupper(ch) != 'N') {
printf("Enter the name of the source file \"file.ext\": ");
scanf("%s", src_file);
while ((fp = fopen(src_file, "rb")) == NULL) { // open file
fprintf(stderr, "Can't open \"%s\"\n", src_file);
printf("Enter the name of the source file \"file.ext\": ");
scanf("%s", src_file);
}
fseek(fp, 0, SEEK_END); // find the end of file
size = ftell(fp); // file size
fseek(fp, 0, SEEK_SET); // set file position to start
unsigned char buffer[size], *temp = buffer; // buffer
// send file to buffer
test = fread(buffer, sizeof(buffer[0]), size, fp);
printf("size written: %d, size of file: %d\n", test, size);
if (test != size) {
fprintf(stderr, "Error: operation fwrite failed!\n");
system("Press any key to continue");
exit(EXIT_FAILURE);
}
fclose(fp);
while ((fp = fopen(src_file, "wb")) == NULL) {
fprintf(stderr, "Can't open \"%s\"\n", src_file);
printf("Enter the name of the source file \"file.ext\": ");
scanf("%s", src_file);
}
// offset buffer data
for (i = 0; (size_t)i < size && orig_char != EOF; i++, temp++) {
orig_char = (int) *temp;
new_char = orig_char ^ KEY;
*temp = new_char;
}
// write buffer to file
test = fwrite(buffer, sizeof(buffer[0]), size, fp);
fclose(fp);
printf("Enter the file's new name \"file.ext\": ");
scanf("%s", dst_file);
while ((rename(src_file, dst_file)) != 0) {
fprintf(stderr, "Failed to rename file, make sure file doesn't already exist!\n");
}
printf("size written: %d, size of file: %d\n", test, size);
printf("File Successfully offset\n\n");
printf("Would you like to continue: ");
scanf(" %c", &ch);
}
return 0;
}
Related
How do I read a file into a string on Linux in C?
I came up with some code, but it's not working, and idk why. fgetc() always returns -1.
The file structure is something like this
.:
Files/
main.c
makefile
./Files:
test
Contents of main.c:
#include <stdio.h>
int fileLength(const char filePath[]);
void readFile(const char filePath[], char* outString);
int main()
{
char fileContents[fileLength("Files/test")];
readFile("Files/test", &fileContents);
printf("DEBUG: Address of fileContents is 0x%x\n", &fileContents);
printf("File contents:\n%s\n", fileContents);
return 0;
}
int fileLength(const char filePath[])
{
//Open the file
FILE* file;
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
return -1;
}
//Find the length
fseek(file, 0, SEEK_END);
return ftell(file);
}
void readFile(const char filePath[], char* outString)
{
FILE* file;
//File reading
printf("DEBUG: File path is %s\n", filePath);
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
exit(1);
}
//Get length of file and allocate the according amount of memory
fseek(file, 0, SEEK_END);
int fileLength = ftell(file);
printf("DEBUG: File length is %i\n", fileLength);
//Allocate string
char fileContent[fileLength];
//Read file to string
printf("DEBUG: File contents as digits:\n");
for (int i = 0; i < fileLength; i++)
{
fileContent[i] = fgetc(file);
printf("%d ", fileContent[i]);
}
printf("\n");
printf("DEBUG: Contents of file are:\n%s\n", fileContent);
fclose(file);
printf("DEBUG: outString is pointing to 0x%x\n", outString);
*outString = fileContent;
}
The output is usually just a bunch of question mark diamond things (running in terminal) that match the length of the file with a few other random chars thrown in at the end. The chars at the end change every time the program is run.
kaylum was right, the solution was to:
rewind() after finding the file length in readFile()
remember to fclose() when done
write directly to outString instead of using fileContent
The final code of main.c comes out to be:
#include <stdio.h>
int fileLength(const char filePath[]);
void readFile(const char filePath[], char* outString);
int main()
{
char fileContents[fileLength("Files/test")];
readFile("Files/test", &fileContents);
printf("File contents:\n%s\n", fileContents);
return 0;
}
int fileLength(const char filePath[])
{
//Open the file
FILE* file;
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
return -1;
}
//Find the length
fseek(file, 0, SEEK_END);
int length = ftell(file);
fclose(file);
return length;
}
void readFile(const char filePath[], char* outString)
{
FILE* file;
//File reading
if ((file = fopen(filePath, "r")) == NULL)
{
printf("ERROR: File (%s) cannot be opened.\n", filePath);
exit(1);
}
//Get length of file and allocate the according amount of memory
fseek(file, 0, SEEK_END);
int fileLength = ftell(file);
rewind(file);
//Read file to string
for (int i = 0; i < fileLength; i++)
outString[i] = fgetc(file);
fclose(file);
}
I want to give input as line number and get output as the corresponding text for that line number in a text file.
Sample text file:
Hi this is Stefen
Hi How are you
Example input:
Enter the line number:2
Expected Output:
Hi How are you
My program is:
#include <stdio.h>
#include <stdlib.h>
int main() {
FILE *fp;
fp = fopen("sample.txt", "r");
if (fp == NULL) {
perror("Unable to open the file\n");
exit(1);
}
char buf[256];
while (fgets(buf, sizeof(buf), fp) != NULL) {
printf("%s\n", buf);
print("~~~~\n");
}
fclose(fp);
return 0;
}
Output I got:(The entire file with the separator ~~~~ below each line)
Hi this is Stefen
~~~~
Hi How are you
~~~~
Can anyone please tell me how to do this?
As pmg suggests, would you please try the following:
#include <stdio.h>
#include <stdlib.h>
#define INFILE "sample.txt"
int main()
{
FILE *fp;
char buf[BUFSIZ];
int count = 0, n;
fp = fopen(INFILE, "r");
if (fp == NULL) {
perror(INFILE);
exit(1);
}
printf("Enter the line number: ");
fgets(buf, sizeof buf, stdin);
n = (int)strtol(buf, (char **)NULL, 10);
while (fgets(buf, sizeof buf , fp) != NULL){
if (++count == n) {
printf("%s", buf);
break;
}
}
fclose(fp);
return EXIT_SUCCESS;
}
Best to use a second file
check if you're at \n that means new line and increment a variable like "line"
printf(" \n Enter line number of the line to be deleted:");
scanf("%d", &delete_line);
//open new file in write mode
ptr2 = fopen("c:\\CTEMP\\newfile.txt", "w");
if(ptr2==NULL)
printf("second error opening newfile");
while (!feof(ptr1))
{
ch = fgetc(ptr1);
if (ch == '\n')
{
temp++;
}
//except the line to be deleted
if (temp != delete_line)
{
//copy all lines in file newfile.c
fputc(ch, ptr2);
}
}
fclose(ptr1);
fclose(ptr2);
"detele_line" variable is for the user to inter.
The easiest way is using array to save the lines, then print the certain line.
#include <stdio.h>
#define M 10010
#define N 256
char buf[M][N];
int main(){
FILE *file;
char fileName[50] = "sample.txt";
file = fopen(fileName, "r");
if(file == NULL)
return 1;
int n = 0;
while(fgets(buf[n], N, file) != NULL){
n++;
}
fclose(file);
int i, x;
printf("Example input:\nEnter the line number:");
scanf("%d", &x);
printf("Expected Output:\n%s", buf[x-1]);
return 0;
}
In this code snippet I'm trying to add a string in a binary file. If the string already exists, I return error, otherwise I add it at EOF. I creataed two functions, void AddNewTeam(FILE* fp, char* newTeam), and int SearchTeam(FILE* fp, char* newTeam) as shown below, but that didn't work. Everytime I enter a string, it is added at EOF, even if is in the binary file.
I think the problem is the fread function, I tried to print the value returned by the fread but it is always 0. Can someone help me trying to understand what's wrong with this code and why it's not working?
void AddNewTeam(FILE* fp, const char* newTeam){
int found;
if((fp = fopen("File.dat", "rb")) == NULL){
fp = fopen("File.dat", "ab");
fclose(fp);
}
printf("\tEnter New Team: ");
scanf("%s", newTeam);
found = SearchTeam(fp, newTeam);
if(found == 0){
if((fp = fopen("File.dat", "ab"))){
fwrite(newTeam, sizeof(newTeam), 1, fp);
printf("\tThe following team has been successfully loaded\n");
fclose(fp);
}
}else if(found == 1){
printf("\tThis team already exists\n");
exit(EXIT_FAILURE);
}
}
int SearchTeam(FILE* fp, const char* newTeam){
char string[MAX][MAX_LENGTH];
int counter, result, found = 0;
if((fp = fopen("File.dat", "rb"))){
fseek(fp, 0, SEEK_SET);
for(counter = 0; !feof(fp); counter++){
if(fread(string[counter], sizeof(string[counter]), 1, fp) == 1){
result = strcmp(newTeam, string[counter]);
if(result == 0){
found = 1; break;
}else if(result != 0){
found = 0;
}
}
}
fclose(fp);
return found;
}else if(fp == NULL){
printf("\tError opening binary file\n");
exit(EXIT_FAILURE);
}
}
This is the main function and the function prototypes
int SearchTeam(FILE* fp, const char* newTeam);
void AddNewTeam(FILE* fp, const char* newTeam);
int main(void){
FILE* fp;
char newTeam[MAX_LENGTH];
AddNewTeam(fp, newTeam);
return 0;
}
You're not appending to the file correctly. The search code expects each team name to be in a block of MAX_LENGTH bytes. But when you write, you do:
fwrite(newTeam, sizeof(newTeam), 1, fp);
newTeam is a pointer, not an array, so sizeof will be the size of a pointer, typically 4 or 8 bytes. You need to write MAX_LENGTH bytes so this will match the way you read from the file.
fwrite(newTeam, MAX_SIZE, 1, fp);
I am trying to write a code that simulates an Anti-Virus scan, it scans 5 specific files and then creates a file named AntiVirusLog.txt. In this file it writes the results, for example PSY.avi INFECTED. An infected file is a file that contains the string in the file youtubesign.
My problem is when I try to print in the results to the file AntiVirusLog.txt it does not print anything and leaves the file blank.
My code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>
#define BUZZ_SIZE 1024
int fast_scan(char *fname, char *str, FILE *fs);
int slow_scan(char *fname, char *str, FILE *fs);
int main(int argc, char *argv[])
{
char name[100];
char choice[5];
char buff[BUZZ_SIZE];
FILE *f7, *f2;
struct dirent *de;
DIR *dr = opendir(argv[1]);
if (dr == NULL) // opendir returns NULL if couldn't open directory
{
printf("Could not open current directory");
return 0;
}
f2 = fopen(argv[2], "rb");
f7 = fopen("AntiVirusLog.txt", "wt");
printf("Welcome to Amnon's Anti-Virus program\n which scan would you like to choose?:\n");
printf("Fast: check only the first and the last 20% of the file\n Slow: Checks the entire file\n");
printf("Enter fast for a fast scan and slow for a slow scan\n");
scanf("%s", choice);
if ((strcmp(choice, "slow"))==0)
{
while ((de = readdir(dr)) != NULL)
{
strcpy(name, argv[1]);
strcat(name, de->d_name);
if((fgets(buff, BUZZ_SIZE, f2)) != NULL)
{
slow_scan(name, buff, f7);
}
}
}
if ((strcmp(choice, "fast")) == 0)
{
while ((de = readdir(dr)) != NULL)
{
strcpy(name, argv[1]);
strcat(name, de->d_name);
if ((fgets(buff, BUZZ_SIZE, f2)) != NULL)
{
fast_scan(name, buff, f7);
}
}
}
printf("The scan was made successfuly, check the file AntiVirusLog.txt to see the results\n");
closedir(dr);
fclose(f2);
fclose(f7);
system("PAUSE");
return (0);
}
int slow_scan(char *fname, char *str, FILE *fs)
{
int findres = 0;
FILE *fp;
char temp[BUZZ_SIZE];
if ((fopen_s(&fp, fname, "rb")) != NULL)
{
return(-1);
}
while ((fgets(temp, BUZZ_SIZE, fp)) != NULL)
{
if ((strstr(temp, str)) != NULL)
{
fprintf(fs, "%s INFECTED\n", fname);
findres++;
}
}
if (findres==0)
{
fprintf(fs, "%s NOT INFECTED\n", fname);
}
fclose(fp);
return(0);
}
int fast_scan(char *fname, char *str, FILE *fs)
{
int findres=0;
int i, j, len, partlen;
FILE *fp;
if ((fopen_s(&fp, fname, "rb")) != NULL)
{
return(-1);
}
fseek(fp, 0, SEEK_END);
len = ftell(fp);
partlen = (len * 20) / 100;
char *temp=malloc(partlen);
while ((fgets(temp, BUZZ_SIZE, fp)) != NULL)
{
for (i = 0; i < partlen; i++)
{
if (temp[i]=str[i])
{
findres++;
}
if (temp[i] != str[i])
{
i = partlen + 1;
}
if (findres == partlen)
{
fprintf(fs, "%s INFECTED\n", fname);
i = partlen + 1;
}
}
for (j = len - partlen; j < len; j++)
{
if (temp[j] = str[j])
{
findres++;
}
if (temp[j] != str[j])
{
j = partlen + 1;
}
if (findres == partlen)
{
fprintf(fs, "%s INFECTED\n", fname);
j = partlen + 1;
}
}
}
if (findres!= partlen)
{
fprintf(fs, "%s NOT INFECTED\n", fname);
}
fclose(fp);
return(0);
}
There are primarily two major issues with your code
Point 1: In your code, for the series of calls like
search_sign(argv[1], buff, f7);
you're using buff uninitialized. The buff is then passed as the second parameter of search_sign(), (to be accepted as str) which is again used as the search string in strstr().
As buff is an automatic local variable, the initial content (value) is garbage (indeterminate) and hence , when used as the search key in strstr(), will invoke undefined behaviour.
Point 2: That said, as my previous comment, you should always be checking the success of fopen() call(s) before using the returned file pointer any further.
I have used some of the advices listen and found some fixes of my own and now it works perfectly! the updated code looks like this:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUZZ_SIZE 1024
int search_sign(char *fname, char *str, FILE *fs);
int main(int argc, char *argv[])
{
char buff[BUZZ_SIZE];
FILE *f,*f7;
f7 = fopen("AntiVirusLog.txt", "wt");
f = fopen(argv[1], "rb");
if ((fgets(buff, BUZZ_SIZE, f)) != NULL)
{
search_sign(argv[2], buff, f7);
search_sign(argv[3], buff, f7);
search_sign(argv[4], buff, f7);
search_sign(argv[5], buff, f7);
search_sign(argv[6], buff, f7);
}
printf("The scan was made successfuly, check the file AntiVirusLog.txt to see the results\n");
fclose(f);
fclose(f7);
system("PAUSE");
return (0);
}
int search_sign(char *fname, char *str, FILE *fs)
{
int findres = 0;
FILE *fp;
char temp[BUZZ_SIZE];
if ((fopen_s(&fp, fname, "rb")) != NULL)
{
return(-1);
}
while ((fgets(temp, BUZZ_SIZE, fp)) != NULL)
{
if ((strstr(temp, str)) != NULL)
{
fprintf(fs, "%s INFECTED\n", fname);
findres++;
}
}
if (findres==0)
{
fprintf(fs, "%s NOT INFECTED\n", fname);
}
fclose(fp);
return(0);
}
I am using Code Blocks and I would like to delete a file using C. The file is used by two functions but not simultaneously.
This is the first function which uses the file:
double FileRead()
{
double n,cl,cd,result;
FILE *fd;
char filename[] = "save.txt";
char buff[5024];
if ((fd = fopen(filename, "r")) != NULL)
{
fseek(fd, 0, SEEK_SET);
while(!feof(fd))
{
memset(buff, 0x00, 5024);
fscanf(fd, "%[^\n]\n", buff);
}
sscanf(buff, "%lf %lf %lf",&n,&cl,&cd);
printf("cl: %1.5f cd: %1.5f\n",cl,cd);
result = (cl/cd);
printf("The CL/CD ratio is : %1.5f\n",result);
}
else
result = 0;
fclose(fd);
return result;
}
And this is the second function:
void evaluate(void) /*evaluate the population */
{
int mem;
int i;
double x[NVARS+1];
char buffer[101] = "save.txt";
FILE *controlpoints;
double y[NVARS] = {1.00000,0.92544,0.82351,0.78301,0.74004,0.50199,0.40422,0.31056, /*fixed values on x axis */
0.18549,0.14954,0.11702,0.06331,0.02581,0.01334,0.00509,0.00000,0.00052,0.00555,0.03324,
0.11345,0.33088,0.43678,0.60146,0.70751,0.8043,0.92047,0.98713,1.00000};
for(mem = 0; mem < POPSIZE; mem++)
{
controlpoints = fopen("controlpoints2.txt","w");
for(i = 0; i < NVARS; i++)
{
x[i+1] = population[mem].gene[i];
fprintf(controlpoints,"%1.5f\n%1.5f\n",y[i],x[i+1]);
printf("The value of population[%d].gene[%d] is %f\n",mem,i,population[mem].gene[i]);
}
fclose(controlpoints);
rbspline();
XfoilCall();
population[mem].fitness = FileRead();
}
remove(buffer);
if(remove(buffer) == 0)
printf("File %s deleted.\n", buffer);
else
fprintf(stderr, "Error deleting the file %s.\n", buffer);
}
All the time I am getting the message "Error deleting the file save.txt". Can you please check it out and tell me what am I doing wrong?
Your code in the second function contains:
remove(buffer);
if (remove(buffer) == 0)
printf("File %s deleted.\n", buffer);
else
fprintf(stderr, "Error deleting the file %s.\n", buffer);
You're removing the file twice and the second time it isn't there, so you report failure.
Fix: remove the unchecked remove(buffer) line.
Look at this part of the code
remove(buffer);
if(remove(buffer) == 0)
printf("File %s deleted.\n", buffer);
else
I think you want this
ret=remove(buffer);
if(ret==0)
printf("File %s deleted.\n", buffer);
else