I am writing a basic C program which takes a word from the user as input and prints that word twice on the same row. The issue that I am facing in printing the word twice is mentioned after the code that I have written below to do this job
void print_word()
{
char ch;
char str[15];
int i = 0; /* i will be used as index to access the elements of str */
printf ("\n Enter a word of your choice : ") ;
ch = getch() ; /* Dont echo character */
while ( !isspace(ch) && i < 14) /* while loop executes till user doesn't input a space or until the str array is full */
/* isspace() is defined in header file <ctype.h> */
{
putchar(ch); /* Now echo character */
str[i] = ch ;
i++ ;
ch = getch();
} //while loop ends
str[i] = '\0' ;
printf("\t") ; //print a gap
printf ("%s ", str) ;
printf ("%s", str) ;
}
This function works properly if user directly enters a word (without using backspace to edit the word).
Suppose user enters 'HELLO' then 5 characters viz.'H' 'E' 'L' 'L' 'O' gets stored in array str. But then user presses backspace three times and the word on the console appears 'HE' while str now contains eight characters H-E-L-L-O and 3 backspace characters. But when the printf function in the last two statements of this code is executed and prints str, the first statement correctly prints the 8 character and displays 'HE' on the console, but second statement prints 'HELLO', leaving the 3 backspace characters that are also there in the array str.
Why the last printf() statement is not printing the string str properly i.e., why is it not printing the backspace characters?
The problem remains even if I print str with puts() function or even if the str is printed with a for loop -- character by character. And I want to know what is actually happening in the backend process?
Use printf("%s\n", str); both times and you'll see that the first printf does not print 'HE'. It prints 'HELLO' just like the second one, just after that it moves the cursor back 3 times, so if you print both strings on the same line then the second string overwrites the last 3 characters of the first 'HELLO'. After printing HELLO and 3 backspaces you have output HELLO and cursor at the mark:
HELLO
^
After printing the space you have:
HE LO
^
After printing another HELLO and 3 backspaces:
HE HELLO
^
You might want to check this question if you want more information about printing strings with a backspace: Function printf() to print backspace problem.
As an alternative to printf("%s\n",str); solution you could process char by char your user's input.
Usually getch() is used whenever the programs require a full control of the input characters, so take advantage of it.
In your while loop just do this, instead:
while ( !isspace(ch) && i < 14)
{
putchar(ch); /* Now echo character */
if( ch == 0x08 && i > 0)
{
i--;
}
else
{
str[i] = ch ;
i++ ;
}
ch = getch();
}
Basically you need to check if the current input character is a backspace (ASCII value 0x08). If it is, decrease the current index of the input array in order to perform the character deletion. Of course don't do it if the current index is 0.
This approach is common in applications such as AT parsers.
This function works properly if user directly enters a word (without using backspace to edit the word).
See this,
#include<stdio.h>
#include<conio.h>
void print_word()
{
char ch;
char str[15];
int i = 0,flag=0;
printf ("\n Enter a word of your choice : ") ;
for(i=0; i<15&&flag==0; ++i)
{
ch = getch();
switch(ch)
{
case 13:
str[i] = '\0';
flag=1;
break;
case '\b':
if(i>0) i--;
str[i--]='\0';
printf("\b \b");
break;
default:
str[i] = ch;
printf("%c",ch);
}
}
str[15]='\0';
printf("\t") ;
printf ("%s ", str) ;
printf ("%s", str) ;
}
int main()
{
print_word();
}
You are responsible for removing backspace from str.
Why the last printf() statement is not printing the string str properly i.e., why is it not printing the backspace characters??
your input: HELLO+(3 backspace)
so the str contains {'H','E','L','L','O','\b','\b','\b'}
and the intersection point in console is
"HE^LLO"
After one tab (nearly 7 spaces), so console appears
"HE "
after one print of str
"HE HE^LLO"
after print of space and str
"HE HE HELLO"
Related
This question already has an answer here:
fgets is getting skipped
(1 answer)
Closed 4 years ago.
Been trying to remove a character but the call to fgets gets skipped/jumped over. On different computers it runs like it should but for some reason, it skips and basically jumps to the end of the program. Any ideas?
Several problems in your code but I do not see any reason of fgets() skipped or jumped over. The getchar() function reads the next character from stdin. Generally when we give input to the getchar() function, we enter the character and press ENTER key. This left the \n character in input stream which can be consumed by next input function called. But in your case you are not calling any other input function after getchar().
[Try calling getchar() above fgets() and give input as - enter a character followed by ENTER key. You will see the fgets() is skipped because it consumes the leftover \n character from input stream stdin.]
Problem 1:
Look at this statement:
str[j] = str + 1;
Since, the str is a char array, str[j] represents a character at location j and str + 1 is pointer. So, this assignment is incompatible because you are trying to assign a char * type to a char. It should be:
str[j] = str[j + 1];
Problem 2:
Your code is having a logical problem. It is unable to handle the scenario where the character to be removed occurs consecutively in the input string. Test your code for input like "Hello World" [character l is occurring consecutively]. Your program output will be [after fixing problem 1]:
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Helo Word <==== character l not removed
Your program is unable to handle this particular scenario because once it removes a character, in the next iteration it starts with next character.
Problem 3:
The strlen() return type is size_t and you are using char type to receive its return value. Instead, you should use size_t type.
The getchar() return type is int [because it returns the special value EOF when the end of the input stream is reached]. You are using char type variable to receive getchar() return value.
One more point (it is not a problem but you should be aware of it and take the precautionary measures):
From fgets() [emphasis mine]:
Reads at most count - 1 characters from the given file stream and stores them in the character array pointed to by str. Parsing stops if end-of-file occurs or a newline character is found, in which case str will contain that newline character. If no errors occur, writes a null character at the position immediately after the last character written to str.
So, it is possible that your input buffer passed to fgets() can have new line character ('\n') in it. For e.g., if you give input Hello World followed by ENTER key than the input buffer str will have "Hello World\n" in it. In your case this will not cause any problem but few extra iteration of loop. You can remove the \n from str buffer like this:
fgets(str, 100, stdin);
str[strcspn(str, "\n")] = 0; // This will remove the trailing newline character from input buffer
Also, you should check the fgets() return. In case of failure, fgets() returns NULL.
Putting these altogether, you can do:
#include <stdio.h>
#include <string.h>
int main() {
char str[100];
size_t i, j, len;
int r;
printf("Enter a sentence: \n");
if (fgets(str, 100, stdin) == NULL) {
fprintf (stderr, ("fgets failed"));
return -1;
}
str[strcspn(str, "\n")] = 0;
printf("This is the sentence: %s\n", str);
printf("Enter character to remove: \n");
r = getchar();
/*If getchar returns EOF, no need to go through character removal logic*/
if (r != EOF) {
len = strlen(str);
i = 0;
while (str[i] != '\0') {
if (str[i] == (char)r) {
for (j = i; j < len; j++) {
str[j] = str[j+1];
}
len--;
}
else
i++;
}
}
printf("Sentence after removal: %s\n", str);
return 0;
}
Output:
# ./a.out
Enter a sentence:
Hello World
This is the sentence: Hello World
Enter character to remove:
l
Sentence after removal: Heo Word
# ./a.out
Enter a sentence:
zzzzz
This is the sentence: zzzzz
Enter character to remove:
z
Sentence after removal:
# ./a.out
Enter a sentence:
aazz
This is the sentence: aazz
Enter character to remove:
a
Sentence after removal: zz
Try changing r = getchar(); with scanf("%c\n", &r);.
Also, your loop has some bugs or inconsistencies:
You're assigning to str[j] the value of a pointer. Should be assigning to str[j] the value of str[j+1].
The end of the inner loop should be len-1 then.
j-- has no effect at all.
You should end your string with \0 after you're done, otherwise you'll print garbage (in my case it was a bunch of \ns).
Putting everything together:
for (i = 0; i < len; i++) {
if (str[i] == r) {
for (j = i; j < len-1; j++) {
str[j] = str[j+1];
}
len--;
}
}
str[len] = '\0';
printf("Sentence after removal: %s\n", str);
If you want to remove the \n at the end of the string after you read it, you can do
str[len] = '\0';
len--;
before the loop.
#include "stdio.h"
int main() {
char input[10];
char standart;
int i;
int b = 0;
scanf("%c", &standart);
for(i = 0; i < 10; i++){
scanf("%c ", &input[i]);
if(input[i] == standart){
b++;
}
}
printf("%d", b);
return 0;
}
// ( 2 % a b ( r ) ? ( (
The code is suppost to read the first character in the list, then see how many of said characters there are (not including itself). But the code doesn't read the last character, in short when I input the sample input the code only sees 2 '(' while it should see 3.
You have to do it like this scanf(" %c",&c);
Because it reads '\n' from previous input, so the space will skip the '\n'
For the given input ( 2 % a b ( r ) ? ( (, the program takes the first character ( as input to variable standart -
scanf("%c", &standart);
The problem is occurring because in the first iteration of for loop the scanf was reading the first whitespace character (a blank space) from given input that exists after ( and storing it into input[0].
The for loop runs for 10 iterations and the last character ( is not inserted in the input array because of which the standart character count in input array is coming one less than expected i.e. 2.
Change the for loop scanf statement to -
scanf(" %c", &input[i]); //Removed the space after %c and added a space before %c.
With this, the for loop scanf will eat whitespaces characters.
So, the next character from input - 2 will be stored to input[0] and % will be stored to input[1] and so on and the last character '(' will be stored to input[9].
And the b will have the correct standart character count in input array i.e. 3.
I'm trying to write a program that deletes the last newline from user input, ie the one generated when the user hits enter after having typed in a string.
void func4()
{
char *string = malloc(sizeof(*string)*256); //Declare size of the string
printf("please enter a long string: ");
fgets(string, 256, stdin); //Get user input for string (Sahand)
printf("You entered: %s", string); //Prints the string
for(int i=0; i<256; i++) //In this loop I attempt to remove the newline generated when clicking enter
//when inputting the string earlier.
{
if((string[i] = '\n')) //If the current element is a newline character.
{
printf("Entered if statement. string[i] = %c and i = %d\n",string[i], i);
string[i] = 0;
break;
}
}
printf("%c",string[0]); //Printing to see what we have as the first position. This generates no output...
for(int i=0;i<sizeof(string);i++) //Printing the whole string. This generates the whole string except the first char...
{
printf("%c",string[i]);
}
printf("The string without newline character: %s", string); //And this generates nothing!
}
But it doesn't behave as I thought it would. Here's the output:
please enter a long string: Sahand
You entered: Sahand
Entered if statement. string[i] =
and i = 0
ahand
The string without newline character:
Program ended with exit code: 0
Questions:
Why does the program seem to match the '\n' with the first character 'S'?
Why does the last line printf("The string without newline character: %s", string); generate no output at all when I haven't deleted anything from the string?
How can I make this program do what I intend it to do?
The condition (string[i] = '\n') will always return true. It should be (string[i] == '\n').
if((string[i] = '\n'))
this line may be wrong, you are assign value to string[i], not compare it.
if((string[i] == '\n'))
How can I scanf() the integer values I enter into an array until I hit enter.
I believe I can use getchar() != '\n'.
but how do I loop through the line ?
Suppose my input is 20 21 2 12 2. I want an array that has all those inputs.
What given functions could I use in order to scan them all in.
You are trying to read integers as characters so once read you need to convert it to integers.
Read the line to a buffer using fgets() then parse the input buffer to get integers.
Store the integers to the array.
The code looks like
char buf[300];
int a[5],i=0;
fgets(buf,sizeof(buf),stdin);
char *p = strtok(buf," ");
while(p != NULL)
{
char *endptr;
a[i] = strtol(p,&endptr,10);
if ((*endptr != '\0') && (isspace(*endptr) == 0))
printf("warning: invalid value detected\n");
else
i++;
p = strtok(NULL," ");
}
You can use the alternative strtol() instead of atoi() to convert string to integer.
PS: Your buf should be large enough to hold the whole line. fgets() read till newline character.
If you use getchar() you obtain digits one by one, so you need
to store them first in the buffer, and when white space comes,
you convert those digits into a number, and store it into array.
here is the explanation of the code I made for you.
1st if statement : if obtained character is a digit, store it in buf
2nd if statement : if obtained character is a white space or EOL and at least 1 digit is stored in buf, convert digits into number and store it in array a.
3rd if statement : if obtained character is not a digit or a white space or a EOL, warns users.
4th if statement : if obtained character is a EOL, end loop.
The code below works fine.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(){
#define BUFSIZE 50
#define ARRAYSIZE 5
int i,k,a[ARRAYSIZE];
char c,buf[BUFSIZE];
for(i=0,k=0;(i<BUFSIZE)&&(k<ARRAYSIZE);){
c=getchar();
if(isdigit(c)){
buf[i++] = c;
}else if((i>0) && (c==' ' || c=='\n')){
buf[i] = '\0';
a[k++] = atoi(buf);
i=0;
}else if(!(c==' ' || c=='\n')){
printf("warning : invalid value %c is detected\n",c);
i=0;
}
if(c=='\n'){
break;
}
}
printf("input :");
for(i=0;i<ARRAYSIZE;i++){
printf("%d, ",a[i]);
}
printf("\n");
}
I would like to know about the getchar() logic in the following codes...
printf("Type up to 25 characters and then press Enter. . . \n") ;
for (i = 0; i < 25; i++)
{
msg[ i] = getchar() ;
if (msg[ i] == ' \n' )
{
i--;
break;
}
}
putchar(' \n' ) ;
for (; i >= 0; i--)
{
putchar(msg[ i] ) ;
}
In the above code if i input a name,say "STACKEXCHANGE" and then hit enter it will display the word properly..but the below code works differently..
printf("What are your two initials?\n") ;
firstInit = getchar() ;
lastInit = getchar() ;
In this example, if i type "ST" and then hit enter, 'S' will be stored in firstinit, while "\n" will be stored in lastInit instead of 'T'.
How does this happen? Isn't 'T' the second character input into the buffer. Infact \n is the third character in the buffer. so why does \n get stored. correct me if iam wrong, but the buffer is released when \n is pressed or entered, then why is it again being stored in the next getchar() function.
Why is the first code executed differently then? I mean if i input "stackexchange" and hit enter "t" is stored as the second character as is wanted, but it in the second example if the same "st" is typed and "enter' is input, the "t" is not stored as the second input, but instead "enter' is taken as the second input.
I am sorry if my typing is confusing... basically i want to know the logical flow in both codes, how it happens behind the scene..
the only reason for storing \n is when you are entering S the pressing enter and not flushing out the carriage return so it will store \n in your second string.
firstInit = getchar() ;
will read and store S
lastInit = getchar() ;
will read and store carriage return
getchar() is a standard library function which will read a character from the console.
Check the below code which takes your input ST and stores it in 2 char's a and b.
int main(void){
char a;
char b;
a = getchar();
b= getchar();
printf("a = %c b = %c\n",a,b);
return 0;
}
Input
ST<enter>
Output
a = S b = T
If you are seeing a newline char being saved into b here then the input is like S<enter> not ST<enter>