When running my C code on WSL (ubuntu), I'm attempting to use fopen() on a file that 100%, positively, absolutely exists. And yet, it keeps saying that it doesn't exist despite it 100%, positively, absolutely existing.
int main (int argc, char *argv[]) {
char *path = "/bin/";
char *line;
// runs batch mode (tests use this mode)
if (argc == 2) {
char *line;
FILE *fp;
for (int i = 0; i < strlen(argv[1]); i++) {
if (argv[1][i] == '\n') {
argv[1][i] == '\0';
}
}
fp = fopen(argv[1], "r");
if (fp == NULL) {
perror("fopen");
}
I'm 100% certain that it's searching in the correct directory, because if I change the mode from "r" to "w", it creates a file with an identical name in the correct directory, right next to the file that already exists with the same name.
I'm seriously at the end of my rope. Absolutely none of this makes sense, especially how it doesn't pick up on there being duplicate files. Can someone please help?
Make certain your input file, that "exist" is not also used someplace else exclusively, like an editor.
Form a sibling file.
Example:
FILE *outf = fopen("test.txt", "w");
if (outf) {
fprintf(stderr, "<%s>\n", argv[1]);
fprintf(outf, "<%s>\n", argv[1]);
fclose(outf);
}
fp = fopen(argv[1], "r");
Was that test file located where you expected and with the expected contents?
Post that files contents.
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)
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);
}
Question Edited
i'm giving a bit of a background on my problem hoping that'll help you understand it better:
I've recently updated my IDE to VC++ 2017 . I've written a basic assembler (for mips ISA) as part of my studies.
All worked well till i've reached the final part of printing the memory image to text file - i've noticed that altough the file pointer was allocated with a value(not NULL) after using "fopen", nothing was written to it.
Here is the definition and the opening of the input/output files(out of context since lack of space);
//File Pointers
FILE *fp_mem = NULL, *fp_asm = NULL;
/** Entering Main Function **/
// open files
fp_asm = fopen(argv[2], "r");
fp_mem = fopen(argv[1], "w");
if (fp_asm == NULL || fp_mem == NULL)
{
perror("ERROR");
exit(errno);
}
/** Assembler functionality **/
//write to file loop
for (i = 0; i <= highest_mem_access && i < MEM_SIZE; i++)
{
int temp = fprintf(fp_mem, "%08X\n", mem[i]);
}
//free label memory
free_label_list();
fclose(fp_asm);
fclose(fp_mem);
I tried various options instead of fpritnf - didn't work.
Most importantly - No File is created in my project directory!
Any idea guys? i'm pretty hopeless... I'll share more of my code if needed.
EDIT
This is a simple try to write to files in VS2015:
#include <stdio.h>
int main()
{
//FILE *fp = fopen("C:/Users/Tom/Desktop/test.txt", "w");
FILE *fp = fopen("test", "w");
if (fp == 0)
{
perror("ERR");
return(11);
}
int count = fprintf(fp,"Hello there,General Kenobi");
fclose(fp);
}
fp isn't NULL , Count = 26 after fprintf , No file located anywhere.
I also tried to write to another location(in comment) - same issue.
I have a program that opens files based on the char **argv command line arguments. Here's the logic:
char * openErrorString = "Error opening file: ";
FILE *fp1 = fopen(*++argv, "r");
if (fp1 == NULL) {
perror(openErrorString);
return 1;
}
FILE *fp2 = fopen(*++argv, "r");
if (fp2 == NULL) {
perror(openErrorString);
return 1;
}
The problem is, I later want to compare the two files and give meaningful output when lines in the files do not match. Here's the code I wrote for that:
while (fgets(fp1Line, max, fp1) != NULL &&
fgets(fp2Line, max, fp2) != NULL) {
if (strcmp(fp1Line, fp2Line)) {
printf("%s\n","Line discrepancy found:");
printf("%s: %s\n", argv[1], fp1Line);
printf("%s: %s\n", argv[2], fp2Line);
fclose(fp1);
fclose(fp2);
return 0;
}
}
However, when I call argv[1] in my printf statement, I get (null), i.e., the final entry in argv. When I call argv[2], I get TERM_PROGRAM=Apple_Terminal. I have no idea what that is. What appears to be happening is that because I incremented the argv pointer twice when accessing it to open the files, argv now starts at the second command line argument. Is there a good way to reset this behavior other than doing two lines of *argv-- after I open the files?
My advice would be to not modify argv. Make a copy of the pointer into another variable, and increment that. This way you can use argv again and again and not worry about where it's pointing right now.
Just don't increment argv, on example:
FILE *fp1 = fopen(argv[0], "r");
// ...
FILE *fp2 = fopen(argv[1], "r");
There is no reason to change the argv pointer if you need it again. Instead, replace
FILE *fp1 = fopen(*++argv, "r");
by
FILE *fp1 = fopen(argv[1], "r");
and
FILE *fp2 = fopen(*++argv, "r");
by
FILE *fp2 = fopen(argv[2], "r");
i tried to read text file in xcode but this
"EXC_BAD_ACCESS message showed up when i tried to build my program
here is my code
and i put inputA.txt file in the same folder with project file
my friend told me that i should put txt file in debug folder is this why i cannot read txt
file in this code? please help me...
macbook user.
int main (int argc, const char * argv[]) {
FILE* fp;
char mychar;
char arr[50][2] = {0, };
int i = 0;
int j, k;
graphType* G_;
G_ = (graphType*)malloc(sizeof(graphType));
Create(G_);
fp = fopen("inputA.txt", "r");
//fp = fopen("inputB.txt", "r");
//fp = fopen("inputC.txt", "r");
while(1){
for(j = 0 ; j < 2 ; j++){
mychar = fgetc(fp);
if(mychar == EOF)
break;
else if(mychar == ' ')
continue;
arr[i][j] = mychar;
}
i++;
}
Per default your binary will be generated in ProjectDir/build/Mode, with Mode being Debug or Release, and will have that as its working directory. If you want to refer to a file in the project directory, you'd have to use ../../input.txt in that case.
The build locations are configured in the "Build Locations" section in a targets or projects build tab. The working directory can be manually changed in the settings for the executable ("General", "Set the working directory to:") if needed.
If you are having doubts then you can always find out what the working directory is:
#include <unistd.h>
int main() {
char buf[2048];
getcwd(buf, sizeof(buf));
printf("%s", buf);
}
Most likely inputA.txt is not in the same file as the binary. You should make sure the text file is copied to the output directory in your project (whether manually or by hand).
Also, fopen will return NULL if the file couldn't be opened, so you might want to add a check for that.
if (fp == NULL)
{
printf("Could not open file!");
return 1;
}
fopen is probably returning null because your text file isn't in the right place. Don't forget to check for null!