Another C question - fopen() function

Special K

Diamond Member
Jun 18, 2000
7,098
0
76
I have a program that is supposed to create multiple text files. What I did was create an array of pointers to point to the filenames, an array of pointers to point to the text for each file, and an array of FILE pointers to use with fopen(). The program compiles with no errors or warnings. Without showing the whole source, I have narrowed the problem down to one line (I think):

filepointer[counter] = fopen(filename[counter],mode);

filepointer is the array of pointers to type FILE, filename[] is the array of pointers pointing to the filenames, and mode is w. This line of code will not execute when the first argument to fopen is one of an array of pointers to a string. It works fine if i give it text ("file.txt") or just the name of a single string, but not if I give it a pointer from an array of pointers. I know that the string contains the text it is supposed to (For example, file.txt) because I checked it after the error occured. What am I doing wrong here? Also, I thought you couldn't pass arrays to functions? (unless they are arrays of pointers? is that right?)
 

DaveSimmons

Elite Member
Aug 12, 2001
40,730
670
126
you don't really give us enough information, but that one line should work providing that filename is an array of strings (char** ) not just a single string (char* ).
e.g.
GOOD: filename[ 0 ] is char*
char filename[ 10 ][ 256 ] ;
strcpy(filename[ 0 ] , "file.txt" ) ;

BAD: filename[0] is just 1 char not char*
char filename[ 10 ] ;
strcpy(filename[ 0 ] , "file.txt" ) ;
 

Special K

Diamond Member
Jun 18, 2000
7,098
0
76
you don't really give us enough information, but that one line should work providing that filename is an array of strings (char** ) not just a single string (char* ).

Thats what I did... I declared it as char *filename[20]; (array of pointers to strings). I don't think you would use char** to declare an array of pointers. Also the section I have that checks for an error looks like this:

if (filepointer[counter] == NULL)
{
fprintf(stderr,"error opening file.\n");
fprintf(stderr,"mode was %s\n",mode);
fprintf(stderr,"filepointer[%d] was %d\n",counter,filepointer[counter]);
fprintf(stderr,"filename[%d] was %s\n",counter,filename[counter]);
fprintf(stderr,"filetext[%d] was %s\n",counter,filetext[counter]);

system("pause");
exit(1);
}

the last 3 fprintf lines display the strings that the pointers point to, and all of them contain the text that was inputted, so I think I declared the arrays correctly.
 

singh

Golden Member
Jul 5, 2001
1,449
0
0
This example might help:

#include <stdio.h>
#include <stdlib.h>


typedef struct FileInfo
{
char strFileName[255];
FILE *pHandle;

}FileInfo;


main()
{
FileInfo MyFiles[3];

strcpy(MyFiles[0].strFileName, "c:\\1.txt");
strcpy(MyFiles[1].strFileName, "c:\\2.txt");
strcpy(MyFiles[2].strFileName, "c:\\3.txt");

for(int i = 0; i < 3; ++i)
{
MyFiles.pHandle = fopen(MyFiles.strFileName, "rt");
fclose(MyFiles.pHandle);
}

}
 

HigherGround

Golden Member
Jan 9, 2000
1,827
0
0
here's another example, something close to what you have I hope.


#include <stdio.h>

int main(void)
{
FILE* fp[4];
const char* fn[] = { "1.txt", "2.txt", "3.txt", "4.txt", NULL };
int j = 0;

for(; fn[j]; j++) {
if(!(fp[j] = fopen(fn[j], "w+"))) {
perror(fn[j]);
continue;
}
fprintf(fp[j], "%s", fn[j]);
fclose(fp[j]);
}

return 0;
}
 

Special K

Diamond Member
Jun 18, 2000
7,098
0
76
Thanks for the examples. It works fine if I initialize the filenames at the beginning, however that is something that I would like to be able to control from within the program. I don't know why this isn't working.
 

singh

Golden Member
Jul 5, 2001
1,449
0
0
Originally posted by: SpecialK
Thanks for the examples. It works fine if I initialize the filenames at the beginning, however that is something that I would like to be able to control from within the program. I don't know why this isn't working.

Post the code.
 

Special K

Diamond Member
Jun 18, 2000
7,098
0
76
I finally found the problem (sort of). The lines where I had the user input the filename and text looked like this:

fgets(buffer,79,stdin);

but then later in the program i used strlen to know how much memory to allocate to store the string. The problem was that strlen was reporting that the string was 1 character longer than it really was. When I changed the function to gets(), the problem went away. I don't know what difference there is between fgets and gets that would cause that problem. The line where I store the string is this:

filename[counter] = (char *)malloc(strlen(buffer)+1);

buffer is just a temp. array for holding the input. I even tried taking off the +1 since strlen was reporting it being 1 char longer than it really was) but that didnt change anything either.
 

Descartes

Lifer
Oct 10, 1999
13,968
2
0
filename[counter] = (char *)malloc(strlen(buffer)+1);

In C, you don't want to cast the return values of functions that return a void *. In C you can assign anything to a void pointer. You only have to explicitly cast a void * to a type when you dereference it.