Ignore function anomaly when used to reading files in c++ - c++

I am trying to use the ignore function skip a few lines, but the parameters of the function are oddly different. Shouldn't it be a streamsize(amount of characters and a delimiter(to stop ignoring up to the assigned character). The problem i am having is that the 2nd parameter for me it is required to be an integer. While i want to use "\n" it doesn't accept it because it is char.
std::basic_istream<char,std::char_traits<char>> &std::basic_istream<char,std::char_traits<char>>::ignore(std::streamsize,int)': cannot convert argument 2 from 'const char [2]' to 'int'

"\n" (with double quotes) is a string literal, not a char literal. In this case, it's an array of two chars; equivalent to {'\n', '\0'}.
'\n' (with single quotes) is a char literal. It represents a single newline character.
std::istream::ignore accepts only a single character as its delimiter, so you have to use the latter.
Note: std::istream::ignore's second parameter is an int rather than a char so that it can accommodate the extra "end of file" pseudo-character. The eof value has to be different than any valid character value, so the type used for the delimiter must be wider than char.

Related

Why is this considered constant?

I have a stack of UTF8 characters:
stack<wchar_t> tokenStack;
i try to add to it like this:
void doLeftParen() { tokenStack.push( L"(" ) }
but the compiler doesn't like it:
$ g++ PropositionalLogic.cpp -o PropositionalLogic
PropositionalLogic.cpp:27:39: error: reference to type 'const value_type'
(aka 'const wchar_t') could not bind to an lvalue of type 'const wchar_t [2]'
void doLeftParen() { tokenStack.push( L"(" ) }
I tried searching for the error, but came up empty. I'm not really sure what else i should be searching for. I've also tried just adding a regular ASCII character, but same error. How can i add characters to this stack?
You're trying to push a string not a char, changing the double quotes to single quotes will make it work, also you're missing a semi-colon at the end of the push function
void doLeftParen() { tokenStack.push( L'(' ); }
You are almost right:
From lex.ccon
A character literal that begins with the letter L, such as L'z',
is a wide-character literal.
Characters with prefix L is not a UTF8 character literal.
The compile error in your code is L"(" (w/ double-quotes) is a multicharater literal but the code expects it to be a stack of wide character literals.
Change it to single-quotes:
L'(' // now a wide-char literal

initialize char array with quotes and curly braces

I'm little confused. What is the logically difference between these codes?
#include <iostream>
using namespace std;
int main(){
char a[5]="ABCD"; // this
cout << a;
return 0;
}
Second is
char a[5]={"ABCD"}; // this
Third is
char a[5]={'A','B','C','D'}; // this
char a[5]={"ABCD"};
char a[5]={'A','B','C','D','\0'};
In both cases, the array of characters a is declared with a size of 5 elements of type char: the 4 characters that compose the word "ABCD", plus a final null character ('\0'), which specifies the end of the sequence and that, in the second case, when using double quotes (") it is appended automatically.Attention adding null character separating via commas. A series of characters enclosed in double quotes ("") is called a string constant. The C compiler can automatically add a null character '\0' at the end of a string constant to indicate the end of the string.
Source:This link can help you better
The first two are assignment of a char[5] source to a char[5] array with different syntax only. (the 5 being the four letters plus a null terminator)
The last one will also do the same, but it doesn't explicitly specify a null terminator. Since you are assigning to a char[5], the last one will still zero-fill the remaining space, effectively adding a null terminator and acting the same, but the last one will not throw a compiler error if you assign to a char[4]; it will just leave you with an unterminated array of characters.

Why can't character constants/literals be empty?

In C and C++ the rules are the same. In C,
[§6.4.4.4]/2 An integer character constant is a sequence of one or
more multibyte characters enclosed in single-quotes, as in 'x'.
In C++,
[§2.14.3]/1 A character literal is one or more characters enclosed
in single quotes, as in 'x', optionally preceded by one of the
letters u, U, or L, as in u'y', U'z', or L'x',
respectively.
The key phrase is "one or more". In contrast, a string literal can be empty, "", presumably because it consists of the null terminating character. In C, this leads to awkward initialization of a char. Either you leave it uninitialized, or use a useless value like 0 or '\0'.
char garbage;
char useless = 0;
char useless2 = '\0';
In C++, you have to use a string literal instead of a character literal if you want it to be empty.
(somecondition ? ' ' : '') // error
(somecondition ? " " : "") // necessary
What is the reason it is this way? I'm assuming C++'s reason is inherited from C.
The reason is that a character literal is defined as a character. There may be extensions that allow it to be more than one character, but it needs to be at least one character or it just doesn't make any sense. It would be the same as trying to do:
int i = ;
If you don't specify a value, what do you put there?
This is because an empty string still contains the the null character '\0' at the end, so there is still a value to bind to the variable name, whereas an empty character literal has no value.
String is a set of character terminated by a NULL character ( '\0' ).
So a Empty string will always have a NULL character in it at the end .
But in case of a character literal no value is there.
it needs at least one character.

C++ comparing a char to a string literal [duplicate]

This question already has answers here:
c++ compile error: ISO C++ forbids comparison between pointer and integer
(5 answers)
Closed 5 years ago.
Beginning programmer here...
I'm writing a very simply program for my computer science class and I ran into an issue that I'd like to know more about. Here is my code:
#include <iostream>
using namespace std;
int main(int argc, const char * argv[])
{
char courseLevel;
cout << "Will you be taking graduate or undergraduate level courses (enter 'U'"
" for undergraduate,'G' for graduate.";
cin >> courseLevel;
if (courseLevel == "U")
{
cout << "You selected undergraduate level courses.";
}
return 0;
}
I'm getting two error messages for my if statement:
1) Result of comparison against a string literal is unspecified (use strncmp instead).
2) Comparison between pointer and integer ('int' and 'const char*').
I seem to have resolved the issue by enclosing my U in single quotes, or the program at least works anyway. But, as I stated, I'd simply like to understand why I was getting the error so I can get a better understanding of what I'm doing.
You need to use single quotes instead.
In C, (and many other languages) a character constant is a single character1 contained in single quotes:
'U'
While a string literal is any number of characters contained in double quotes:
"U"
You declared courseLevel as a single character: char courseLevel; So you can only compare that to another single char.
When you do if (courseLevel == "U"), the left side is a char, while the right side is a const char* -- a pointer to the first char in that string literal. Your compiler is telling you this:
Comparison between pointer and integer ('int' and 'const char*')
So your options are:
if (courseLevel == 'U') // compare char to char
Or, for sake of example:
if (courseLevel == "U"[0]) // compare char to first char in string
Note for completeness: You can have mulit-character constants:
int a = 'abcd'; // 0x61626364 in GCC
But this is certainly not what you're looking for.
Rapptz is right, but I think some more elaboration should help...
courseLevel == "U"
In C and C++, double-quotes create string literals - which are arrays of characters finishing with a numerical-0 ASCII-NUL terminating sentinel character so programs can work out where the text ends. So, you basically are asking if a character is equal to an array of characters... they just can't be compared. Similar questions that are valid are:
does this character variable hold a specific character value: courseLevel == 'U'
does this character variable appear in a specific array: strchr(courseLevel, "U")
does this character variable match the first element in a specific array: courseLevel == "U"[0]
Of course, the first one of these is the one that makes intuitive sense in your program.
The reason why you get an error is because string literals in C and C++ end with a null terminated character \0 while single characters don't. So when you compare to a char to a string literal you're comparing the character literal to a char array {'U','\0'}.

What does '\0' mean?

I can't understand what the '\0' in the two different place mean in the following code:
string x = "hhhdef\n";
cout << x << endl;
x[3]='\0';
cout << x << endl;
cout<<"hhh\0defef\n"<<endl;
Result:
hhhdef
hhhef
hhh
Can anyone give me some pointers?
C++ std::strings are "counted" strings - i.e., their length is stored as an integer, and they can contain any character. When you replace the third character with a \0 nothing special happens - it's printed as if it was any other character (in particular, your console simply ignores it).
In the last line, instead, you are printing a C string, whose end is determined by the first \0 that is found. In such a case, cout goes on printing characters until it finds a \0, which, in your case, is after the third h.
C++ has two string types:
The built-in C-style null-terminated strings which are really just byte arrays and the C++ standard library std::string class which is not null terminated.
Printing a null-terminated string prints everything up until the first null character. Printing a std::string prints the whole string, regardless of null characters in its middle.
\0 is the NULL character, you can find it in your ASCII table, it has the value 0.
It is used to determinate the end of C-style strings.
However, C++ class std::string stores its size as an integer, and thus does not rely on it.
You're representing strings in two different ways here, which is why the behaviour differs.
The second one is easier to explain; it's a C-style raw char array. In a C-style string, '\0' denotes the null terminator; it's used to mark the end of the string. So any functions that process/display strings will stop as soon as they hit it (which is why your last string is truncated).
The first example is creating a fully-formed C++ std::string object. These don't assign any special meaning to '\0' (they don't have null terminators).
The \0 is treated as NULL Character. It is used to mark the end of the string in C.
In C, string is a pointer pointing to array of characters with \0 at the end. So following will be valid representation of strings in C.
char *c =”Hello”; // it is actually Hello\0
char c[] = {‘Y’,’o’,’\0′};
The applications of ‘\0’ lies in determining the end of string .For eg : finding the length of string.
The \0 is basically a null terminator which is used in C to terminate the end of string character , in simple words its value is null in characters basically gives the compiler indication that this is the end of the String Character
Let me give you example -
As we write printf("Hello World"); /* Hello World\0
here we can clearly see \0 is acting as null ,tough printinting the String in comments would give the same output .