Usually, I do the do { } while (0);
trick.
But, if you want a macro that is a drop in replacement for fgets
where you can test the return value transparently, how about:
#include <stdio.h>
#include <string.h>
#define FGETS(_buf,_len,_xf) \
({ \
char *_cp = fgets(_buf,_len,_xf); \
if (_cp != NULL) \
_buf[strcspn(_buf,"\n")] = 0; \
_cp; \
})
#define FGETOF(_buf,_xf) \
FGETS(_buf,sizeof(_buf),_xf)
int
main(void)
{
char buf[100];
while (1) {
if (FGETOF(buf,stdin) == NULL)
break;
printf("buf: '%s'\n",buf);
}
return 0;
}
The multiline macro is fine, but can be cleaned up [with no loss in speed] using an inline
function:
#include <stdio.h>
#include <string.h>
static inline char *
xfgets(char *buf,size_t siz,FILE *xf)
{
char *cp;
cp = fgets(buf,siz,xf);
if (cp != NULL)
buf[strcspn(buf,"\n")] = 0;
return cp;
}
#define FGETS(_buf,_len,_xf) \
xfgets(_buf,_len,_xf)
#define FGETOF(_buf,_xf) \
FGETS(_buf,sizeof(_buf),_xf)
int
main(void)
{
char buf[100];
while (1) {
if (FGETOF(buf,stdin) == NULL)
break;
printf("buf: '%s'\n",buf);
}
return 0;
}