What does each element of printf's #%ld!\n mean? - c++

void* PrintHello(void *threadid)
{
long tid;
tid =(long)threadid;
printf("Hello World! It's me, thread #%ld!\n",tid);
pthread_exit(NULL);
}
I'm wondering what each element of the variable declaration stands for and if there is an easier way (more readable/analogous) to just printf?
# =
% =
ld = Long int
! = not?
\n = new line
Also, the pointers seem to be written in two different ways on our slides.
There is:
void* function_name(void* args)
And there is:
void* function_name(void *args)
What is the significance of the asterisk location? Which looks to be correct in this example?

When printing something with a variable, you require % to declare this is the spot where the var input is gonna be. # is just a regular character. ld just represents the type of var you are inputting. In this case, long. ! means nothing as well, it's just a regular character. Also, when printing a var, the only thing that matters (in this case) is the thing between the % and the variable type which is ld in this case. \n just means new line as you stated before.
The asterisks location doesn't change anything. Both of them are correct. The reason for the asterisks is just to tell you it's a pointer

Read your compiler's documentation for printf(). Or online documentation, like this one, or this one. Documentation will explain to you exactly what the various parameters and placeholders are.
In your example, # and ! don't mean anything. They are outside of any format specifier, so they are just literal character data like the majority of your format string content is. Only specifiers preceded by % have any special meaning.
The % character is an escape character that tells printf() to process the following ld specifier. printf() will replace %ld with the value of the tid variable in the formatted string.

Perhaps you would also be interested to see the analogous C++ statement?
Also, for some of you, the C++ version will explain what the printf format info does.
std::printf by default directs the output to stdout. C++ uses std::cout
'#' and '!' are just characters (in both forms)
So, in C++:
std::cout << '#' << tid << "!\n";
However, I would probably use:
std::cout << '#' << tid << '!' << std::endl;
Notes:
Did you notice there is no %ld? The compiler already knows the type of tid (i.e. long int), so you need not explain it a second time to std::cout like you would have to with std::printf.
As an additional benefit, when someone changes the tid type to int32_t (or perhaps int64_t, or static_cast to something smaller), the cout line is un-affected. Quick, what is XX of %XXd for a "long long unsigned int"? How about we never look that up again.
What is the significance of the asterisk location? Which looks to be
correct in this example?
Both forms are 'correct'. I prefer the '* ' form, probably because of my background (with little 'c' exposure).

As stated already by others, %ld in format string "Hello World! It's me, thread #%ld!\n" defines the place where a variable of type long will be placed. # and ! are ordinary characters, and \n stands for a new line (special character backslash gives the subsequent character a special meaning).
But there is another issue in your code when you assign long tid =(long)threadid while having threadid being of type void*, i.e. a pointer to some unspecific type. Actually, if you know that threadid will point to a long, you should write long tid = *((long*)threadid) in order to dereference the pointer and interpret it as particular type long; otherwise, you would assign the pointer value (i.e. some memory address).

This is not a particular keyword of C Language.
let me explain by breaking it up.
#%ld!\n
Equals to
# : Hash character to show count/numbers
%ld : Specifier referencing a long integer that you want to show.
! : Simple exclamatory character.
\n : New line

Related

Sign & Unsigned Char is not working in C++

In C++ Primer 5th Edition I saw this
when I tried to use it---
At this time it didn't work, but the program's output did give a weird symbol, but signed is totally blank And also they give some warnings when I tried to compile it. But C++ primer and so many webs said it should work... So I don't think they give the wrong information did I do something wrong?
I am newbie btw :)
But C++ primer ... said it should work
No it doesn't. The quote from C++ primer doesn't use std::cout at all. The output that you see doesn't contradict with what the book says.
So I don't think they give the wrong information
No1.
did I do something wrong?
It seems that you've possibly misunderstood what the value of a character means, or possibly misunderstood how character streams work.
Character types are integer types (but not all integer types are character types). The values of unsigned char are 0..255 (on systems where size of byte is 8 bits). Each2 of those values represent some textual symbol. The mapping from a set of values to a set of symbols is called a "character set" or "character encoding".
std::cout is a character stream. << is stream insertion operator. When you insert a character into a stream, the behaviour is not to show the numerical value. Instead, the behaviour to show the symbol that the value is mapped to3 in the character set that your system uses. In this case, it appears that the value 255 is mapped to whatever strange symbol you saw on the screen.
If you wish to print the numerical value of a character, what you can do is convert to a non-character integer type and insert that to the character stream:
int i = c;
std::cout << i;
1 At least, there's no wrong information regarding your confusion. The quote is a bit inaccurate and outdated in case of c2. Before C++20, the value was "implementation defined" rather than "undefined". Since C++20, the value is actually defined, and the value is 0 which is the null terminator character that signifies end of a string. If you try to print this character, you'll see no output.
2 This was bit of a lie for simplicity's sake. Some characters are not visible symbols. For example, there is the null terminator charter as well as other control characters. The situation becomes even more complex in the case of variable width encodings such as the ubiquitous Unicode, where symbols may consist of a sequence of several char. In such encoding, and individual char cannot necessarily be interpreted correctly without other char that are part of such sequence.
3 And this behaviour should feel natural once you grok the purpose of character types. Consider following program:
unsigned char c = 'a';
std::cout << c;
It would be highly confusing if the output would be a number that is the value of the character (such as 97 which may be the value of the symbol 'a' on the system) rather than the symbol 'a'.
For extra meditation, think about what this program might print (and feel free to try it out):
char c = 57;
std::cout << c << '\n';
int i = c;
std::cout << i << '\n';
c = '9';
std::cout << c << '\n';
i = c;
std::cout << i << '\n';
This is due to the behavior of the << operator on the char type and the character stream cout. Note, the << is known as formatted output means it does some implicit formatting.
We can say that the value of a variable is not the same as its representation in certain contexts. For example:
int main() {
bool t = true;
std::cout << t << std::endl; // Prints 1, not "true"
}
Think of it this way, why would we need char if it would still behave like a number when printed, why not to use int or unsigned? In essence, we have different types so to have different behaviors which can be deduced from these types.
So, the underlying numeric value of a char is probably not what we looking for, when we print one.
Check this for example:
int main() {
unsigned char c = -1;
int i = c;
std::cout << i << std::endl; // Prints 255
}
If I recall correctly, you're somewhat close in the Primer to the topic of built-in types conversions, it will bring in clarity when you'll get to know these rules better. Anyway, I'm sure, you will benefit greatly from looking into this article. Especially the "Printing chars as integers via type casting" part.

Odd behavior in boost::format hex

I'm trying to format a binary array: char* memblock to a hex string.
When I use the following:
fprintf(out, "0x%02x,", memblock[0]);
I get the following output:
0x7f,
When I try to use boost::format on an ofstream like so:
std::ofstream outFile (path, std::ios::out); //also tried with binary
outFile << (boost::format("0x%02x")%memblock[0]);
I get a weird output like this (seen in Vi): 0x0^?.
What gives?
Given that the character for 0x7f is CTRL-?, it looks like it's outputting the memblock[0] as a character rather than a hex value, despite your format string.
This actually makes sense based on what I've read in the documentation. Boost::format is a type-safe library where the format specifiers dictate how a variable will be output, but limited by the actual type of said variable, which takes precedence.
The documentation states (my bold):
Legacy printf format strings: %spec where spec is a printf format specification.
spec passes formatting options, like width, alignment, numerical base used for formatting numbers, as well as other specific flags. But the classical type-specification flag of printf has a weaker meaning in format.
It merely sets the appropriate flags on the internal stream, and/or formatting parameters, but does not require the corresponding argument to be of a specific type. e.g. : the specification 2$x, meaning "print argument number 2, which is an integral number, in hexa" for printf, merely means "print argument 2 with stream basefield flags set to hex" for format.
And presumably, having the field flag set to hex doesn't make a lot of sense when you're printing a char, so it's ignored. Additionally from that documentation (though paraphrased a little):
The type-char does not impose the concerned argument to be of a restricted set of types, but merely sets the flags that are associated with this type specification. A type-char of p or x means hexadecimal output but simply sets the hex flag on the stream.
This is also verified more specifically by the text from this link:
My colleagues and I have found, though, that when a %d descriptor is used to print a char variable the result is as though a %c descriptor had been used - printf and boost::format don't produce the same result.
The Boost documentation linked to above also explains that the zero-padding 0 modifier works on all types, not just integral ones, which is why you're getting the second 0 in 0x0^? (the ^? is a single character).
In many ways, this is similar to the problem of trying to output a const char * in C++ so that you see a pointer. The following code:
#include <iostream>
int main() {
const char *xyzzy = "plugh";
std::cout << xyzzy << '\n';
std::cout << (void*)xyzzy << '\n';
return 0;
}
will produce something like:
plugh
0x4009a0
because the standard libraries know that C-style strings are a special case but, if you tell them it's a void pointer, they'll give you a pointer as output.
A solution in your specific case may be just to cast your char to an int or some other type that intelligently handles the %x format specifier:
outFile << (boost::format("0x%02x") % static_cast<int>(memblock[0]));

searching files?

This code is a part of a larger code that indexes files, and tokenizes the words in each file so that you can be able to search a certain word in the large amount of file you have. (like Google)
This function is supposed to search your files for a word that you want to find. But I don't completely understand how it works!
Can someone please explain what this code does and how it does it?
In addition, I have several questions:
1) What exactly in "infile"?
2) What does the built-in function c_str() do?
3) Why does the variable "currentlineno" start at 1? Couldn't the first line in a file start at 0?
4) What is the difference between ++x and x++?
5) What is the difference between the condition "currentlineno < lineNumber" and "currentlineno != lineNumber" ?
This is the code:
void DisplayResult(string fileName, int lineNumber)
{
ifstream infile(fileName.c_str(), ifstream::in);
char line[1000];
int currentlineno = 1;
while(currentlineno < lineNumber)
{
infile.getline(line, 1000);
++currentlineno;
}
infile.getline(line, 1000);
cout<<endl<<"\nResult from ("<<fileName<<" ), line #"<<lineNumber<<": "<<endl;
cout<<"\t"<<line;
infile.close();
}
This function display the line at the corresponding line number pass by parameter.
1/ Infile permits to open a file as in put streams : http://www.cplusplus.com/reference/fstream/ifstream/
2/ c_str() permits to pass to a string structure to a simple char* (a char array). It is the structure use in the language C, which explains why the method name is "c_str". In C++, we usually use string more than char* cause it is really simpler.
3/ Why currentlineno start at 1 ? The function read the file content before the given line number. The, read one more time to display the wanted line.
4/ ++x is pre-incrementation, x++ is post-incrementation.
When you use ++x, x is incremented before to use it, otherwise, with x++, x is incremented after.
int x = 1;
cout << ++x; // display 2
x = 1;
cout << x++; // display 1
5/ Look at operators : http://www.cplusplus.com/doc/tutorial/operators/
1) What exactly in "infile"?
ANS:: Construct object and optionally open file. Link
2) What does the built-in function c_str() do?
ANS:: It is needed to get a const char* representation of the text stored
inside a std::string class. Link
3) Why does the variable "currentlineno" start at 1? Couldn't the first line in a file start at 0?
ANS:: Depends on the second input parameter of the function DisplayResult.
4) What is the difference between ++x and x++?
ANS:: See this. Probably you may have heard of Post-Increment and Pre-Increment.
5) What is the difference between the condition "currentlineno < lineNumber" and "currentlineno != lineNumber" ?
ANS:: Value of currentlineno should not exceed the value of lineNumber when condition is currentlineno < lineNumber. Value of currentlineno may exceed or may be less than the value of lineNumber but should not be equal to the value of lineNumber when condition is currentlineno != lineNumber.
This function does not search for words.
It takes as input a file name and a line number. It tries to find and read that line.
The output starts with a line stating: "The result from (fileName ), line #lineNumber: "
It is followed by a text indented by a tab and followed by the found line contents. This second line of output is left incomplete (not followed by a newline).
The found contents is empty, if the file has has less than the requested number of lines or if any of the lines before the requested line has more than 999 characters.
If the requested line has more than 999 characters it is truncated to 999 characters.
Other questions:
1) infile is a function-scope object of automatic storage duration and type std::basic_ifstream<char, std::char_traits<char>>, which is initialized for reading from the file named in fileName.
2) The member function c_str() built into the standard library string class returns a pointer to the string contents as a non-modifiable, nul-terminated character array, which is the format typically used in C for strings (type const char *). For historical reasons the file-based standard library streams take their file name arguments in this format.
3) Humans typically count line numbers starting with one. That is the convention used for the lineNumber parameter. The algorithm used must match this. The currentlineno local variable is used to mean 'the number of the next line to be read'. As such it must be initialized with 1. (This is somewhat confusing, considering the name of the variable.) Other implementations that initialize the line counter with 0 are possible - and indeed natural to most C++ programmers.
4) See any textbook or online reference of C++. Look for "pre-increment" (++x) and "post-increment" (x++) operators. They have the same side effect (increment x), but differ in the value of the expression. If you don't use the result they are equivalent (for basic types).
C++ programmers usually prefer pre-increment as it can generally be implemented more efficiently for user-defined types.
5) Even more basic textbook question. a < b tests for a less-than relationship, a != b tests for inequality.
Note: All answers assume that the types used are from the standard C++ library, i.e that appropriate includes of the <string> and <iostream> headers and necessary using directives or declarations are used.

Scanf function with strings

I need to read input from user. The input value may be string type or int type.
If the value is int then the program insert the value into my object.
Else if the value is string then it should check the value of that string, if it's "end" then the program ends.
Halda h; //my object
string t;
int tint;
bool end=false;
while(end!=true)
{
if(scanf("%d",&tint)==1)
{
h.insert(tint);
}
else if(scanf("%s",t)==1)
{
if(t=="end")
end=true;
else if(t=="next")
if(h.empty()==false)
printf("%d\n",h.pop());
else
printf("-1\n");
}
}
The problem is that scanning string doesn't seem to work properly.
I've tried to change it to: if(cin>>t) and it worked well.
I need to get it work with scanf.
The specifier %s in the scanf() format expects a char*, not a std::string.
From C11 Standard (C++ Standard refers to it about the C standard library):
Except in the case of a % specifier, the input item (or, in the case of a %n directive, the
count of input characters) is converted to a type appropriate to the conversion specifier. If
the input item is not a matching sequence, the execution of the directive fails: this
condition is a matching failure. Unless assignment suppression was indicated by a *, the
result of the conversion is placed in the object pointed to by the first argument following
the format argument that has not already received a conversion result. If this object
does not have an appropriate type, or if the result of the conversion cannot be represented
in the object, the behavior is undefined.
Anyway, here there's is no real reason to prefer the C way, use C++ facilities. And when you use the C library, use safe functions that only reads characters up to a given limit (just like fgets, or scanf with a width specifier), otherwise you could have overflow, that leads again to undefined behavior, and some errors if you're luck.
That's a really bad way to check for end-of-input. Either use an integer or use a string.
If you choose string, make provisions to convert from string to int.
My logic would be to first check if it can be converted to integer. if it can be, then continue with the logic. If it can't be(such as if it's a float or double or some other string) then ignore and move on. If it can be, then insert it into Halda's object.
Sidenote: Do not use scanf() and printf() when you're working with C++.
Assuming string refers to std::sring this program doesn't have defined behavior. You can't really use std::string with sscanf() You could set up a buffer inside the std::string and read into that but the string wouldn't change its size. You are probably better off using streams with std::string (well, in my opinion you are always better off using streams).

Disambiguating std::isalpha() in C++

So I am currently writing a part of a program that takes user text input. I want to ignore all input characters that are not alphabetic, and so I figured std::isalpha() would be a good way to do this. Unfortunately, as far as I know there are two std::isalpha() functions, and the general one needs to be disambiguated from the locale-specific one thusly:
(int(*)(int))std::isalpha()
If I don't disambiguate, std::isalpha seems to return true when reading uppercase but false when reading lowercase letters (if I directly print the returned value, though, it returns 0 for non-alpha chars, 1 for uppercase chars, and 2 for lowercase chars). So I need to do this.
I've done so in another program before, but for some reason, in this project, I sometimes get "ISO C++ forbids" errors. Note, only sometimes. Here is the problematic area of code (this appears together without anything in between):
std::cout << "Is alpha? " << (int(*)(int))std::isalpha((char)Event.text.unicode) << "\n";
if ( (int(*)(int))std::isalpha((char)Event.text.unicode) == true)
{
std::cout << "Is alpha!\n";
//...snip...
}
The first instance, where I send the returned value to std::cout, works fine - I get no errors for this, I get the expected values (0 for non-alpha, 1 for alpha), and if that's the only place I try to disambiguate, the program compiles and runs fine.
The second instance, however, throws up this:
error: ISO C++ forbids comparison between pointer and integer
and only compiles if I remove the (int(*)(int)) snippet, at which point bad behavior ensues. Could someone enlighten me here?
You are casting the return value of the std::alpha() call to int(*)(int), and then compare that pointer to true. Comparing pointers to boolean values doesn't make much sense and you get an error.
Now, without the cast, you compare the int returned by std::alpha() to true. bool is an integer type, and to compare the two different integer types the values are first converted to the same type. In this case they are both converted to int. true becomes 1, and if std::isalpha() returned 2 the comparison ends up with 2 != 1.
If you want to compare the result of std::alpha() against a bool, you should cast that returned in to bool, or simply leave out the comparison and use something like if (std::isalpha(c)) {...}
There is no need to disambiguate, because the there is no ambiguity in a normal call.
Also, there is no need to use the std:: prefix when you get the function declaration from <ctype.h>, which after C++11 is the header you should preferably use (i.e., not <cctype>) – and for that matter also before C++11, but C++11 clinched it.
Third, you should not compare the result to true.
However, you need to cast a char argument to unsigned char, lest you get Undefined Behavior for anything but 7-bit ASCII.
E.g. do like this:
bool isAlpha( char const c )
{
typedef unsigned char UChar;
return !!isalpha( UChar( c ) );
}