I am trying to to record response by the user(using getchar()). I am having issues with '\n' sticking in buffer. If I use fgets(char* buf, .. , ..), '\n' again goes into buf and you have to include '\n' at the end of the test string. when using string.h functions (like strcmp()). Is there any clean way of writing code for such purposes.
#include<stdio.h>
#include<string.h>
int main()
{
char buf[100];
fgets(buf, 3, stdin);
puts(buf);
int i = strcmp("p\n", buf);
printf("%d", i);
//if (!strcmp("CLock to random\n", buf))
//{
//puts("sucess");
//}
char c;
c = getchar();
putchar(c);
return 0;
}
Now I want to record response(single character 'p'). If I use getchar(), in place of fgets(), program skips second getchar()( c = '\n'). If I use the current code, i have to include \n in strcmp() every time.
If you want to discard the \n:
char buf[0x1000];
fgets(buf, sizeof(buf), stdin);
char *p = strchr(buf, '\n');
if (p) *p = 0;
#include <stdio.h>
#include <string.h>
char* chomp(char* str){
size_t len = strlen(str);
if(len>0 && str[len-1] == '\n')
str[len-1] = '\0';
return str;
}
int main(void){
char buf[128];
fgets(buf, sizeof(buf), stdin);
printf("<%s>\n", buf); //include newline
printf("<%s>\n", chomp(buf));//drop tail newline
printf("<%s>\n", chomp(buf));//NC
return 0;
}
Related
I have two inputs using fgets() function. Obviously, I declare size of input hoping it will truncate the input. It does truncate the input, but the remaining characters overflow into the following fgets(). I thought flushing the stdin would be the fix, but it doesn't seem to be working. Any help? Example below.
char a[3];
char b[3];
fgets(a, sizeof(a), stdin);
fflush(stdin);
fgets(b, sizeof(b), stdin);
fprintf(stderr, "%s%s", a, b);
an input of "help" followed by "ok" would produce the following:
hel
pok
strchr could be used to look for a newline. If found, set the newline to zero to terminate the string. Call fgets to fill the remainder of the array. The loops continue until both arrays are filled.
The array with size [4] can store three characters and a terminating zero.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void) {
char a[4];
char b[4];
char *newline = NULL;
size_t len = 0;
fgets(a, sizeof(a), stdin);
while ( ( newline = strchr ( a, '\n'))) {//find a newline
*newline = 0;//set terminating zero
len = strlen ( a);
if ( len < sizeof a - 1) {//space available in array
fgets ( newline, sizeof a - len, stdin);//more input into array
}
else {
break;
}
}
fgets(b, sizeof(b), stdin);
while ( ( newline = strchr ( b, '\n'))) {//find a newline
*newline = 0;//set terminating zero
len = strlen ( b);
if ( len < sizeof b - 1) {//space available in array
fgets ( newline, sizeof b - len, stdin);//more input into array
}
else {
break;
}
}
fprintf(stderr, "%s%s\n", a, b);
return 0;
}
getchar could be used to clear the input stream if the first array does not contain a newline.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main ( void) {
char a[4];
char b[4];
fgets(a, sizeof(a), stdin);
if ( ! strchr ( a, '\n')) {//no newline
while ( '\n' != getchar ( )) {//clear the input stream
if ( EOF == getchar ( )) {
fprintf ( stderr, "problem EOF\n");
return 1;
}
}
}
fgets(b, sizeof(b), stdin);
fprintf(stderr, "%s%s\n", a, b);
return 0;
}
how to flush stdin
Do NOT use: fflush( stdin )
The function: fflush() is ONLY for output streams and the C programming language specifically states that calling fflush() with an input stream results in undefined behavior. (regardless of what visual studio might allow)
Suggest:
int ch;
while( (ch = getchar() ) != EOF && ch != '\n' ){;}
regarding the function: fgets()
That function always appends a NUL byte to the input and always stops 1 short of the length it is given, so there will be room for the NUL byte
regarding:
char a[3];
char b[3];
fgets(a, sizeof(a), stdin);
fflush(stdin);
fgets(b, sizeof(b), stdin);
fprintf(stderr, "%s%s", a, b)
replace:
fflush(stdin);
with:
int ch;
while( ( ch = getchar() ) != EOF && ch != '\n' ){;}
Suppose, I have a file with the following contents
abcdefghijkl
mnopqrstuvwx
yz1234567890
and I only want to read the first 5 characters from each line so the it can be like the following:
abcde
mnopq
yz123
I tried the following solution,
char line[5];
for (int i = 0; i < 5; i++){
char c = getchar();
line[i] = c;
printf("%c", line[i]);
}
but it does not work. How can I solve this?
Here is a demonstrative program. For simplicity instead of an external file there is used the standard input stream stdin.
#include <stdio.h>
#include <string.h>
int main(void)
{
char line[6];
while ( fgets( line, sizeof( line ), stdin ) != NULL )
{
char *p = strchr( line, '\n' );
if ( !p ) fscanf( stdin, "%*[^\n]\n" );
else *p = '\0';
puts( line );
}
return 0;
}
If to enter
abcdefghijkl
xyz
mnopqrstuvwx
yz1234567890
then the output will be
abcde
xyz
mnopq
yz123
The code you posted will read 5 bytes from stdin and print them. This code should work.
The problem with your code is probably that you are not discarding the remaining characters on the line before reading the next line with the same loop. Since you did not post the code which is calling the loop, I have no way of knowing.
Simple function https://godbolt.org/z/2UP4JW
#include <stdio.h>
#include <stdint.h>
char *read5chars(char *buff, FILE *fp)
{
int ch;
char *ret;
ret = fgets(buff, 6, fp);
do
{
ch = fgetc(fp);
}while(ch != '\n' && ch != EOF);
return ret;
}
int main()
{
char line[6];
while(read5chars(line, stdin))
printf("%s\n", line);
}
I have to split a string-input value where-ever there is a blankspace and output the result.
eg: input:
I am a noob at C
output:
>>I
>>am
>>a
>>noob
>>at
>>C
Code:
void splitText(){
char str[100];
char sep[] = " \r\n";
char *res; //if i remove this
fgets(str,sizeof str,stdin);
if (fgets(str, sizeof str, stdin) == NULL) {
printf("error");
}
char *p = strchr(str, '\n');
if (p) *p = 0;
res = strtok(str, sep); //and this
printf("%s\n",res); //and change this to str
}
Working code for anyone encountering the same problem:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void splitText() {
char str[100];
char sep[] = " \n";
char *res;
fgets(str,sizeof str, stdin);
if ( fgets(str, sizeof str, stdin) == NULL ) {
printf("Error");
break;
}
res = strtok(str, sep);
while(res != NULL){
printf("Splitted String: \"%s\"\n",res);
res = strtok(NULL,sep);
}
}
Thanks to everyone who contributed in helping me with this issue!
The problem with
char str[100] = scanf("%s",str);
is that you are assigning an int to a char array.
scanf() returns the number of items successfully scanned. The actual reading of chars into the array is done by scanf() itself. So you just need to call scanf() separately.
if (scanf("%s",str) != 1) { /* error */}
But scanf() is not the right tool here since you want to read a whole line. scanf() would stop at the first whitespace (after reading non-whitespace chars).
So when you type "I am a noob at C", scanf() will only read the I and ignore the rest.
What you want is to use the fgets() function to read a line:
char str[100];
if (fgets(str, sizeof str, stdin) == NULL) {
/* error */
}
/* rest of the code */
fgets() would read the newline as well if there's space in the buffer. If this is undesirable, then you can remove it:
char *p = strchr(str, '\n');
if (p) *p = 0; //remove the trailing newline.
Note: strtok() is not a thread safe function. POSIX provides strtok_r() as a thread-safe alternative. This is something to be aware of even if it doesn't matter in this specific case.
Here's a self contained example:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
char str[100];
char sep[] = " \n";
char *res;
if ( fgets(str, sizeof str, stdin) == NULL ) {
exit(1);
}
res = strtok(str, sep);
while(res != NULL){
printf("Splitted String: \"%s\"\n",res);
res = strtok(NULL,sep);
}
return 0;
}
That is not how scanf() works.
Change the code to
char str[100];
scanf("%s",str);
A little note about scanf()
You should check for return values, like here for scanf().
if (scanf("%s", str) != 1)
{
printf("scanf failed");
exit(0);
}
You should also mention the number of chars to be read by scanf() to avoid buffer overflow.
scanf("%99s", str)
For a char str[100] of size 100, one should give 99 to keep place for the null character \0.
i wanna print string to each word in each line .it looks like putc not working and why i can not use putchar in c programming language ?
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main() {
char s[50];
int i, len;
printf("\enter string : ");
gets(s);
len = strlen(s);
i = 0;
while (i<len) {
while (s[i] == ' ' && i<len)
i++;
while (s[i] != ' ' && i<len)
putc(s[i++], stdout);
putc('\n', stdout);
}
getch();
}
There's nothing massively wrong with your code, other than:
the use of non-standard features like conio.h and getch;
the use of unsafe functions (which tend not to matter in classwork that much);
the wrong order for conditions in your while statements, which may cause undefined behaviour.
Hence, this code appears to do what you need:
#include <stdio.h>
#include <string.h>
int main (void) {
char s[50];
int i, len;
printf("enter string : ");
gets(s);
len = strlen(s);
i = 0;
while (i<len) {
while (i < len && s[i] == ' ')
i++;
while (i < len && s[i] != ' ')
putc(s[i++], stdout);
putc('\n', stdout);
}
return 0;
}
However, it's not that clean, a professional coder would tend to opt for more modularisation and worthwhile comments, something along the lines of the following. First, some general functions for skipping spaces and echoing words:
#include <stdio.h>
#include <string.h>
static char *skipSpaces (char *pStr) {
// Just throw away spaces, returning address of first non-space.
while (*pStr == ' ')
pStr++;
return pStr;
}
static char *echoWord (char *pStr) {
// If at end of string, say so.
if (*pStr == '\0')
return NULL;
// Echo the word itself.
while ((*pStr != '\0') && (*pStr != ' '))
putchar (*pStr++);
// Then skip to start of next word (or end of string).
pStr = skipSpaces (pStr);
// Return new pointer.
return pStr;
}
Then, with that done, the main program becomes a lot easier to understand:
int main (void) {
// Get string from user in a more safe manner.
char str[50];
printf("Enter string: ");
fgets (str, sizeof (str), stdin);
// Remove newline if there.
size_t len = strlen (str);
if ((len > 0) && (str[len-1] == '\n'))
str[len-1] = '\0';
// Start with first real character.
char *pStr = skipSpaces (str);
// Process words and space groups (adding newline) until at end of string.
while ((pStr = echoWord (pStr)) != NULL)
putchar ('\n');
return 0;
}
#include<stdio.h>
#include<string.h>
int main()
{
char buffer[32];
char c;
int i;
printf("input: ");
fgets(buffer, 32, stdin);
printf("items filled: %d\n", sscanf("%c%d\n", &c, &i));
printf("%c%d\n", c, i);
return 0;
}
When typing a character followed by a number "f7", im expecting "f" to go into variable c, and "7" to go into variable i. For some reason, sscanf() fails to fill both, and I'm getting their initial garbage values. What am I doing wrong?
Actual sscanf() signature is this :
int sscanf(const char *str, const char *format, ...);
check your signature of sscanf() you have used wrong signature
It should be
sscanf(buffer,"%c%d\n", &c, &i);
You're not using buffer in the sscanf() call, so they're not getting filled.
int i;
char c;
char buffer[32];
fgets(buffer, 32, stdin);
sscanf(buffer, "%c%d", &c, &i)
^
you're missing this part
Do not use sscanf. The correct way to do the parsing you are trying to do is
#include <stdlib.h>
#include <stdio.h>
// ...
char *endptr, buffer[32];
char c;
int i;
// ...
fgets(buffer, 32, stdin);
c = buffer[0];
i = strtol(buffer+1, &endptr, 10);
if (endptr == buffer+1 || (*endptr != '\0' && *endptr != '\n')) {
puts("invalid input");
return 1;
} else {
printf("%c%d\n", c, i);
return 0;
}
sscanf("%c%d\n", &c, &i) is never told to look in the buffer for c and i, it looks like you are making this call incorrectly.