After spending more than few days on debugging, I can't find the reason why my code below creates additional spaces when printing out the error check ("expecting or missing"). For example, when I run each of these line of symbols one at a time in order.
The first two works fine, but the third line of input will error check at the wrong position. But the symbol that its expecting is correct (<). When I remove the call to the reset function in the bottom of my code, the error check of the third line of input will be at the correct position but the symbol that its expecting is incorrect: { . Most likely because the stack hasn't reseted from the previous line of inputs.
I made print statements on the values of the increments for printing spaces and the size of the char array itself, but the numbers are correct. The culprit might be the reset function I made, but the character resets fine. Only problem is that the output is creating additional spaces when printing out the error check, which leads to displaying the error check at the wrong position.
You need to reset check1 and check2 to false within your while loop. Other wise when running the third case after the second it includes extra white space resulting in the wrong offset.
Related
What is the correct way to scan unknown number of set of characters? let me explain , i want to scan with form "char:integer" e.g a:5
What is the right way
while(scanf(" %c%c%d",&a,&b,&c) != EOF){...}
or
while(scanf(" %c%c%d",&a,&b,&c) ==3){...}
the second pattern is tricky bcs sometimes it works and sometimes it does not.
also why does in first pattern using windows require ctr+Z (eof) to press twice?
the second pattern is tricky bcs sometimes it works and sometimes it does not.
That's because
while(scanf(" %c%c%d",&a,&b,&c) == 3){...}
will run only when all the three variables got assigned properly without any early matching failure or end of file.
Whereas
while(scanf(" %c%c%d",&a,&b,&c) != EOF){...}
will run even if few (<3) variables got assigned unless there's an end of file. That means this definition will work even in the case of matching failure which is undesirable.
So use while(scanf(" %c%c%d",&a,&b,&c) == 3){...} this definition.
Maybe you should just use while(scanf("%c:%d",&a,&b) ==2){...}.
Because this will stop the loop when a matching failure or EOF is met, both of which implies there happenes something unexpected, so you'd better jump out of the loop immediately. And I don't think the value of ':' is useful.
I am a beginner of C language. I was recently writing a program to print a histogram of the number of instances of a character in an input. Printing the histogram horizontally is easy, but vertically is a challenge.
Please have a look at the following code:
#include <stdio.h>
int main()
{
/*THIS IS JUST A SAMPLE OF WHAT I WANT TO ASK*/
int occurrence = 5;
int i;
for (i=0;i<occurrence;i++){
printf("\t*\n");
}
}
For an example, say any letter occurs 5 times. So I have set the occurrence to 5. And I am printing the bar in the form of asterisks. Now through this code, I am able to print an histogram containing 5 asterisks. But the thing is if I want to print other elements, like the x and y axis, the code creates a \n character. So if I write the code to print other elements, they start printing from the next line. So I figured out something else.
Now read this code:
#include <stdio.h>
int main()
{
/*THIS IS JUST A SAMPLE OF WHAT I WANT TO ASK*/
int instances = 5;
int i;
for (i=0;i<instances;i++){
printf("\t*\t\t\t\t\t\t\t\t\t");
}
}
Now what I did is depending on the size of the output screen, I created 9 tab characters so that the next asterisk moves on to the next line without printing any \n character.
Now the main question: IS THERE ANY OTHER WAY TO CREATE INVISIBLE SPACES UNTIL THE NEXT THING TO BE PRINTED MOVES ON TO THE NEXT LINE?
This question might be stupid but if there is a solution, it will be best for me.
NOTE: If there is no such method of creating blank spaces then please suggest a good way to create a vertical histogram. If someone wants an improvisation in the question, I am ready to do it.
Thanks for the help!
Outputs::
If I use the first code and I make other chart elements using printf statements, this is the output::
Now can you see that the bar made of asterisks is not aligned with the x and y axis. This happens due to the \n character.
Instead of hacking around with spaces yourself, you might want to look into a library that handles all that graphical stuff for you. For example, ncurses is a pretty decent library to do pseudo-graphical output on a console. However, "ncurses" seems to be for Unix only, but there may be other libraries for Windows.
If using a library is not an option, I'd suggest to work with a 2-dimensional character buffer (that you treat like a bitmap) instead of writing things directly to the console. It's a lot less "fiddling around". Just watch out to truncate your buffer line size to the console line size before printing, in order to avoid automatic line breaks where you don't want them.
If you do not want to use curses library, for example if you have found a printing terminal in a museum and want that your program can work on it, you have to reverse the problem.
You must print line by line if you do not use a graphic library. So your program could look like :
compute the occurence of characters
compute the maximum occurence
for each line from max occurence to 0
compute a line for every character printing a space (not reached)
for each character
if the occurence is greater than the line index put a mark at correct place in the line
print the line
That's the algo, actual coding is left as exercice for the reader :-)
You might want to think about having a two dimensional array. Start by filling it with spaces. Then replace the spaces with the character you want to print at the correct index. Using two for loops, traverse the array in order to print. Print a new line at the end of the row. Changing the order of the index changes a vertical/horizontal print. Negatives are
having to keep the whole thing in memory.
Needing multiple passes. One to set the characters and another to print.
I'm making a very simple console text editor. In order to move the cursor to the end of the previous line when I backspace at the beginning of a line, I need to read an already printed line from the console, then get its length. How would I go about making this work?
There is no way to do this using scanf() and printf(); the program would need to keep track of what it prints. However, it is also impossible to edit previously printed screen lines using only the standard I/O functions - in order to do that, you'd need to use e.g. ncurses.
Store every element you print in the editor in an char array, because you may have to go back all way up to start or in the middle, not only one line up.
Using WinAPI to get the attribute of a character located in y line and x column of the screen console.
This is what I am trying to do after a call to GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &nativeData); where the console cursor is set to the specified location. This won't work. It will return the last used attribute change instead.
How do I obtain the attributes used on all the characters on their locations?
EDIT:
The code I used to test ReadConsoleOutput() : http://hastebin.com/atohetisin.pl
It throws garbage values.
I see several problems off the top of my head:
No error checking. You must check the return value for ReadConsoleOutput and other functions, as documented. If the function fails, you must call GetLastError() to get the error code. If you don't check for errors, you're flying blind.
You don't allocate a buffer to receive the data in. (Granted, the documentation confusingly implies that it allocates the buffer for you, but that's obviously wrong since there's no way for it to return a pointer to it. Also, the sample code clearly shows that you have to allocate the buffer yourself. I've added a note.)
It looks as if you had intended to read the characters you had written, but you are writing to (10,5) and reading from (0,0).
You're passing newpos, which is set to (10,5), as dwBufferCoord when you call ReadConsoleOutput, but you specified a buffer size of (2,1). It doesn't make sense for the target coordinates to be outside the buffer.
Taking those last two points together I think perhaps you have dwBufferCoord and lpReadRegion confused, though I'm not sure what you meant the coordinates (200,50) to do.
You're interpreting CHAR_INFO as an integer in the final printf statement. The first element of CHAR_INFO is the character itself, not the attribute. You probably wanted to say chiBuffer[0].Attributes rather than just chiBuffer[0]. (Of course, this is moot at the moment, since chiBuffer points to a random memory address.)
If you do want to retrieve the character, you'll first need to work out whether the console is in Unicode or ASCII mode, and retrieve UnicodeChar or AsciiChar accordingly.
Please refer to the following code snippet, I will be referring to the line numbers on it:
https://gist.github.com/wilbertcr/474c6a13e377dc8ce51a
As you can see on line 172-200, I created a modified version of the original back_over function, which just moves the pointer without erasing the character that's moving over.
Outside of the function in_process, and as a global variable, I created int verase, see line 1, which I use on line 82 to indicate CTRL+H has been pressed(ch == tp->tty_termios.c_cc[VERASED]).
My idea is to use this as a flag so I can catch the next character, which should be the number of spaces I need to back_over, and do that by calling back_over the number of times indicated by that next character.
The problem I am having is that I don't know how to turn that next character into its corresponding int so that I can use it on the for loop. Lines 27-38 show a failed attempt to do that, however, no matter how small the key I press(I've tried 1 and 2 and 3), it always takes me to the beginning of the line(luckily back_over doesn't go beyond a line break--see line 185).
It seems like the for loop is being executed more than the it should, which I suspect is happening because "number" is not really 1 or 2 or 3 but something else, something the for loop is interpreting as much bigger than the number I am pressing in the keyboard. I would appreciate some help on how can I turn it into an int.
It turned out it was just a matter of doing:
ch=ch-'0'