I'm trying to write a program that can open all given files in a directory, and output the files with some changes to another directory given a path specified by the user. I made a function that will be called after fork() for each filename encountered in the current directory, and the output will have the same name in this new directory. I have looked all over, and I still can't find a reason as to why fgets() keeps returning NULL.
void sorter(char *fileName, char *directory, char* newName){
FILE *edit = fopen(fileName, "r");
char buf[700];
char *bufp = buf;
char *fLine = fgets(bufp, sizeof(buf), edit);
if (edit == NULL){
exit(EXIT_FAILURE);
}
printf("%s\n", fLine);
chdir(directory);
FILE *output=fopen(newName, "w");
while(fLine){
fprintf(output, fLine);
fprintf(output, "done");
}
fclose(output);
fclose(edit);
}
Related
Im making a txt editor in the terminal, one of it's features is to edit a specific line.
To do so,
I am creating a new temporary txt file,
deleting the old/original one
and renaming the temporary one to the original.
Here's the code:
FileLineEdit(char filename[20], int line, char newline[1000]){
FILE * fp;
FILE * fptmp;
char buffer[1000];
int count;
int ret;
fp = fopen(filename, "r");
fptmp = fopen("tmp/replace.txt", "w");
if (fp == NULL || fptmp == NULL)
{
printf("\nErro!\n");
exit(1);
}
count = 0;
while ((fgets(buffer, 1000, fp)) != NULL)
{
count++;
if (count == line)
fputs(newline, fptmp);
else
fputs(buffer, fptmp);
}
fclose(fp);
fclose(fptmp);
//strcat(fullpath, filename);
//printf("%s", fullpath);
ret = remove(filename);
if(ret == 0) {
printf("File deleted successfully");
} else {
printf("Error: unable to delete the file");
}
rename("tmp/replace.txt", "tmp/a.txt");
getch();
}
The output is constantly:
Error: unable to delete the file
btw once I try this outside the "tmp/" folder it works just fine
The /tmp folder has the sticky bit (s) set, and that means, that anyone can read and create/modify files in it, but only its owner (root) can remove them.
So, if is what you want your program to do, you should do it in some directory other than /tmp
Also, as jarmod pointed out, you shouldn't have a hardcoded filename for your temporary filename. You should use tmpfile or tmpnam for this purpose:
Instead of:
fptmp = fopen("tmp/replace.txt", "w");
Write:
fptmp = tmpfile();
The file will be automatically deleted when the file stream is closed.
(You can read a more about the /tmp dir here)
In this code I opened my files in my open_file function. Then the process_file function needs to copy the text from my in file and Copy it to an out file. Right now it produces a new file but it is blank. It does not give me any error messages. I do not know what is wrong.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define MAX_LEN 100
FILE* open_file(char prompt[], char mode[]);
FILE* process_file(FILE* in, FILE* out);
int main(int argc, const char * argv[]) {
FILE* in = NULL;
FILE* out = NULL;
printf("MAD-LIBS Text Processor\n");
printf("The Program will open a mad-libs file, ask you to fill various words, and produce a funny story.\n");
open_file("Enter mad-lib file name:\n", "r");
open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
fclose(in);
fclose(out);
return 0;
}
/* open_file = prompts user for file name & and attempts to open it, if it fails it prompts the user again. */
FILE* open_file(char prompt [], char mode[]) {
char filename[255];
FILE* in;
do {
printf("%s", prompt);
scanf("%s", filename);
in = fopen(filename, mode);
if (in == NULL) {
printf("Unable to open file: %s. Try Again!\n", filename);
}
} while(in == NULL);
return in;
}
/* process_file = processes entire input file and writes it to output file */
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
char NewContent[MAX_LEN];
//gets whats in file in
while(fgets(content, content[MAX_LEN], in) != NULL) {
fputs (content, stdout);
strcat(NewContent, content);
}
// copies it
while (fgets(content, content[MAX_LEN], in) != NULL) {
fprintf(out, "%s", content);
}
printf("Successfully copied file\n");
return in;
}
You never assign the FILE* from open_file function to your variable, so it never gets processed.
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
You are not storing the FILE pointers that open_file is returning, so in
and out remain uninitialized.
You have to do:
in = open_file("Enter mad-lib file name:\n", "r");
out = open_file("Enter file name for resulting story:\n", "w");
process_file(in, out);
Also your process_file is wrong. NewContent is not initialized, when you do
strcat(NewContent, content);
this yields undefined behaviour. Declare NewContent like this:
char NewContent[MAX_LEN] = { 0 };
so that it is properly \0-terminated.
Also depending on the size of the file you are copying, MAX_LEN might not be
long enough to hold the whole file. In that case you would overflow the buffer.
It would be better not to use NewContent in the first place and write to out
in the same reading loop:
FILE* process_file(FILE* in, FILE* out) {
char content[MAX_LEN];
//gets whats in file in
while(fgets(content, MAX_LEN, in) != NULL) { //<- your fgets was wrong
fputs (content, stdout);
fprintf(out, "%s", content); // or fputs(content, out);
}
printf("Successfully copied file\n");
return in;
}
And you were calling fgets incorrectly (look at my corrected code)
Also bear in mind, that you did have 2 loop doing while(fgets(...) != NULL.
Well, the first loop ends, that's because fgets returns NULL, most likely
because the whole file was read or there was an I/O error. In either case
subsequent calls of fgets will return NULL as well, so your second loop
would not even be executed at all.
Here's my issue:
I'm currently working on a project for university. We're suppose to do a program that receives .pbm and .pgm files as input, and then we're suppose to handle them in some ways. But for now the main thing is to successfully receive them.
Each .pbm and .pgm file's first line is a "magic number". A set of characters like P1, P2 (...) P6.
Our goal is to receive a .pbm file as input, save the first line, dynamically allocate a string so it is just as big as its content (P6\n, for example), so we can then detect the magic number. The same applies to every other line. We basically just want a way to save each line into an array, making them just as big as their content.
Me and my project partner are both beginners: file handling, pointers, dynamic memory and headers are still pretty hard to us. Thank you in advance.
---EDIT--- (Forgot the code, as an user pointed out)
int main(int argc, char const *argv[])
{
readFile(argv[1], "EI_2012-13_ascii.pbm");
return 0;
}
void readFile (const char* input_file, char* filename){
char *line_buffer, *line;
FILE *file_stream = NULL;
if(!check_extension(filename, ".pbm") &&
!check_extension(filename, ".pgm") && !check_extension(filename, ".ppm"))
ERROR(ERR_EXT, "Invalid file extension!\n");
file_stream = fopen(input_file, "r");
if (file_stream == NULL)
ERROR(ERR_EXT, "Couldn't open the file for reading");
line_buffer = malloc(sizeof(2));
fscanf(file_stream, "%s", line_buffer);
//line = strchr(line_buffer, '\n');
printf("%s\n", line_buffer);
printf("%d\n", sizeof(line_buffer));
fclose(file_stream);
}
With this code we were attempting to output a string and its size underneath it. Strangely we keep getting the same output: 4. We needed that the malloc received a proper argument, the size of the line until the '\n'.
You can detect the magic number reading the file line by line using Linux function getline() as shown below,
void readFile (const char* input_file, char* filename){
char *line;
FILE *file_stream = NULL;
ssize_t read; size_t len = 0;
file_stream = fopen(input_file, "r");
if (file_stream == NULL)
ERROR(ERR_EXT, "Couldn't open the file for reading");
while((read = getline(&line, &len, file_stream)) != 1){
printf("%s", line);
printf("length of line: %zu\n", read);
}
if (line)
free(line);
fclose(file_stream);
}
I am trying to open a file (that wants to be a small archive) and I want to copy another file content in it. The code is the following:
FILE * arch;
FILE * par;
void read_words (FILE *f)
{
char x[1024];
while (fscanf(f," %s",x)==1)
{
fprintf(arch," %s", x);
}
}
int main(int argc, char * argv[])
{
char * nome;
nome = argv[1];
archivio = scrivi(getcwd(NULL, 0), nome);
arch = fopen(archivio, "w+");
par = fopen(argv[2], "r+");
read_words(par);
return 0;
}
Please assume that "archivio" is a working path.
i call the function as follows: ./a.out archiveName FilePath.
All i want to do is opening this archive, then, after some fprintfs (that work correctly, not shown here) opening another file and write its content in archive.
The problem is in the function read_words. It works if taken alone (I took code from here), but if I insert that here, it doesn't work, because it doesn't even enter in while (fscanf(f," %s",x)==1). In fact archive file is always empty.
Can you help me find out why?
Thanks
PS: This is an example text i tried to insert:
La funzione mkbkp si occupa della creazione di un archivio contenente i file e le cartelle passate come parametri.
The strange thing is that if you make a c file with only read_words, it works fine.
Given the way you describe the behavior of your program, I can only suppose that you are not reading the file that you want to be reading. Try using this function:
void show_file (const char *filename, FILE *out) {
int c;
FILE *file;
fprintf(out, "%s(%s) BEGIN\n", __func__, filename);
file = fopen(filename, "r");
if (file) {
while ((c = fgetc(file)) != EOF) {
fputc(c, out);
}
fclose(file);
} else {
fprintf(out, "%s: failed to open file '%s' (%d)\n", __func__, filename, errno);
}
fprintf(out, "%s(%s) END\n", __func__, filename);
}
You can call this function from your main like this:
show_file(argv[2], stderr);
Make sure the path to the file and the contents of the file match your expectations.
This is driving me crazy. I want to read from a subdirectory (./method/CoyoteAdapter.java.tk.method.514.5.533.5.bk), but my code crashes at fscan (Bus error):
void readFrag( int **sequence, int& nTokens, char* fragName )
{
FILE *file;
char tmp[200];
strncpy(tmp, &fragName[2], 198);
char szWorkingDirectory[PATH_MAX];
szWorkingDirectory[0] = '\0';
getwd(szWorkingDirectory);
printf("Attempting to open %s/%s\n", szWorkingDirectory, tmp);
file = fopen(tmp, "r");
nTokens = 0;
fscanf(file, "%d", &(*sequence)[nTokens]);
while(!feof (file))
{
fscanf(file, "%d", &(*sequence)[nTokens]);
++nTokens;
}
fclose(file);
}
// maxFragSizes: Each block has its max frag size
void init( int **seq, int& seqSize, int **sub, int& subSize, int **problemSizesPerBlock, char* fragListName )
{
FILE *file;
char line[200];
int* tokens = new int[THREADS_PER_BLOCK-1];
int nTokens = 0;
file = fopen(fragListName, "rt");
while(fgets(line, 200, file) != NULL)
{
readFrag( &(*seq), nTokens, line );
}
fclose(file);
}
However, if I copy the file to my directory, it works. I'm on UNIX (Mac OS). Please help!
Edit: I added the following code, as suggested. The output it ok, but it still doesn't work...
You must have to verify the file pointer. May be file is not found or you don't have sufficient privileges to read it.
file = fopen(fragName, "rt");
if(file==NULL)
{
printf("\nFile not found");
return 0;
}
fscanf(file, "%d", &tmp);
You aren't checking to see if "file" being returned by fopen() is NULL or not before calling fscanf. That's why you are crashing.
As to how to open a file, you may want to call getcwd (getwd) and print the result to see if you are in the parent directory that you think you are in. You probably don't need the "./" prefix in your file path, but I don't think it hurts.
void readFrag( char* fragName )
{
FILE *file;
int tmp;
char szWorkingDir[PATH_MAX];
szWorkingDirectory[0] = '\0';
getwd(szWorkingDirectory);
printf("Attempting to open %s/%s\n", szWorkingDir, fragName);
file = fopen(fragName, "rt");
if (file != NULL)
fscanf(file, "%d", &tmp);
}
int main()
{
readFrag("method/CoyoteAdapter.java.tk.method.514.5.533.5.bk");
return 0;
}
AVD is almost right -- you need to check your FILE* from fopen(3) to see if you actually opened the file. But his answer (and selbie's similar answer) both neglect the single most important piece of information: why the fopen(3) failed.
Try this:
void readFrag( char* fragName )
{
FILE *file;
int tmp;
file = fopen(fragName, "r");
if (!file) {
perror("Error reading fragment file in readFrag");
return;
}
fscanf(file, "%d", &tmp);
}
I also removed the t from the mode as I can't find any documentation anywhere that supports its use. I hope that this isn't the cause of the problem -- one would hope the libraries would be a bit more rigorous -- but because it is invalid input it certainly could be at fault. (Check your system's fopen(3) manpage and please correct me if I'm mistaken about your platform.)
Mostly likely the value of seq that you're passing in to your init function does not point at a pointer to valid memory (either seq itself is invalid, or *seq is)