Strange error, argv[4] being set to null when a file exists?

Jan 28, 2017 at 6:58pm
Strange error, argv[4] being set to null when a file exists?

I think reading the code and reading the output would describe this issue the best. When I run the program, when specC doesn't exist, I get the error "Error: opening file out.nes failed." but when I run the program when the file does exist, I get "Error: opening file (null) failed.". I'm having a hard time understanding why this is happening.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include<cstdio>

int main(int argc, char* argv[])
	{
	if(argc != 4)
		{
		fprintf(stderr,"\x1b[31;1mError:\x1b[0m 3 arguments needed\n");
		return 1;
		}
	
	FILE* specA;
	FILE* specB;
	FILE* specC;
	
	if((specA = fopen(argv[2],"r")) == NULL)
		{
		fprintf(stderr,"\x1b[31;1mError:\x1b[0m opening file %s failed.\n", argv[2]);
		return 2;
		}
	if((specB = fopen(argv[3],"r")) == NULL)
		{
		fprintf(stderr,"\x1b[31;1mError:\x1b[0m opening file %s failed.\n", argv[3]);
		return 2;
		}
	if((specC = fopen(argv[4],"w+")) == NULL)
		{
		fprintf(stderr,"\x1b[31;1mError:\x1b[0m opening file %s failed.\n", argv[4]);
		return 2;
		}
	
	int C;
	
	for(C = 0;C < 1048576;C++)
		{
		putc(

		(
		getc(specA) +
		getc(specB)
		) /2
		
		, specC);
		}
	}



$ ./exec C/2.nes C/1.nes out.nes //out.nes does not exist.
Error: opening file out.nes failed.
$ ./exec C/2.nes C/1.nes out.nes //out.nes does exist.
Error: opening file (null) failed.
$ ./exec C/2.nes C/1.nes out1.nes //out1.nes does not exist.
Error: opening file out1.nes failed.
$ ./exec C/2.nes C/1.nes out.nes //out.nes does exist.
Error: opening file (null) failed.
$ ./exec C/2.nes C/1.nes out.nes //out.nes does exist.
Error: opening file (null) failed.
$ ./exec C/2.nes C/1.nes out.nes  //out.nes does exist.
Error: opening file (null) failed.


Also, why is this website so broken? It seems to be getting worse every day.
Last edited on Jan 28, 2017 at 7:01pm
Jan 28, 2017 at 7:54pm
Do you realize that arrays start at zero not one? Are you aware that argv[argc] is guaranteed to be a null pointer?

Edit: And note argv[0] is usually the program name, your command line arguments start at the second element of this array.

Last edited on Jan 28, 2017 at 7:56pm
Jan 28, 2017 at 8:15pm
I do realize that arrays start at zero. No, I'm pretty sure argv[argc] is NOT guaranteed to be a null pointer, as my faulty program and many faulty programs I've written have demonstrated.

Thanks for explaining my silly mistake, anyways. It's always the simple things...
Jan 28, 2017 at 8:26pm
No, I'm pretty sure argv[argc] is NOT guaranteed to be a null pointer,

Ah, but it is.

From the C99 draft standard.


5.1.2.2.1 Program startup

2. If they are declared, the parameters to the main function shall obey the following
constraints:
— The value of argc shall be nonnegative.
argv[argc] shall be a null pointer.


Look at your error messages "Error: opening file (null) failed."
This demonstrates that the pointer is a NULL pointer. Remember you tried to access argv[4], this would be the same as trying to access argv[argc] in this program (remember argc is equal to 4).



Jan 28, 2017 at 8:49pm
Good point, but in all cases I'm trying to access argv[argc], and some of those cases argv[argc] is equal to "out.nes" and "out1.nes", not always null. If it helps, I'm running gcc main.cpp -o exec to compile, and I'm running gcc 6.3.1-1. I don't know why it isn't null if it says to in the standard, but I know it's not always null via demonstration.
Jan 28, 2017 at 10:41pm
but in all cases I'm trying to access argv[argc]

No, argc is the number of parameters, 4 in this case. You tested argc to insure that it's value was 4, if it wasn't you returned from the function. If it was equal to 4 you proceeded, to the if() statements. In each of those if statements, except the last, you used an array index value that was less than argc those strings would be equal to whatever the corresponding command line argument contained. In your last if statement you tried to use an index value that was equal to argc, which is a NULL pointer as indicated by your error messages.

I don't know why it isn't null if it says to in the standard

argv[argc] was indeed a NULL pointer in your program, remember in this case argv[4] is the same as argv[argc].

For example the following sample run line: "yourProgramName parameter1 parameter2 parameter3" would produce the following output:

argv[0] = "yourProgramName"
argv[1] = "parameter1"
argv[2] = "parameter2"
argv[3] = "parameter3"
argv[4] = NULL

Jan 29, 2017 at 2:00am
You're not understanding what I'm saying. In the last test case, I was always testing argv[4], but argv[4] was not always null, as demonstrated by:

$ ./exec C/2.nes C/1.nes out.nes (this was typed into a terminal)

Error: opening file out.nes failed. (The output of the program)

The variables, in this case, were equal to:
argv[0] = "./exec"
argv[1] = "C/2.nes"
argv[2] = "C/1.nes"
argv[3] = "out.nes"
argv[4] = (supposed to be null, but actually "out.nes". If it was equal to null, then the output would have been "Error: opening file (null) failed." but it WASN'T in this case.)
Jan 29, 2017 at 2:55am
You're not understanding what I'm saying. In the last test case, I was always testing argv[4], but argv[4] was not always null, as demonstrated by:


If, as is the case in the OP, "out.nes" doesn't actually exist, then argv[4] would never be evaluated since trying to open "out.nes" (argv[3]) for reading would fail prior to that happening. I would suggest that some of your trials were run in different environments (one where "out.nes" existed and one where it did not.)
Last edited on Jan 29, 2017 at 2:56am
Jan 29, 2017 at 5:30am
Oh! Ugh, I make the silliest mistakes sometimes. I don't get why I keep doing this... I haven't programmed in a while, and I just wrote the program as a fun experiment. How are you guys able to analyze code so well, and able to catch on to things that always seem to go over my head?
Topic archived. No new replies allowed.