# Thread: Problem opening input file entered by user

1. ## Problem opening input file entered by user

Hi so I have recently been having a problem trying to open a file, that is entered by the user.

Here is the assignment I have to do:

Your friend has recently come into possession of an old treasure chest. They are convinced there is great treasure inside. They may not even need to go to the Caribbean to get treasure! The treasure chest is locked with seven locks and your friend has found 100 keys that might fit these locks. Your friend and their crew members will have to try different combinations of keys to try and get the treasure chest open. There’s one other thing. The treasure chest is haunted! The pirate who previously owned this treasure is still around, reminding other pirates that each lock has a unique key and letting them know if any of their current guesses are correct. Your program will need to read in a file of the correct combination of keys, numbered 1-100. Then, prompt the user for the seven numbers indicating the seven keys they wish to use. They cannot use the same key twice in one attempt. If they have all the correct keys in the exactly correct order, they can open the chest. If they have some correct keys, regardless of order, let the user know how many keys are correct. Input File Format The input file will contain 7 unique integers from 0 to 100. Program Specification You must use arrays to solve the problem. Your program should first prompt the user for the name of the input file. Then, your program should process the input file and copy the correct order of keys into the program. Then you can prompt the user for their first guess. If the user attempts to use a key more than once in a single guess, tell them they can only use each key once. If the user exactly matches the keys and the order, let them open the chest. If the user identifies some of the correct keys, let them know how many keys are correct but tell them they may not be in the right order.

And here is the code I currently have:
Code:
```01
#include <stdio.h>

02
#include <string.h>

03
int main()

04
{

05
FILE * ifp;

06
char filename[20];

07
int i=0;

08
int keyval[7];

09
int key[7];

10
int counter;

11
printf("What is the name of the text file?\n");

12
gets(filename);

13
ifp = fopen(filename, "r");

14

15
if (ifp == NULL){

16
printf("Error the file could not be opened.\n");

17
}

18
else{

19
while(!feof(ifp)){

20
fscanf(ifp, "%d",keyval[i] );

21
printf("%d", keyval[i]);

22
i++;

23
}

24
printf("In order to get my treasure you'll have to figure out which of my 100 keys are used in the 7 locks!\n");

25
printf("Which keys will you use?");

26
for(counter=0; counter < 7; counter++){

27
scanf("%d", key[counter]);

28
}

29
if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){

30
printf("You've opened my treasure and found a map to the rest of the treasure on the island! Haha!\n");

31
}

32
}

33
fclose(ifp);

34
return 0;

35
}

```

So for some reason when I try to open the file it is always NULL, and just prints the error message that I put in. The name of the file is keylist.txt. I could also use some advice on how to go about checking if any keys are matched and how to print out the number of matches. I'm also not sure how to check to see if they use the same key more than once. Any help would be appreciated, thanks!

2. Woah, let me see if I can help you by posting something people can actually copy and paste.
Code:
```#include <stdio.h>
#include <string.h>

int main()
{

FILE * ifp;

char filename[20];

int i=0;
int keyval[7];
int key[7];
int counter;

printf("What is the name of the text file?\n");

gets(filename);

ifp = fopen(filename, "r");

if (ifp == NULL){
printf("Error the file could not be opened.\n");
}
else{
while(!feof(ifp)){
fscanf(ifp, "%d",keyval[i] );
printf("%d", keyval[i]);
i++;
}

printf("In order to get my treasure you'll have to figure out which of my 100 keys are used in the 7 locks!\n");
printf("Which keys will you use?");

for(counter=0; counter < 7; counter++){
scanf("%d", key[counter]);
}

if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){
printf("You've opened my treasure and found a map to the rest of the treasure on the island! Haha!\n");
}
}

fclose(ifp);

return 0;
}```
Now usually when the fopen() function returns NULL after trying to open a file for reading, the file is usually somewhere else. If your person on the computer types "keys.txt" the file needs to be in the same place as the program is. If it's in another directory, or on another drive, then it is part of the file path. File paths can get quite long -- much more than 20, typically -- for this reason.

So you need to ask yourself:
where is my file?
is my string long enough to point to the file?

3. Originally Posted by whiteflags
Woah, let me see if I can help you by posting something people can actually copy and paste.
Code:
```#include <stdio.h>
#include <string.h>

int main()
{

FILE * ifp;

char filename[20];

int i=0;
int keyval[7];
int key[7];
int counter;

printf("What is the name of the text file?\n");

gets(filename);

ifp = fopen(filename, "r");

if (ifp == NULL){
printf("Error the file could not be opened.\n");
}
else{
while(!feof(ifp)){
fscanf(ifp, "%d",keyval[i] );
printf("%d", keyval[i]);
i++;
}

printf("In order to get my treasure you'll have to figure out which of my 100 keys are used in the 7 locks!\n");
printf("Which keys will you use?");

for(counter=0; counter < 7; counter++){
scanf("%d", key[counter]);
}

if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){
printf("You've opened my treasure and found a map to the rest of the treasure on the island! Haha!\n");
}
}

fclose(ifp);

return 0;
}```
Now usually when the fopen() function returns NULL after trying to open a file for reading, the file is usually somewhere else. If your person on the computer types "keys.txt" the file needs to be in the same place as the program is. If it's in another directory, or on another drive, then it is part of the file path. File paths can get quite long -- much more than 20, typically -- for this reason.

So you need to ask yourself:
where is my file?
is my string long enough to point to the file?
So I tried making the string 100 long and putting the file where the project is located. Now when I run the program rather than getting the error message, it ask for the file from the user, and then I get the windows message that the program has stopped working and it is looking for a fix. Thanks for the reply

4. Yeah the program has lots more issues.

Code:
```C:\Users\jk\Desktop>gcc -Wall treasure.c
treasure.c: In function 'main':
treasure.c:27:25: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'int' [-Wformat=]
fscanf(ifp, "%d",keyval[i] );
^
treasure.c:36:19: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat=]
scanf("%d", key[counter]);
^
treasure.c:39:144: error: lvalue required as left operand of assignment
if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){
^```
Both of these can lead to a crash. You aren't calling scanf() correctly, and arrays start at 0. By attempting to read key[7] and keyval[7] to compare them, you overstep the bounds of the array.

Also assignment (=) isn't the same as equality (==). One turns a variable's value into something else, the other sees if two things are the same or not.

5. Originally Posted by whiteflags
Yeah the program has lots more issues.

Code:
```C:\Users\jk\Desktop>gcc -Wall treasure.c
treasure.c: In function 'main':
treasure.c:27:25: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'int' [-Wformat=]
fscanf(ifp, "%d",keyval[i] );
^
treasure.c:36:19: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat=]
scanf("%d", key[counter]);
^
treasure.c:39:144: error: lvalue required as left operand of assignment
if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){
^```
Both of these can lead to a crash. You aren't calling scanf() correctly, and arrays start at 0. By attempting to read key[7] and keyval[7] to compare them, you overstep the bounds of the array.

Also assignment (=) isn't the same as equality (==). One turns a variable's value into something else, the other sees if two things are the same or not.
So I fixed the problem with the (=) sign and made the arrays go from 0-6 instead of 1-7. I'm not sure exactly how I'm using scanf wrong but when I run the program now I just get the file couldn't open message.

6. I'm not sure exactly how I'm using scanf wrong
Take another look at your lessons on scanf(). Scanf wants to write to a memory address. Your lines are missing key uses of the address-of operator.
but when I run the program now I just get the file couldn't open message.
Double check the name of the file that you want to open, and make sure that you get it right. Get the extension right, and everything. If it's not exactly the same, it won't find it to open.

7. Originally Posted by whiteflags
Take another look at your lessons on scanf(). Scanf wants to write to a memory address. Your lines are missing key uses of the address-of operator.

Double check the name of the file that you want to open, and make sure that you get it right. Get the extension right, and everything. If it's not exactly the same, it won't find it to open.
The only problem that I could think of is that %d is not what you use for integer arrays. I didn't think you used %s either so I don't know what to use there.

8. it is not the %d part that whiteflags is refereeing to, it is the how to get the information into or read from the information within the type of storage container yo are using, ( and the names one uses to describe items in programming). the container being an array and pointers.

These are the errors I am getting off your code in post. 3
Code:
```gcc -Wall -o "treasure" "treasure.c" (in directory: /home/userx/bin)
treasure.c: In function 'main':
treasure.c:18:5: warning: implicit declaration of function 'gets' [-Wimplicit-function-declaration]
gets(filename);
^```
means no header to define function.
Code:
```treasure.c:27:25: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'int' [-Wformat=]
fscanf(ifp, "%d",keyval[i] );
^```
means it is expecting a int * (pointer) but is it being given just an int. the bold is the 3rd argument type int when it is looking for a int *
Code:
```treasure.c:36:19: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat=]
scanf("%d", key[counter]);
^```
same error only that it is with scanf and not fscanf it is complaining about your arrays not being shown using a pointer assignment. & or *
Code:
```treasure.c:39:144: error: lvalue required as left operand of assignment
if(keyval[1]= key[1] && keyval[2]= key[2] && keyval[3]= key[3] && keyval[4]=key[4] && keyval[5]=key[5] && keyval[6]=key[6] && keyval[7]=key[7]){
^
Compilation failed.```
means you're trying to assign the values to the left .. needs to be the comparison 'equals' not the assignment 'equals'

9. means no header to define function.
No, this probably means that you're using a modern compiler compiling for the current standard (C11) which has removed gets() from the standard.

By the way using gets() with any compiler is a very very very bad idea, this function is unsafe and can never be used safely.

Jim

10. the error implicit declaration

When you get the error: implicit declaration of function it should also list the offending function. Often this error happens because of a forgotten or missing header file, so at the shell prompt you can type man 2 function name
it does not have the header added to the include statement so it knows what it is, prototype.[/quote]

and that what you said too....

11. These are the errors I am getting off your code in post. 3
This it what I was replying to.

it does not have the header added to the include statement so it knows what it is, prototype.
Until the C11 standard the <stdio.h> header file (which is #included by the way) has the prototype for this dangerous function.

The reason you are seeing this message is probably because you're compiling a C11 compatible program, unlike the OP.

Since C11 removed the gets() function from the standard, it is no longer prototyped in <stdio.h> and the actual gets() function itself should no longer be part of the standard C library, hence your warning message.

Jim

12. I was more focused on reading error messages and knowing what they are telling someone so they can trouble shoot their code, but yes you too are correct I am not arguing that point, only now stating it is about time they took that function out. Because I personally am tired of seeing everyone that sees someone using gets being told do not use that function when they should have removed it a long time ago. so all we are seeing here is Murphy's law being applied. have a nice day.

13. Your code has several problems. First of all, if you want to write in a file, use ofstream. ifstreamis only for reading files.
[COLOR=#242729][FONT=Arial]Second of all, the open method takes a char[], not a string. The usual way to store strings in C++ is by using string, but they can also be stored in arrays of chars. To convert a string to a char[], use the c_str() method: