Reference a file in C static library - c

I created a static library in C using Visual Studio. This library contains a function which accesses a text file stored in that current directory. The library was built properly. But the problem is that when I call the function from outside other project it is not loading that text file( I linked the .lib file properly everything else is working except for loading of that file).
Any ideas how to load a text file from .lib file just by relative path??
Thanks in advance..
The following is the library test function definition
int test()
{
FILE *fp = fopen("hello.txt", "r");
if(!fp) printf("File Error");
return 0;
}
The test.lib file is built and created for this.
Just accessing the current folder hello.txt file but when this function is called from other Project. it is saying File Error.

Modify your code to look at the errno:
#include <errno.h>
#include <string.h>
...
if(!fp) printf("File error: %s\n", strerror(errno));
And then look up the meaning of the errno on your operating system to see what's going on.

I'm pretty sure the fact that you're calling this function from a library is a red herring.
What's most likely happening is that your hello.txt file is not in the working directory of the executing process. Go ahead and #include <windows.h> in your project, and use the GetCurrentDirectory function to see what the working directory is when you run your program. Most likely, it's not the same path as your text file.
To remedy this, you can do one of two things: you can change the startup settings of the program (whether that's from Visual Studio or a Windows shortcut) to specify the working directory (called "Start in:" for a Windows shortcut) to be the path to the text file you want to open, or you can figure out what working directory your program has been using and move your text file there instead.
Edit: Also, if you want the application to use its own directory (where the executable file actually resides) you can use the GetModuleFileName function to get the full path of the executable. Of course, you'll have to trim the filename of the program off the end of the string it produces, but that should be a piece of cake.

Check your file path and print an errno, I think you have a static file path

Related

Unexpected error when reading from a text file in C

I'm trying to read text from a file (should be pretty easy right?). As far as I recall, the syntax should look something like
FILE *filename;
filename = fopen("filename.txt", "r"); /*when file is the same
folder of the .exe*/
Below is my code. When I run it, I simply get "Error", which is the prompt I wanted in case of an error. I included here a global struct declaration because it's literally the only other thing in the code, even though I'm positive it's not causing any problem with opening the file.
#include <stdio.h>
#include <stdlib.h>
struct list {
char subject[20];
char prof_name[20];
char prof_surname[20];
char period[20];
int credits;
int pass_rate;
};
int main()
{
struct list data[80];
FILE *prof;
prof = fopen("professor.txt", "r");
if (prof == NULL) {
fprintf(stderr, "Error");
exit(EXIT_FAILURE);
}
return 0;
}
The file has the correct name and extension, it's in the same folder as the .exe (I've also tried with the address, it still does the same). I feel like I'm going to get crazy if I look at the code even for just one more minute. There must be something I missed
Regarding the comment "when file is the same folder of the .exe", that is incorrect.
Instead relative paths (like your professor.txt) is relative from the process current working directory. Which might be very different from the location of the .exe file.
My guess is that you're running inside Visual Studio (or other IDE) which places the executable files in a sub-directory. The working directory when running, though, is usually the project root directory.
So either go into the project settings and change the working directory when running the program into the directory where the file is located, or move the file to the actual working directory.
You can use the _getcwd function to get the process working directory, to verify that it is what you believe it is.

Opening and Creating files in C Issue?

So, I have written a simple program in C which opens a file called prog6_input.txt and generates another file called prog_output.txt. However, the code below works perfectly for Windows but fails whenever I compile on a Mac. (I also assume this is having the same issue with create the file as well)
FILE *ptr_file = fopen("prog6_input.txt", "r");
// We Don't have a input file
if(!ptr_file) {
perror("Error Reading Input file.\n");
return 1;
}
For perror:No Such file or directory
The file, as seen in the screenshot below, is in the same directory. This works in windows, but does not in Mac OSX? Why is this and how would i fix it?
UPDATE: In order to vompile i used make main in the directory using terminal.
You should open up a terminal, cd to your Prog6 directory, and run your executable with ./main.

Relative paths from binary file

I have the following folder structure:
bin/ <-binary-file is in here
include/
src/
data/
Makefile
In my code, I use relative paths to my data. So "../data/xml/xmlFile.xml". This is fine if I were executing the binary file from the bin/ folder:
brandonto#computer:~/PATH-TO-PROJECT/bin$ ./binary-file
argv[0] = ./binary-file
dirname(argv[0]) = .
But if I were executing the binary from the main folder (or any other folder that is not the bin/ folder):
brandonto#computer:~/PATH-TO-PROJECT$ bin/binary-file
argv[0] = bin/binary-file
dirname(argv[0]) = bin
The xml files would not be found because "../data" would now go up one directory from the main folder (or whatever folder you are in when executing the program).
How could I make it so that the binary file could be executed from any directory on my system?
To make the question a little more clear:
brandonto#brandonto-Aspire-S3-391:~/cpp-workspace/sdl-projects/sdl-space-shooter/bin$ ~/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter
argv[0] = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter
dirname(argv[0]) = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin
brandonto#brandonto-Aspire-S3-391:~/cpp-workspace/sdl-projects/sdl-space-shooter/bin$ cd ..
brandonto#brandonto-Aspire-S3-391:~/cpp-workspace/sdl-projects/sdl-space-shooter$ ~/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter
argv[0] = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin/SpaceShooter
dirname(argv[0]) = /home/brandonto/cpp-workspace/sdl-projects/sdl-space-shooter/bin
Unable to load image ../data/graphics/background/darkPurple.png! SDL_image Error: Couldn't open ../data/graphics/background/darkPurple.png
Unable to load image ../data/graphics/sprites/meteorBrown_big1.png! SDL_image Error: Couldn't open ../data/graphics/sprites/meteorBrown_big1.png
Here, I executed the binary file once from inside the bin/ folder, then once from inside the main folder. The binary ran fine from inside the bin/ folder, but could not find the relative paths to the .png files from inside the main folder.
Probably you are asking a wrong question: the build system has nothing to do with program execution.
However, if you look for an answer, how to make my program to correctly use data, that is located relative to program installation, than here is an answer.
When you program main gets executed, it gets the binary path as the first parameter (index 0). That path can be relative or absolute, but in any case it allows you to find the base directory.
These are also useful links:
How do I find the location of the executable in C?
Finding current executable's path without /proc/self/exe
Here how you can use first argument:
#include <linux/limits.h>
#include <stdio.h>
#include <string.h>
#include <libgen.h>
int main(int argc, char *argv[])
{
char datadir[PATH_MAX];
strncpy(datadir, argv[0], sizeof(datadir));
dirname(datadir);
strncat(datadir, "/../data", sizeof(datadir));
printf("Data dir: %s\n", datadir);
return 0;
}
I believe that you can find your process id (pid) using the getpid command and perform functions to extract the directory in a manner similar to this question on Ask Ubuntu.
I would have the data associated in some way (organizationally) with the bin directory where the executable resides.
Then, when running the routine, if a complete path is provided (noted by checking arg[0]), then you can find the data directory. If a relative path is provided, then search the search path sequentially until you find the executable, and then you can therefore find the data directory.
No pids needed. (I think this is how Python finds its way, or at least how it used to do so.)
I usually solve this with a program setting. In the good old days I would have these settings in a .ini file which would accompany the executable. Some settings would be configurable from within the program, and all could be edited with a text editor. If the file was missing, or any setting missing, they would be created by default.
For the location of the program's data I would use its full absolute path name. For example it might be
Datapath = D:\os50k
and the program then appends individual file names to the path as necessary.
These days in Windows the System Registry is used for this purpose. However your question is tagged Linux which stores settings in various places, including the program directory.
This question, and this question describe the process more fully.
If your paths can be determined at build time, (i.e. your project will never need to be installed to another directory,) you can inject the path through the build system as a preprocessor definition. Here's an example with CMake:
file(TO_CMAKE_PATH "${PROJECT_BINARY_DIR}/resources" RESOURCE_DIR) # Normalize Windows/Linux paths
add_custom_command(
TARGET my_target POST_BUILD
COMMAND ${CMAKE_COMMAND} ARGS -E copy_directory ${CMAKE_CURRENT_SOURCE_DIR}/resources ${RESOURCE_DIR}
)
target_compile_definitions(my_target PUBLIC RESOURCE_DIR=${RESOURCE_DIR})
.
#define VAL(x) #x
#define STR(x) VAL(x)
const char* my_resource = STR(RESOURCE_DIR) "/my_resource.abc";

How to make .txt files visible to Visual C

I'm writing a program to that needs to read 32-bit binary numbers in as strings from a text file (notepad). The file contents look like this:
11111111111111110111100011111110
11111111111111111111111111110101
00000000100001011010101011110101
00000000000000000000000010010001
Every time I try to run the code I get the error message saying that the debug assertion failed because the (stream != NULL) condition was not satisfied. I assume that this comes from an error with the fscanf part of the code. I have looked at similar questions with the solution usually being to move the text file to the current working directory, but I am not sure what this means. I am using visual studio Express 2013, and have the text file saved under resource files in my console application. I also have the console application and the text file saved in a single folder on my desktop. Neither of these seem to have had any effect in resolving the error. Here is my source code if it helps at all:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<math.h>
void main()
{
char str[34];
FILE *binnz;
binnz = fopen("binns.txt", "r");
while (fscanf(binnz,"%s",str) != EOF)
{
printf("%s\n", str);
}
fclose(binnz);
}
If the problem is where the text file is stored, where -exactly- do I put it?
Thanks in advance.
I have looked at similar questions with the solution usually being to move the text file to the current working directory, but I am not sure what this means.
The working directory of a program basically allows it to open files by a relative path. Typically, the working directory of a program will be wherever the executable file resides (so it can easily reference files in the same directory); however, when debugging in Visual Studio, it'll use the project directory as the working directory by default. You can change this under the "Debugging" page of your project settings, or you can just put binns.txt in your project directory.
The resource directory is the wrong place. Add a system("dir") to your program, and it will show you where your program is running. Put your file in there, and you should be good to go.

Unable to open a file with fopen()

I've been trying to open a file and output text, but I keep getting errors. So I thought I would start at the very beginning and just try opening the file. This is my code:
#include <stdio.h>
#include <stdlib.h>
#define CORRECT_PARAMETERS 3
int main(void)
{
FILE *file;
file = fopen("TestFile1.txt", "r");
if (file == NULL) {
printf("Error");
}
fclose(file);
}
When I run the file, "Error" gets printed to the console and that's it. The TestFile1.txt is in the same location as my .exe. How do I fix this?
Instead of printf("Error");, you should try perror("Error") which may print the actual reason of failure (like Permission Problem, Invalid Argument, etc).
How are you running the file? Is it from the command line or from an IDE? The directory that your executable is in is not necessarily your working directory.
Try using the full path name in the fopen and see if that fixes it. If so, then the problem is as described.
For example:
file = fopen("c:\\MyDirectory\\TestFile1.txt", "r");
file = fopen("/full/path/to/TestFile1.txt", "r");
Or open up a command window and navigate to the directory where your executable is, then run it manually.
As an aside, you can insert a simple (for Windows or Linux/UNIX/BSD/etc respectively):
system ("cd")
system("pwd")
before the fopen to show which directory you're actually in.
Your executable's working directory is probably set to something other than the directory where it is saved. Check your IDE settings.
A little error checking goes a long way -- you can always test the value of errno or call perror() or strerror() to get more information about why the fopen() call failed.
Otherwise the suggestions about checking the path are probably correct... most likely you're not in the directory you think you are from the IDE and don't have the permissions you expect.
Well, now you know there is a problem, the next step is to figure out what exactly the error is, what happens when you compile and run this?:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *file;
file = fopen("TestFile1.txt", "r");
if (file == NULL) {
perror("Error");
} else {
fclose(file);
}
}
In addition to the above, you might be interested in displaying your current directory:
int MAX_PATH_LENGTH = 80;
char* path[MAX_PATH_LENGTH];
getcwd(path, MAX_PATH_LENGTH);
printf("Current Directory = %s", path);
This should work without issue on a gcc/glibc platform. (I'm most familiar with that type of platform). There was a question posted here that talked about getcwd & Visual Studio if you're on a Windows type platform.
Try using an absolute path for the filename. And if you are using Windows, use getlasterror() to see the actual error message.
The output folder directory must have been configured to some other directory in IDE. Either you can change that or replace the filename with entire file path.
Hope this helps.

Resources