How to fopen with name already in a array of strings - c

I am trying to find a way to use
FILE * fopen ( const char * filename, const char * mode ); but passing the filename indirectly. i would also like to know how to indirectly call a function with name taken straightly from argv[].I dont want to store the string in a buffer char array. For example:
int main (int argc,char *argv[])
{
FILE *src;
...
src = fopen("argv[1]", "r"); //1st:how to insert the name of the argv[1] for example?
...
function_call(argc,argv); //2nd:and also how to call a function using directly argc argv
...
}
void create_files(char name_file1[],char name_file2[])
{...}
Do i have to store length and the string of chars in order to call a function? (regarding the 2nd question) :)

You can simply use argv[1], it's a char *:
if (argc < 2)
/* Error. */
src = fopen(argv[1], "r");
Same goes for create_files.
create_files(argv[1], argv[2]);

fopen takes a pointer to an array of characters. argv is pointer to an array of pointers to arrays of characters.
fopen(argv[1], "r")
will pass the pointer in the second position of the argv array to fopen.
If you want to pass argc and argv around, just pass them as they are. Their types do not change.

Related

How to read const char * from files

I need to read a filename from a text file.
Then I have to use it as an argument for fopen .
Consequently , I need to read it as a const char* because this is the type fopen accepts as a first argument. How do I do this?
I tried something like:
FILE *a;
a=fopen("a.txt","r");
const char *filename
fgets(filename,100,a);
image=fopen(filename,"rb");
Something is be wrong as I receive a segmentation fault when I do this. I think that the variable filename is not well-received by the fopen function.
You may have seen that fopen() takes an argument of type (const char *), but you need to be able to modify your string before you pass it to the function. Also, you need to allocate space for your string, and you might consider allocating space for more than 100 chars. The stdio.h header file contains the macro FILENAME_MAX, which expands to an integer constant of the correct size for an array that will hold the longest possible file name string on a system. For example, you can use char filename[FILENAME_MAX];. When the identifier filename is encountered in the call to fopen(), it decays to a pointer to char, which is converted to a pointer to const char, as per the function prototype.
Furthermore, fgets() keeps the newline when if fetches a line of text, so you will need to remove that. You should check the result of fgets(), as it returns a NULL pointer in the event of an error or if it is called at end-of-file; otherwise it returns a pointer to the first char in filename[].
FILE *a;
a=fopen("a.txt","r");
char filename[FILENAME_MAX];
char *ch;
ch = fgets(filename,FILENAME_MAX,a);
/* Remove trailing newline */
if (ch) {
while (*ch != '\0' && *ch != '\n') {
++ch;
}
if (*ch == '\n') { // replace '\n' with '\0'
*ch = '\0';
}
image=fopen(filename,"rb");
}
First, your seg fault likely comes from trying to use memory that you do not own. i.e. by creating the variable:
const char *filename;
And not giving it any memory ([c][m]alloc) before trying to use it.
Regarding your statement:
Consequently , i need to read it as a const char*.
Not necessarily.
The first argument of the fopen prototype: "FILE *fopen(const char *filename, const char *mode)" simply guarantees that the argument passed in that position will be treated as a const char * within the fopen function.
The argument can be passed using a simple char *, eg. either of these forms:
char *filename = {"somefilename.txt"};
or
char filename[80];
strcpy(filename, "somefilename.txt");
And, as mentioned in comments, and other answers, remove the newline character, \n before passing as an argument.

unable to get filename from argv[1] in C

I'm trying to make a program which makes a copy of the file you put in, only then with a reversed filename (eg. input.txt = txt.tupni).
I start my program with
int main(int argc, char **argv) {
When I use printf("%s",argv[1]) I can see the file name which has been put in. However, when I try to manipulate it I can't get it to work.
char name = argv[1] doesnt work,
neither does char name[] = argv[1] work
All I want is either a char array or a piece of malloc memory which has all of the characters.
argv is of type char **, so argv[1] is of type char *. So that's the type of the variable you want to assign this to.
char *name = argv[1];
You can't declare name as char [] and initialize it with a char *. Only a string literal may be used for initialization.
If you want to make a copy of the string rather than have another pointer to it, you can use strdup which allocates memory for the copied string and copies it over.
char *name = strdup(argv[1]);
Don't forget to free it when you're done with it.
You need to use a function like strcpy to accomplish this, as well as know the string length.
Here's what you do:
int len = strlen(argv[1])
char *buffer = (char*)malloc(len + 1);
if(buffer != NULL)
{
strcpy(buffer, argv[1]);
// copy the file etc.
}

c program crashes while trying to open a file with variable filename

As stated in the title, i ask for the user to provide the filename and i use gets to save it in str. Then i try to access the file using the name and the program crashes.
int openFile(FILE *fp){
puts("What's the name of the file (and format) to be accessed?");
char str[64];
gets(str);
fp = fopen((const char *)str, 'r');
...
return 0;
In main:
FILE *fp; // file pointer
openFile(fp);
The filename i enter (data.txt) is indeed in the same directory as the rest of the project so that should not be the problem. I've tried testing if the file is opened correctly (which it should) but it keeps crashing right after i give the name.
The main problem is that you are trying to set an argument passed by value in a function and expect the value to be changed outside. This can't work.
Currently you have:
void openFile(FILE* fp) {
fp = ...
}
int main()
{
FILE* fp;
openFile(fp);
}
But fp in main() is passed as a pointer by value. Which means that inside openFile you are setting a local variable, while the passed one is not modified.
To solve the problem you can:
directly return a FILE* from openFile
accept a pointer to pointer argument to be able to set it, eg void openFile(FILE** fp) and then openFile(&fp)
Mind that the second argument of fopen is a const char* not a single char, "r" should be used.
It should be fp = fopen(str, "r");, because fopen() expects mode as a char * pointing to a string, rather than a single char.
Also, since parameters in C are passed by value, your fp won't get modified after openFile() is called. To get it work, you'll have to rewrite it, and call it by openFile(&fp);. Here is an example:
void openFile(FILE **fp) {
puts("What's the name of the file (and format) to be accessed?");
char str[64];
fgets(str, 64, stdin);
str[strcspn(str, "\n")] = '\0';
*fp = fopen(str, "r");
}
fgets() is used to provide buffer overflow protection.

Dynamically allocated string from command line argument

I'm looking to process a string passed via a command line argument with a for loop in C. I'm wondering if this would be the correct way.
main(int argc, char * argv[])
{
char * somestring;
somestring = malloc( (strlen(argv[1]) + 1) * sizeof(char) );
somestring = argv[1];
...
}
or would C allocate the appropriate memory if I did:
char * somestring;
somestring = argv[1];
If you want to copy an argument in your own allocated memory then you have to write
int main(int argc, char * argv[1])
{
char * somestring;
somestring = malloc( strlen( argv[1] ) + 1 );
strcpy( somestring, argv[1] );
...
}
otherwise statement
somestring = argv[1];
results in a memory leak.
Also do not forget to free the memory when it will not be needed any more.
Take into account that though this record
int main(int argc, char * argv[1])
is valid it is better to write
int main(int argc, char * argv[])
because your intention by specifying char * argv[1] is not clear
If you need to preserve a transient string then yes you need to allocate memory, copy it into the new buffer (via strcpy-like function) and latter deallocate that buffer.
But in this case, the command line arguments are not transient. They are available for the whole lifetime of the process. Therefore it is enough to just remember the pointer to them. So something like this would be enough:
const char* firstParameter = nullptr;
int main(int argc, char* argv[])
{
if (argc > 1) firstParameter = argv[1];
}
A good way would be allocating the memory for the pointer and use strcpy function to copy the contents.
For example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, char * argv[])
{
char *somestring;
if(argv[1] == NULL)
{
puts("Argument 1 is not specified.");
exit(1);
}
somestring = malloc( strlen(argv[1])+1 );
strcpy(somestring, argv[1]);
printf("%s\n",somestring);
return 0;
}
Also before allocating the memory for pointer, first check if argv[1] is not NULL.
Fisrt of all this is a wrong way of copying a string into another string.
You have done memory allocation correcly but your method of copying a string into another is wrong. You have allocated memory for string and collected its address into somestring. Now you are assigning argv[1] to it which is address of command line argument vector which is 2D array actually. So you should use strcpy() to copy string.
Or if you want just base address of string use char pointer instead and assign argv[1] to it. But it is of no use.
P.S. passing command line argument like you are doing is not recommended as all arguments are stored in argument vector argv which is 2D array. So if you are passing only one string then it is okay but if you are passing more than one strings then use char **argv instead.

using arg vector in fopen

I wish to have a file name as an argument to the C program. I tried all the possible ways in fopen something like the below.
fp = fopen(*argv[2], "r");
Also used "*argv[2]" but did not work. I want to know where I am going wrong so that I can use this correctly. Thanks!
It should be
fp = fopen(argv[2], "r");
Please be aware that argv[0] will contain your exe name(with path), other arguments which you pass will start from argv[1].
Refer to this for more details on using command line arguments in C.
In your main function if you are getting char **argv as the argument, the array subscripting argv[1] automatically turns it into a char * which is expected as an argument by fopen.
fp = fopen(argv[2], "r" )
is enough
argv is an array of character pointers. Indexing this array gives you the strings you've passed on the command line. You don't need further dereferencing with an additional *
fopen takes a char* as argument for the filename:
FILE *fopen(const char *path, const char *mode);
You just need to use it like:
fp = fopen(argv[2], "r"); // if 2nd argument passed is your filename

Resources