Extra whitespace in output after using scanf ( %c) - whitespace

After I run this do/while loop for the first time the output always seems to have an extra space before the printf. I think it might have something to do with buffer overflow, but I'm not quite sure how to get rid of it.
Any help would be much appreciated, thanks!
do {
printf("Enter a format specifier: ");
scanf(" %c", fmt+1);
printf(fmt, value);
} while(*(fmt+1) != 'q');
**fmt is a char array.

I expanded your code into a complete program as follows:
#include "stdio.h"
main () {
char fmt[2] = "% ";
int value = 23;
do {
printf("Enter a format specifier: ");
scanf(" %c", fmt+1);
printf(fmt,value);
} while(*(fmt+1) != 'q');
}
... and got the following result:
Enter a format specifier: i
23h (Enter a format specifier: d
23h (Enter a format specifier: x
17h (Enter a format specifier: o
27h (Enter a format specifier: q
qh (
This output was a little different from what you seem to have observed, but I think it might be the same in principle. If so, I think it is as you suspected: a buffer overflow error caused by the fact that fmt is declared as a char array that isn't long enough to include the null that should be at the end of any C string. Thus, printf() kept on writing random data after the format character until it happened to come across a null.
Changing the fourth line of code to ensure that the string has enough space for the visible characters and the terminating null, but no more, i.e.:
char fmt[] = "% ";
... gives the following result (which was, perhaps, something like you expected?):
Enter a format specifier: i
23Enter a format specifier: d
23Enter a format specifier: x
17Enter a format specifier: o
27Enter a format specifier: q
q
For more info on this issue you could read Char array initialization dilemma.

Related

trying the check if cin.get() leaves the end of line character in stream

1.i am trying to check whether the cin.get() leaves the end line character in stream and considered it for next input.
i have tried this code in code blocks but unable to provide input for next string,i am attaching code i have tried and the output .could anyone please explain.
#include<iostream>
using namespace std;
int main()
{
char s1[10];
char s2[10];
cout << "enter the first string: ";
cin.get(s1, 10);
cout << "enter the second string: ";
cin.getline(s2, 10);
cout << s1 << " " << s2;
return 0;
}
enter the first string: hello
enter the second string: hello
please explain the output
This get function reference says that your overload is
Same as get(s, count, widen('\n'))
And that overload of the function reads until (among other things)
the next available input character c equals delim, as determined by Traits::eq(c, delim). This character is not extracted (unlike basic_istream::getline())
[Emphasis mine]
So the newline is left in the input buffer, for the getline call to read as an "empty" line.
If you want to read lines, I suggest you use std::string and std::getline (which does read, and throw away, the newline).
cin.get() grabs the newline character by default. It will not leave the newline in the stream.

How to detect snprintf failure?

I am using snprintf to format string using user-defined format (also given as string). The code looks like this:
void DataPoint::valueReceived( QVariant value ) {
// Get the formating QVariant, which is only considered valid if it's string
QVariant format = this->property("format");
if( format.isValid() && format.type()==QMetaType::QString && !format.isNull() ) {
// Convert QString to std string
const std::string formatStr = format.toString().toStdString();
LOGMTRTTIINFO(pointName<<"="<<value.toString().toUtf8().constData()<<"=>"<<formatStr<<"["<<formatStr.length()<<'\n');
// The attempt to catch exceptions caused by invalid formating string
try {
if( value.type() == QMetaType::QString ) {
// Treat value as string (values are allways ASCII)
const std::string array = value.toString().toStdString();
const char* data = (char*)array.c_str();
// Assume no more than 10 characters are added during formating.
char* result = (char*)calloc(array.length()+10, sizeof(char));
snprintf(result, array.length()+10, formatStr.c_str(), data);
value = result;
}
// If not string, then it's a number.
else {
double data = value.toDouble();
char* result = (char*)calloc(30, sizeof(char));
// Even 15 characters is already longer than largest number you can make any sense of
snprintf(result, 30, formatStr.c_str(), data);
LOGMTRTTIINFO(pointName<<"="<<data<<"=>"<<formatStr<<"["<<formatStr.length()<<"]=>"<<result<<'\n');
value = result;
}
} catch(...) {
LOGMTRTTIERR("Format error in "<<pointName<<'\n');
}
}
ui->value->setText(value.toString());
}
As you can see I assumed there will be some exception. But there's not, invalid formatting string results in gibberish. This is what I get if I try to format double using %s:
So is there a way to detect that invalid formatting option was selected, such as formatting number as string or vice-versa? And what if totally invalid formatting string is given?
You ask if it's possible to detect format/argument mismatch at run-time, right? Then the short and only answer is no.
To expand on that "no" it's because Variable-argument functions (functions using the ellipsis ...) have no kind of type-safety. The compiler will convert some types of arguments to others (e.g. char or short will be converted to int, float will be converted to double), and if you use a literal string for the format some compilers will be able to parse the string and check the arguments you pass.
However since you pass a variable string, that can change at run-time, the compiler have no possibility for any kind of compile-time checking, and the function must trust that the format string passed is using the correct formatting for the arguments passed. If it's not then you have undefined behavior.
It should be noted that snprintf might not actually fail when being passed mismatching format specifier and argument value.
For example if using the %d format to print an int value, but then passing a double value, the snprintf would happily extract sizeof(int) bytes from the double value, and interpret it as an int value. The value printed will be quite unexpected, but there won't be a "failure" as such. Only undefined behavior (as mentioned above).
Thus it's not really possible to detect such errors or problems at all. At least not through the code. This is something that needs proper testing and code-review to catch.
What happens when snprintf fails? When snprintf fails, POSIX requires that errno is set:
If an output error was encountered, these functions shall return a negative value and set errno to indicate the error.
Also you can find some relevant information regarding how to handle snprintf failures Here.

stored hex values in notepad file with .ini extension how to read it in hex only via CAPL

I have stored hex values in a text file with .ini extension along with address. But when i read it, it will not be in hex format it will be in character so is there any way to read value as hex and store it in byte in C language or in CAPL script?
I assume that you know how to read a text file in CAPL...
You can convert a hex string to a number using strtol(char s[], long result&):long. See the CAPL help (CAPL Function Overview -> General -> strol):
The number base is
haxadecimal if the string starts with "0x"
octal if the string starts with "0"
decimal otherwise
Whitespace (space or tabs) at the start of the staring are ignored.
Example:
on start
{
long number1, number2;
strtol("0xFF", number1);
strtol("-128", number2);
write("number1 = %d", number1);
write("number2 = %d", number2);
}
Output:
number1 = 255
number2 = -128
See also: strtoll(), strtoul(), strtoull(), strtod() and atol()
Update:
If the hex string does not start with "0x"...
on message 0x200
{
if (this.byte(0) == hextol("38"))
write("byte(0) == 56");
}
long hextol(char s[])
{
long res;
char xs[8];
strncpy(xs, "0x", elcount(xs)); // cpy "0x" to 'xs'
strncat(xs, s, elcount(xs)); // cat 'xs' and 's'
strtol(xs, res); // convert to long
return res;
}

8051 sentence and word counter

I found this code below on the internet which is suppose to count the sentences on an 8051 MCU.
Can someone please explain to me what is exactly happening where there are question marks.
Any kind of help would be highly appreciated.
#include<string.h>
char code *text=" what is a program? that has, a a lot of errors! When " ;
char code *text1=" you compile. this file, uVision. reports a number of? ";
char code *text2=" problems that you! may interactively correct. " ; //Null characters are also included in array!!!
void count ( char pdata* , char pdata*);
void main (void){
char pdata Nw,Ns;
char data TextNw[2],TextNs[2];
count(&Nw, &Ns); // call subroutine
TextNw[0]=Nw/10; //?????????????????????????????????
TextNw[1]=Nw%10; //?????????????????????????????????
TextNs[0]=Ns/10; //?????????????????????????????????
TextNs[1]=Ns%10; //?????????????????????????????????
while(1);
}
void count ( char pdata *Nw, char pdata *Ns ){
unsigned char N, i, ch;
typedef enum {idle1, idle2} state; //?????????????????????????????????
state S; // begining state
P2=0x00; // pdata bank definition it must be performed first!!
*Ns=*Nw=0; // without proper start-up there is no initialisation, initialise now!!
S=idle1; // beginning state
N=strlen(text)+strlen(text1)+strlen(text2)+3; //????????????? + 3 to acount 3 Null characters!
P2=0x00; // pdata bank definition
for(i=0;i!=N;i++){
ch=text[i]; // take a caharacter from the text
switch (S)
{
case (idle1):{
if (ch==0) break; // skip NULL terminating character!
if (ch!=' '){
S=idle2;
(*Nw)++;
}
break;
}
case(idle2):{
if (ch==0) break; // skip NULL terminating character!
if((ch==' ')||(ch==','))S=idle1;
else if ((ch=='?')||(ch=='.')||(ch=='!')){
S=idle1;
(*Ns)++;
}
break;
}
}
}
}
This program does 2 things in conjunction - counts number of sentences in the text and counts the number of words in the text. Once the counting is done, the results are stored in 2-char arrays. For example, for 57 words in 3 sentences the results will be stored as this: TextNw = {'5','7'} and TextNs = {'0','3'}.
The variable N contains the full length of the text with the addition of 3 null terminating characters (one per sentence).
The algorithm simultaneously counts words and sentences. In idle1 state the counting is in word-counting mode. In idle2 state the counting is in sentence-counting mode. The modes are interchanged according to current character being read - if delimiter is encountered, the appropriate counter is increased.

What's in xcode console with scanf ,when want a number but input a char?

xcode 5.0
when I run following code:
void guessNum(){
int answer = 0;
int guess = 0;
int turn = 0;
answer = arc4random() % 100 + 1;
while (guess != answer) {
turn++;
NSLog(#"Guess #%i: Enter a number between 1 and 100", turn);
scanf("%i", &guess);
if (guess > answer) {
NSLog(#"Lower!");
}
else if (guess < answer) {
NSLog(#"Higher!");
}
else {
NSLog(#"Correct! The answer was %i", answer);
}
} // end of while loop
NSLog(#"It took you %i tries", turn);
}
when I type a character, just like a in xcode debug console, program run automatic and print:
...
2013-11-18 10:47:39.719 donglix[15115:303] Higher!
2013-11-18 10:47:39.719 donglix[15115:303] Guess #1932: Enter a number between 1 and 100
2013-11-18 10:47:39.719 donglix[15115:303] Higher!
2013-11-18 10:47:39.720 donglix[15115:303] Guess #1933: Enter a number between 1 and 100
...
what's the problem?
"scanf()" reads the input you've typed in and, because of your "%i" (integer) format string, is expecting to take that input and drop it into a number.
If you used "%s" as your format string, then you would take the input as a C-style character array (and have to convert those characters if you wanted to get the integer value out of that).
For example, you can replace this line:
scanf("%i", &guess);
with something like this:
char stringToConvert[256]; // if you type more than 256 characters, you'll crash
sscanf("%s",&stringToConvert);
guess = atoi(stringToConvert); // this function converts the string into an integer
If you type in the character "a", scanf converts that to 97 in the ascii table.

Resources