SuperContraptionGuy SuperContraptionGuy - 4 months ago 17
C Question

Issues with Printf() and fgets()

I am working on creating a project that has a custom header file, and ran into some problems:

I'm not exactly sure what happened to this code, but after I started using the

fgets()
function, it seems to have stopped the output of some
printf()
's in my code. Here are the important parts of the code, probably missing some
#include
statements here:

main.cpp


#include "ichat.h"

int main() {

prompts(P_IDLE, response);
prompts(P_USERNAME, response);
}


ichat.cpp


#include "ichat.h"
int prompts(int p_tag, char *response) {

if (p_tag == P_IDLE) {

printf("\nWaiting for connections. Press [ENTER] to start a chat.");
char msg[50];
char *ptr;
while (true) {

fgets(msg, strlen(msg), stdin);
ptr = (char*)memchr(msg, '\n', strlen(msg));
if (ptr != NULL) {

break;
}

} else if (p_tag == P_USERNAME) {

printf("\nPlease enter a username you'd like to use: ");
....

} ...


some of
ichat.h
, incase you were curious...

#define P_IDLE 0
#define P_USERNAME 1


compiled with
gcc main.cpp ichat.cpp
.

The issue is that when adding in the while loop with the
fgets()
function, none of the
printf()
functions produce output in the command line. I'm not exactly sure what is happening here, because those print functions were working, and sometimes they work if I remove the
\n
, or if I add another
printf()
function right before them. It's pretty confusing...

Is there a better way to get input from the user? I'm open to any hints, critiques, and ideas about any part of my code.

Answer

The nub of your problem is

char msg[50];
 /* no initialisation of data in msg */
fgets(msg, strlen(msg), stdin);

msg is uninitialised, so the values of any of the characters in it are indeterminate - they are not guaranteed to be zero. Formally, even accessing their values (which strlen() does to search for a '\0') gives undefined behaviour.

What you need to do is change strlen(msg) to sizeof msg (which will consistently give the value of 50).

fgets() will modify msg based on input. Then you can use strlen() on the result.

Also: try not to use (char *) type conversions on the result of functions like memchr() that return void *. It is only needed in C if you have forgotten to #include <string.h>. Including the right header is the better solution than the type conversion. If your C compiler is actually a C++ compiler, the conversion will be needed, but C++ provides alternative approaches that are often preferable (more type safe, etc).