Opening image files through unix system command in C - c

I have a project where the user can open files by selecting them in a menu.
I have two near identical pieces of code, but one works, whereas the other doesn't:
the one that works is for opening text files through gedit ("chemin" contains the file path):
char buf[200];
snprintf(buf,sizeof(buf),"gedit %s",chemin);
system(buf);
And this one doesn't work when run in my code, but does work when run outside of it (opens .jpg files with eog - have also tried xdg with no improvement):
snprintf(buf,sizeof(buf),"eog %s",chemin);
system(buf);
Is there a surer way of opening .jpg files from the unix command line? Or did I forget something?
TIA
UPDATE
It seems the buffer only prints its first 7 characters to the command line, ie:
my file path: ./FICHIER_PROJET/basededonnee/basedeDonneefichier/IMG_RGB/21.jpg
what the command line prints: eog ./FI
This only happens with these .jpg files

The problem might come from the char '\0' that has the wrong place, try something like :
strncpy(buf, "eog ", 4);
strncat(buf, chemin, sizeof(chemin));
buf[4+sizeof(chemin)] = '\0';
if(system(buf) == -1){
perror("Error with the system call ");
exit(-1);
}

Solved it... I had been using one general buffer for all my system commands. I created a new buffer just for this one and it works.

Related

Fopen - No such file or directory in C

This code does not open file properly, it returns no such file or directory, although the path and privilege are there and no other program is using the file. How can I fix the error? I tried swapping the path and moving the file, the error is there still.
char string[105];
FILE* file = fopen("C:\\Users\\Public\\Documents\\a.txt", "r");
while (fgets(string, 100, file)) {
printf("%s", string);
}
It can be surprisingly tricky to open a simple file! Lots of things can go wrong. I recommend writing slightly more verbose code, like this:
#include <string.h>
#include <errno.h>
char* filename = "C:\\Users\\Public\\Documents\\a.txt";
char string[105];
FILE* file = fopen(filename, "r");
if (file == NULL) {
fprintf(stderr, "can't open %s: %s\n", filename, strerror(errno));
exit(1);
}
while (fgets(string, 100, file)) {
printf("%s", string);
}
The point is that the error message prints out both the name of the file it tried but failed to open, and the actual reason it couldn't open it. (Also, by storing the filename in a variable, you make it absolutely certain that the filename it prints in the error message is the filename it tried but failed to open.) It sounds like you already know that the error was "no such file or directory", but I'm not sure how you know this.
Even though I've been programming in C for a long time, sometimes I still have this problem. One thing I'll sometimes do is use my mouse to copy the exact filename string printed in the error message, the file the program said it couldn't open, the file I'm sure is really there, and paste it into a terminal window (or CMD or Powershell if you're on Windows), along with a directory-listing command, to see if the operating system can actually see the file. That is, for your example, the command I'd run is
dir C:\Users\Public\Documents\a.txt
but the point is that I would not actually type the pathname "C:\Users\Public\Documents\a.txt", instead I would copy and paste it out of the error message that the program printed. Sometimes there are surprising little impossible-to-spot differences between the filename you thought it was trying to open, versus the filename it was actually trying to open, and this exercise is a good way to let the computer help you find those differences.
Remember, too, that you'll get the error "No such file or directory" if there's no file by that name in the directory, or if the directory isn't there at all. For example, if you're trying to open the path
C:\Users\Public\Documents\a.txt
and the file a.txt keeps not being there, and you keep checking your home directory
C:\Users\Donkey\Documents
and you keep seeing that the file is there, it can be surprisingly easy to overlook what the real problem is. :-)
Addendum: You might be having an issue with the different Unix/Linux versus Windows file path separators, that is, / versus \. Usually, on a Windows machine, it's safest to use \, as you've done. (One very frequent mistake is to forget to double the backslashes, but it looks like you got that right.) Depending on your programming environment, if there's some level of Unix emulation going on, you can sometimes use Unix-style /, and it will automatically translate to \ for you. I've never heard of a situation where using \ made it not work (which is a possibility being explored in the comments), but you might experiment with that, perhaps trying
char* filename = "/c/Users/Public/Documents/a.txt";
or (less likely)
char* filename = "C:/Users/Public/Documents/a.txt";

How to use relative path to open files in C using xcode?

I need to make a game in C for my finals. The user should input the map file he wants to play.
Here's my simple code:
int main(){
FILE *map;
char fileToRead[100];
do{
printf("Insert file name: ");
fgets(fileToRead, 100, stdin);
map = fopen("/Users/rajunior/Desktop/map_2.txt", "r");
//map = fopen(fileToRead, "r");
printf("%s", fileToRead);
If I use the "map = fopen("/Users/rajunior...)" hardcoded, it works!
But I need to use the second (commented) option; the first one is useless for my purpose.
In other words, I need the fileToRead to be in the same directory as my .c, but how?
screenshot: https://imgur.com/a/DbX9tw4
Option 1: Install the command line tools. Put the C file and the text file in the same directory. Open a terminal window. Compile and run from the command line. If I recall correctly, the command line tools download can be found in Preferences.../Downloads.
Option 2: Go to the Product/Scheme/Edit Scheme... menu. When the dialog box appears, select Run at the left and Options at the top. Then look for Working Directory. Set the working directory to point to the directory where the text file is.
This was going to be a comment, but it is too long for comfort.
You'll need to know the current directory of the process when it is run. If you run it from the shell, the current directory of your program will be the same as the current directory of the program. If you run it from within XCode, I've no idea what the directory will be, but it probably won't be where the source is — it'll be in a build directory of some sort, probably.
Your program can find out where it is run from with getcwd(). Then you'll be able to tell how to chdir() to the directory where the source is (as long as the program knows where the source is, because you told it somehow — argument or command line variable, or …). Or you can determine how to create a relative path name that will find the file in the source directory.
There's probably an XCode (maybe Objective-C) way to find the information, perhaps via plists.
I don't code for a Mac; I only code on a Mac, and I run XCode itself rather seldom.

fopen in C(Linux) returns "Too many open files"

static char filename[128] = "trace.txt";
g_file = fopen(filename, "w");
if(NULL == g_file)
{
printf("Cannot open file %s.error %s\n",filename,strerror(errno));
exit(1);
}
I am trying to open a empty text file named trace.txt in write mode (in my working directory.)
The program is creating an empty file trace.txt in my directory.but the check (NULL == g_file)
is returning true and it is returning error code 24 (Too many open files.).Any idea why this is.This is the first file I am opening in my program.
Surprisingly the code is creating an empty file in my working directory by the name specified.However the check for null file pointer is succeeding for some reason.? :(
You probably have a file descriptor leak.
If your code keeps opening files, never closing them, you will reach the limit sooner or later, and then fopen will fail.
You can check this by printing the file descriptor numbers you get whenever opening a file. If they keep growing, you have a leak.
It is most likely due to your system reaching its maximum allowed open file handles.
You can easily test this by running the following:
$ dd if=/dev/urandom of=test.dat bs=16 count=1
If you are out of file handles, this should provide the same or similar error.
You can trouble shoot this using some of the following commands:
To see the maximum allowed open files:
$ cat /proc/sys/fs/file-max
To see the which files are currently open (remember this includes device files, sockets, etc):
$ lsof
You can also use lsof to get a count of open files:
$ lsof | wc -l
This looks like a similar issue to what you're having, but I'm not entirely sure if it will help you solve the problem. Might be worth a look:
Problem with writing to file in C
Correct, I faced same error message and found that I was trying to close the file in a function but not where it was opened. So I then closed in the function where it was opened, later everything went fine.

fopen() returning a NULL pointer, but the file definitely exists

The code I have is as follows:
FILE *txt_file = fopen("data.txt", "r");
if (txt_file == NULL) {
perror("Can't open file");
}
The error message returned is:
Can't open file: No such file or directory
The file 'data.txt' definitely exists in the working directory (it exists in the directory that contains my .c and .h files), so why is fopen() is returning a NULL pointer?
Standard problem. Try
FILE *txt_file = fopen("C:\\SomeFolder\\data.txt", "r");
I.e. try opening it with the full absolute path first ; if it works then you just have to figure out what the current directory is with _getcwd() and then fix your relative path.
Is it possible that the filename is not really "data.txt"?
On Unix, filenames are really byte strings not character strings, and it is possible to create files with controls such as backspace in their names. I have seen cases in the past in which copy-pasting into terminals resulted in files with ordinary-looking names, but trying to open the filename that appears in a directory listing results in an error.
One way to tell for sure that the filenames really are what you think they are:
$ python
>>> import os
>>> os.listdir('.')
My problem was that I had a file filename.txt and I didn't realize that in reality it was filename.txt.txt due to windows not showing the extension.
Make sure that your input file is in the same directory as the executable, which may be different than the one where your source files are kept. If you're running the program in an IDE debugger, make sure that your working directory is set to the location of the input file. Also, if you're running in *nix rather than Windows, you may need to prepend a "./" to the input filename.
Invisible SPACE character in file name?
Once a year I have a similar problem:
I try to open a file with the filename in a string, obtained from a sting operation. When I print the name it seems OK, but fopen() returns a null pointer. The only help is printing the name with delimiters showing the exact beginning and end of the filename string. Of course this does not not help with unprintable chars.
I just had a similar issue like this where I knew the path was correct and the file was in the right location. Check the file permissions. It is possible that the program cannot access the file because it is getting permission denied.
I encountered the same errno to fopen on Linux from a script file corrupted by Windows.
ENOENT 2 No such file or directory
Wordpad on Windows (or some other Microsoft culprit) inserted CRLF = (0x0D, 0x0A) into my linux script files in place of newline = LF = 0x0A. When I read the file name into a buffer and called fopen if failed due to the invisible appended CR character.
In the Codelite editor on Linux Mint I was able to show EOL characters (View > Display EOL) and remove them with find and replace, using copy and paste of the CRLF from the corrupted script files and the LF from an uncorrupted file into the text fields.

C:copying multiple files into one

I am stuck/struggling with a problem I am trying in C(Linux) using API calls(only) to copy multiple input files via command line into one output file. I have searched the Internet for answers but none seem to solve.
My program allows me to specify multiple input files and one output file via the command line. For example:
./archiver file1.txt file2 file3 file4 outputfile
I read these parameters using argc/argv. For some reason when I do ls -l, ./archiver and outputfile have the same number of bytes, thus meaning none of my input files have been copied to my outputfile, just whatever was in memory (when I do cat outputfile it shows a bunch of these )
None of the contents from my input files are in my output files.
Please could you help me as after those bunch of "" I don't know what to do I have tried reading up on malloc() etc. but I don't know how to implement that or if thats even relevant here.
Any help is appreciated, thanks for your time.
file_desc_in = open(argv[i],O_RDONLY,0);
//NEED a loop to copy multiple files in...
while (!eof) {
bytes_read = read(file_desc_in, &buffer, sizeof(buffersize));
if (bytes_read > 1)
bytes_written = write(file_desc_out, &i, bytes_read);
else {
eof=1;
}
I haven't included the errors but I do have them. Thanks for replying immediately.
It'd help to see your code. There's not a lot here to go on, but I'm going to take a wild guess. I suspect you're copying the file specified by argv[0] (your program) and not getting the rest. I don't think I can do any better with what you've given.
You say you are only using API calls. What API are you talking about? The POSIX API? The standard C file I/O API?
If you are just combining input files, you don't really need to write a C program to do it. Since you are running Linux, try using the shell command cat input1 input2 input3 > output.
If you must write a C program to do it, start simple. Before you actually do any file I/O, make sure that you can interpret the input arguments correctly. Have your program simply read in the command-line input and print out something like this:
Input files: file1.txt file2.txt file2.txt
Output files: outputfile.txt
That way, you can verify that your CLI parsing code works correctly before you start worrying about file I/O. It's much easier to debug things one piece at a time.
Your outer loop needs to open each filename, and close it at the end of the loop. You close the output file at the very end, after all the input files are read.
You should also learn the difference between open, read, write and fopen, fread, fwrite.

Resources