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);
}
Related
i write this program for encrypt any file with any size but if file will smaller than 1Kbyte my program give me segment fault error whats wrong?
#include <stdio.h>
#include <stdlib.h>
long int findsize(char file_name[])
{
FILE* fp = fopen(file_name, "r");
if (fp == NULL) {
printf("File Not Found!\n");
return -1;
}
fseek(fp, 0L, SEEK_END);
long int res = ftell(fp);
fclose(fp);
return res;
}
int main ()
{
FILE *fptr;
char path[256];
char* data;
int passcode;
printf("Enter the path of file : ");
scanf("%s",path);
long int file_size = findsize(path);
data = malloc(file_size);
fptr = fopen(path,"rb");
int i = 0;
while (!feof(fptr))
data[i++] = fgetc(fptr);
fclose(fptr);
fptr = fopen(path, "wb");
for (int j=0; j<i-1; j++)
fputc((data[j] ^ 0x60), fptr);
fclose(fptr);
free(data);
return 0;
}
my program can encrypt files bigger than 1GByte but. what should i do?
#include <stdio.h>
#include <stdlib.h>
int count_arr(FILE *file)
{
int c,count=0;
//FILE *file;
//file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF){
putchar(c);
++count;}
fclose(file);
}
return count;
}
void make_arr (FILE *file, char arr[]){
int c,n=0,count=0;
char ch;
//FILE *file;
//file = fopen("test.txt", "r");
if (file) {
while ((c = getc(file)) != EOF){
ch = (char)c;
arr[n]=ch;
++n; }
fclose(file);
}
}
int main(){
FILE *file;
int n;
//scanf("%c",&file_name);
file = fopen("test.txt","r");
int count = count_arr(file);
char arr [count];
make_arr(file, arr);
for(n=0; n<count;++n) printf("%c",arr[n]);
}
So far this is all I have for my code. I know I am doing it completely wrong. When I print out the char array it prints random junk... I am trying to code a function "make_arr" that passes an array which gets stored with characters from a file. Any help would be appreciated!
Here is an small example that reads a file into a buffer:
FILE* file = fopen("file.txt", "r");
// get filesize
fseek(file, 0, SEEK_END);
int fsize = ftell(file);
fseek(file, 0, SEEK_SET);
// allocate buffer **note** that if you like
// to use the buffer as a c-string then you must also
// allocate space for the terminating null character
char* buffer = malloc(fsize);
// read the file into buffer
fread(buffer, fsize, 1, file);
// close the file
fclose(file);
// output data here
for(int i = 0; i < fsize; i++) {
printf("%c", buffer[i]);
}
// free your buffer
free(buffer);
If you really would like to use a function to fill your buffer this would work (not really see the point though), although I still will make only one read operation:
void make_array(FILE* file, char* array, int size) {
// read entire file into array
fread(array, size, 1, file);
}
int main(int argc,char** argv) {
// open file and get file size by first
// moving the filepointer to the end of the file
// and then using ftell() to tell its position ie the filesize
// then move the filepointer back to the beginning of the file
FILE* file = fopen("test.txt", "r");
fseek(file, 0, SEEK_END);
int fs = ftell(file);
fseek(file, 0, SEEK_SET);
char array[fs];
// fill array with content from file
make_array(file, array, fs);
// close file handle
fclose(file);
// output contents of array
for(int i = 0; i < fs; i++) {
printf("%c\n", array[i]);
}
return 0;
}
Like I stated in the comments above you need to add space for the terminating null character if you like to use the char array as a string:
char* array = malloc(fs + 1);
fread(array, fs, 1, file);
// add terminating null character
array[fs] = '\0';
// print the string
printf("%s\n", array);
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;
}
I was wondering how I can get this code to overwrite a textfile from it's text value to it's ASCII value.
I want it to do something like this:
CMD > c:\users\username\desktop>cA5.exe content.txt
content.txt has "abc" in it and I want the command line to change the "abc" to it's ASCII values. 97... etc. I don't want anything written in the command window, I want it to change in the text file. Is this possible, if so, how could I do it with this existing code?
#include <stdio.h>
#include <stdlib.h>
int main(int argc[1], char *argv[1])
{
FILE *fp; // declaring variable
fp = fopen(argv[1], "rb");
if (fp != NULL) // checks the return value from fopen
{
int i;
do
{
i = fgetc(fp); // scans the file
printf("%c",i);
printf(" ");
}
while(i!=-1);
fclose(fp);
}
else
{
printf("Error.\n");
}
}
Not the best code but very simple.
#include <stdio.h>
#include <stdlib.h>
void convertToAHex(char *data, long int size, FILE *file){
rewind(file);
int i;
for(i = 0; i < size; ++i){
fprintf(file, "%d ", data[i]);
}
}
int main(int argc, char *argv[]){
if(argc != 2){
return EXIT_FAILURE;
}
FILE *file = fopen(argv[1], "r+");
if(file){
char *data;
long int size;
fseek(file, 0, SEEK_END);
size = ftell(file);
rewind(file);
data = (char *) calloc(size, sizeof(char));
if(data){
fread(data, 1, size, file);
convertToAHex(data, size, file);
free(data);
}
fclose(file);
}
return EXIT_SUCCESS;
}
I want to reverse the contents of the input file and display the reversed contents, but I am not getting it; i think I have made a logic error.
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
int main() {
char* c = malloc(10);
char* c1 = malloc(10);
char ch, arg1[100], arg2[100];
int i, count = 0;
FILE *fp, *fq;
printf("Name of the file:");
scanf("%s", arg1);
fp = fopen(arg1, "w+");
if (!fp) {
perror("Failed to open file");
return errno;
}
printf("\t\t\t%s\n\n", arg1);
printf("\t\tInput the text into the file\n");
printf("\t\tPress Ctrl+d to the stop\n");
while ((*c=getchar()) != EOF) {
fwrite(c, 1, sizeof(c), fp);
count++;
}
printf("\n\n");
fclose(fp);
fp = fopen(arg1, "w+");
printf("Name of the output file:");
scanf("%s", arg2);
printf("Reversing the contents of the file.......\n");
fq = fopen(arg2, "w+");
printf("\t\t%s\n\n", arg2);
for (i = 1; i <= count; i++) {
fseek(fp, -(i + 1), SEEK_END)
fwrite(c1, 1, sizeof(c1), fq);
}
printf("Done....Opening the file\n");
rewind(fq);
for (i = 0; i <= count; i++) {
ch = getc(fp);
putc(ch, stdout);
}
fclose(fp);
fclose(fq);
return 0;
}
Here is an example program which loads the file into memory and then prints the content of the memory backwards to stdout.
#include <stdio.h>
#include <stdlib.h>
/* get the size of the file. No error checking here! */
long get_filesize(FILE *fp)
{
long fsize;
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
rewind(fp);
return fsize;
}
int main(int argc, char *argv[])
{
if(argv[1] == NULL) return EXIT_FAILURE;
FILE *input;
unsigned char *data;
long filesize;
int i;
/* open target file */
input = fopen(argv[1], "rb");
if(input == NULL) exit(EXIT_FAILURE);
/* retrieve size of the file */
filesize = get_filesize(input);
if(filesize < 1) exit(EXIT_FAILURE);
/* allocate space for the file */
data = malloc(filesize * sizeof(unsigned char));
if(data == NULL) exit(EXIT_FAILURE);
/* read the file into buffer and close the file handle */
fread(data, filesize, sizeof(unsigned char), input);
fclose(input);
/* print the file content from end to beginning */
for(i = --filesize; i >= 0; --i)
putchar(data[i]);
/* free the data buffer memory */
free(data);
return EXIT_SUCCESS;
}
Input text:
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
when an unknown printer took a galley of type and scrambled it to make a type
specimen book.
Output text:
.koob nemiceps epyt a ekam ot ti delbmarcs dna epyt fo yellag a koot retnirp
nwonknu na nehw ,s0051 eht ecnis reve txet ymmud dradnats s'yrtsudni eht neeb
sah muspI meroL .yrtsudni gnittesepyt dna gnitnirp eht fo txet ymmud ylpmis si
muspI meroL