Debug Assertion Failure on gets(char) function

K

kudruu

Hello,
I am having a problem in Microsoft Visual C++ with some code I have
written (I am a bit of a novice so I appologize if this is a very
mundane problem).
This is a segment from one of the functions I am using. I am trying
to get a user to input whether they want an output file or not and if
they do to specify the name. Output_File is a global char.
Maybe there is a better way to do this, nonetheless, it compiles with
a LNK4075 warning.
When I run the code, however, it allows me to enter the if statement
and type my preference. Then it doesn't even advance to the next
print statement (in or outside of the if), it quits with the message:

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}
 
K

kudruu

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

So I did a little bit of tweaking and now it reads:
printf("Do you wish to write an output file (y/n)? ");
scanf("%s",&Yes_No);
printf("Got Here\n");
if (Yes_No[0] == 'y'){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

This works only for the case of y, however I still get the error on n
(and any other letter). After this function, there are several other
functions that must be called using Output_File, is it possible to set
a character array to Null or False?
 
K

kudruu

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

So I did a little bit of tweaking and now it reads:
printf("Do you wish to write an output file (y/n)? ");
scanf("%s",&Yes_No);
printf("Got Here\n");
if (Yes_No[0] == 'y'){
printf("\nPlease input the desired name of your file:
");
scanf("%s",&Output_File);
}

This works only for the case of y, however I still get the error on n
(and any other letter).

Putting an else statement in that reads:
else
ACS_Output_File = NULL;
Only produces an error that my left operand must be an l-value (type
mismatch). I thought the syntax
else
ACS_Output_File[] = NULL;
would work but it gives me a bracket error.

After this function, there are several other
functions that must be called using Output_File, is it possible to
set
a character array to Null or False?
 
R

Richard Tobin

Richard Heathfield said:
Never compare strings with ==.

Hardly ever.

It is sometimes useful to "intern" strings, that is, ensure that there
is always only one string with a given value in a given set. The main
reason for doing this is exactly so that you can compare them with ==.

I once had a program that went usefully faster after "strcmp(a,b) == 0"
was replaced with "a == b || strcmp(a, b) == 0", because there was a very
high chance that equal strings would have come from the same source and
thus be equal as pointers.

-- Richard
 
R

Richard Heathfield

(e-mail address removed) said:

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

Never use gets. Never use %s in scanf. Never compare strings with ==.
Never use a single-character array to store a non-empty string.

#include <stdio.h>
#include <string.h>

int chomp(char *s)
{
char *p = strchr(s, '\n');
if(p != NULL)
{
*p = '\0';
}
return p != NULL;
}

int main(void)
{
char Yes_No[16] = {0};
char Filename[FILENAME_MAX] = {0};

printf("Do you wish to write an output file (y/n"? ");
fflush(stdout);
if(fgets(Yes_No, sizeof Yes_No, stdin) != NULL)
{
printf("Please input the desired name of your file: ");
fflush(stdout);
if(fgets(Filename, sizeof Filename, stdin) != NULL)
{
if(chomp(Filename))
{
/* Now:
open your file
if it opened okay
write stuff
check that it wrote okay
close it
*/
}
else
{
fprintf(stderr, "Filename too long.\n");
}
}
else
{
fprintf(stderr, "Couldn't read filename.\n");
}
}
else
{
fprintf(stderr, "Couldn't read your answer.\n");
}
return 0;
}
 
E

Eric Sosman

Hello,
I am having a problem in Microsoft Visual C++ with some code I have
written (I am a bit of a novice so I appologize if this is a very
mundane problem).
This is a segment from one of the functions I am using. I am trying
to get a user to input whether they want an output file or not and if
they do to specify the name. Output_File is a global char.
Maybe there is a better way to do this, nonetheless, it compiles with
a LNK4075 warning.
When I run the code, however, it allows me to enter the if statement
and type my preference. Then it doesn't even advance to the next
print statement (in or outside of the if), it quits with the message:

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

Your code contains at least five errors, possibly
more having to do with the portions you haven't shown.

1: NEVER USE gets()! NEVER, NEVER, NEVER!!! For
some of the reasons, see Question 12.23 in the
comp.lang.c Frequently Asked Questions (FAQ) at
http://www.c-faq.com/. (This is probably the
cause of your linker warning.)

2: A string with N "payload" characters requires
space for N+1 characters altogether, because a
zero byte '\0' follows the last payload character.
Your Yes_No array is one character long, so it
has enough room for N==0 payload characters.

3: The == operator is not the way to compare strings
for equality of their payloads. See Question 8.2
in the FAQ.

4: The way you are using scanf() is vulnerable to the
same problem as the NEVER-to-be-used gets(). See
Question 12.20 in the FAQ.

5: If Output_File is as you say a char, then it is
too small to hold a file name; see error #2. If
it is an array of char, the & operator shouldn't
be there; see Question 6.12 in the FAQ. And if
it's a char* pointer, the & operator still doesn't
belong; see the entire Section 6 of the FAQ. One
way or another, your use of Output_File is wrong.

You say you're a novice, and there's nothing shameful
about that: Comparatively few people pop out of the womb
already knowing C. But it seems to me that you are not
just "a bit of a novice" but a "rank beginner," and you
need to spend a good deal more time with a C textbook
before you go much further. Your misunderstandings are
so fundamental at the moment that Usenet is a poor vehicle
for correcting them. It's a good medium for communicating
fine points, for airing opinions, and for invective and
flame wars, but it's not a channel that's suited to mass
transfer of basic information. Hit the books!
 
R

Richard Heathfield

Typo corrections. See below.

Richard Heathfield said:
(e-mail address removed) said:

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

Never use gets. Never use %s in scanf. Never compare strings with ==.
Never use a single-character array to store a non-empty string.

#include <stdio.h>
#include <string.h>

int chomp(char *s)
{
char *p = strchr(s, '\n');
if(p != NULL)
{
*p = '\0';
}
return p != NULL;
}

int main(void)
{
char Yes_No[16] = {0};
char Filename[FILENAME_MAX] = {0};

printf("Do you wish to write an output file (y/n"? ");

Spurious " there. Should read:

printf("Do you wish to write an output file (y/n)? ");
fflush(stdout);
if(fgets(Yes_No, sizeof Yes_No, stdin) != NULL)

Sheesh. I forgot to check that the answer was yes.

Replace that line with:

if(fgets(Yes_No, sizeof Yes_No, stdin) != NULL && Yes_No[0] == 'y')
 
K

Kenneth Brody

Hello,
I am having a problem in Microsoft Visual C++ with some code I have [...]
Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

You would have to ask in a Microsoft-specific group about the
exact meaning of that asssertion error.

[OT response, using magical knowledge]

The error means _tfsopen() was passed a filename of "".
Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

I find it unlikely that this is the code where the failure takes
place, given that I don't see any file opens here, though it is
possible. (That's where an MS-specific group comes in handy.)

However, getting back to non-platform-specific things, what happens
if the user enters more than zero characters at the "gets(Yes_No)"
call, given the definition of "char Yes_No[1]"?

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
K

kudruu

Thank you very much for your input. I changed the compare convention
to use string compare as the extra clock cycles will not matter in
this instance. However, I found that my problem actually stemmed from
passing a global variable around do different functions. Instead, I
set a file write variable as a boolean and passed it around to my
functions. The file string name is then used in two separate
functions.
Sorry for not specifying my file string name to begin with, it was an
array of 80 characters (long enough for a file name). The part of the
code that contains the scanf functions is part of a function
containing a case statement where I listen for event messages over a
com port and must write each separate one to a file (previously I had
not put in a file write option).
Apologies all around to the C community for using gets.
Thanks for all the help!
 
B

Barry Schwarz

Hello,
I am having a problem in Microsoft Visual C++ with some code I have
written (I am a bit of a novice so I appologize if this is a very
mundane problem).
This is a segment from one of the functions I am using. I am trying
to get a user to input whether they want an output file or not and if
they do to specify the name. Output_File is a global char.
Maybe there is a better way to do this, nonetheless, it compiles with
a LNK4075 warning.
When I run the code, however, it allows me to enter the if statement
and type my preference. Then it doesn't even advance to the next
print statement (in or outside of the if), it quits with the message:

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){

At this point, your code invokes undefined behavior. Unless the user
does nothing but press the enter key, the input will involve at least
two characters. Your array has room for only one. You overflow your
buffer. Your solution to this problem should involve using a function
other than gets.

After you solve that problem, look in your reference book for how to
compare strings. The == operator is not what you want.
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);

You didn't show the definition of Output_File but 99+% of the time
this is wrong. What type of argument must the %s conversion
correspond to? What type is your argument?


Remove del for email
 
E

Eric Sosman

Richard Tobin wrote On 06/18/07 12:10,:
Hardly ever.

It is sometimes useful to "intern" strings, that is, ensure that there
is always only one string with a given value in a given set. The main
reason for doing this is exactly so that you can compare them with ==.

I once had a program that went usefully faster after "strcmp(a,b) == 0"
was replaced with "a == b || strcmp(a, b) == 0", because there was a very
high chance that equal strings would have come from the same source and
thus be equal as pointers.

Quite by chance, I discovered that at least one strcmp()
implementation makes this test internally, and returns zero
immediately if its arguments are equal. I conjecture that
the equal-arguments case "fell out" of code to detect whether
the argument alignments would permit comparing four or even
eight bytes at a time.
 
B

Barry Schwarz

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

So I did a little bit of tweaking and now it reads:
printf("Do you wish to write an output file (y/n)? ");
scanf("%s",&Yes_No);

This invokes undefined behavior in multiple flavors.
printf("Got Here\n");
if (Yes_No[0] == 'y'){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);

This probably invokes undefined behavior. We will know for sure when
you show us the definition of Output_File.
}

This works only for the case of y, however I still get the error on n
(and any other letter). After this function, there are several other
functions that must be called using Output_File, is it possible to set
a character array to Null or False?


Remove del for email
 
R

Richard Heathfield

(e-mail address removed) said:
Thank you very much for your input. I changed the compare convention
to use string compare as the extra clock cycles will not matter in
this instance.

You mean, on *this* occasion it's okay to spend the extra time doing it
right, but maybe next time it'd be better to do it wrong, for the sake
of a faster program?

If that /is/ what you mean, I offer you the following program, which
will get you the wrong results very very quickly indeed:

int main(void) { return 0; }
However, I found that my problem actually stemmed from
passing a global variable around do different functions.

No, one of your problems may have stemmed from that, but you had more
than one problem.
 
R

Richard Heathfield

Barry Schwarz said:

You didn't show the definition of Output_File but 99+% of the time
this is wrong.

How would you define Output_File in such a way as to make it right?
 
K

Keith Thompson

Richard Heathfield said:
Barry Schwarz said:


How would you define Output_File in such a way as to make it right?

char s[BIG_ENOUGH];
#define Output_File s[0]

Which is deliberately silly, as well as ignoring the inherent problems
scanf's "%s" format.

On the other hand, 100% is consistent with 99+%.
 
E

Eric Sosman

Richard Heathfield wrote On 06/18/07 17:11,:
Barry Schwarz said:




How would you define Output_File in such a way as to make it right?

char Output_File_Buffer[9999];
#define Output_File Output_File_Buffer[0]

(So when I wrote earlier that the usage was guaranteed
to be wrong, I was, er, wrong.)
 
R

Richard Heathfield

Keith Thompson said:
Richard Heathfield said:
How would you define Output_File in such a way as to make it right?

char s[BIG_ENOUGH];
#define Output_File s[0]

Ah, I see. Clearly, I have an insufficiently twisted imagination. :)
 
B

Barry Schwarz

Barry Schwarz said:



How would you define Output_File in such a way as to make it right?

I always try to allow for the fact that my imagination may be too
limited to come up with some code to make it correct. I refer you to
the 2006 thread "counting with char" where many thought you could not
have a "neat and tidy" loop using an int index that went from INT_MIN
to INT_MAX until Malcolm showed how easy it was in a message dated 7
May.


Remove del for email
 
C

CBFalconer

I am having a problem in Microsoft Visual C++ with some code I have
written (I am a bit of a novice so I appologize if this is a very
mundane problem).
This is a segment from one of the functions I am using. I am trying
to get a user to input whether they want an output file or not and if
they do to specify the name. Output_File is a global char.
Maybe there is a better way to do this, nonetheless, it compiles with
a LNK4075 warning.
When I run the code, however, it allows me to enter the if statement
and type my preference. Then it doesn't even advance to the next
print statement (in or outside of the if), it quits with the message:

Code:
Debug Assertion Failed!
File: fopen.c
Line: 55

Expression: *file != _T("\0')

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

To start with, NEVER use gets. You can use fgets, or ggets (the
latter is available at <http://cbfalconer.home.att.net/download/>)
or getc (which returns an int). In addition Yes_No is a char array
with room for exactly one char, which has to be a '\0' to form a
string. That should get you started.

Visual C has nothing to do with it, and 'LNK4075' is totally
meaningless. Publish complete compilable code samples, not
extractions. To make the output visible on all systems use
fflush(stdout) or end the string with a '\n'.
 
A

Army1987

Richard Heathfield said:
Typo corrections. See below.

Richard Heathfield said:
(e-mail address removed) said:

Here is the problem code:
char Yes_No[1];

printf("Do you wish to write an output file (y/n)? ");
if (gets(Yes_No) == "y"){
printf("\nPlease input the desired name of your file: ");
scanf("%s",&Output_File);
}

Never use gets. Never use %s in scanf. Never compare strings with ==.
Never use a single-character array to store a non-empty string.

#include <stdio.h>
#include <string.h>

int chomp(char *s)
{
char *p = strchr(s, '\n');
if(p != NULL)
{
*p = '\0';
}
return p != NULL;
}

int main(void)
{
char Yes_No[16] = {0};
char Filename[FILENAME_MAX] = {0};

printf("Do you wish to write an output file (y/n"? ");

Spurious " there. Should read:

printf("Do you wish to write an output file (y/n)? ");
fflush(stdout);
if(fgets(Yes_No, sizeof Yes_No, stdin) != NULL)

Sheesh. I forgot to check that the answer was yes.

Replace that line with:

if(fgets(Yes_No, sizeof Yes_No, stdin) != NULL && Yes_No[0] == 'y')

Is it necessary? I'd just use:
int answer;
int ch;

and then:
answer = getchar();
do {
ch = getchar();
} while (ch != '\n' && ch != EOF);
if (answer == 'y' || answer == 'Y') {
...
}

How does storing 15 character of the answer help?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,044
Latest member
RonaldNen

Latest Threads

Top