String.length() shows incorrect value [duplicate] - c++

This question already has answers here:
Read whole ASCII file into C++ std::string [duplicate]
(9 answers)
Closed 3 years ago.
I am trying this following code in cpp
#include <iostream>
#include <string>
void Strlength(const string& s) {
cout << s.length() << endl;
}
int main() {
string s;
cin >> s;
cout << s.length() << endl;
Strlength(s);
return 0;
}
The string which I am giving as input is 100,000 characters long and is like "xxxxxxx...xxxxabcde"(fill the ... with remaining x)
This gives me the output as
4095
4095
I am expecting the output to be 100000. what am I doing wrong?
This relates to one of the hackerrank problem (Test case 10): String Similarity

Assuming you describe the input correctly, that is it is one single "word", then the issue is not in your code. The issue must be in the environment which runs the code. It has some kind of mechanism to feed the standard input to your program. Either that has a limitation on total input length, or it has a limitation of line length. 4 kilobytes is 4096 bytes, so perhaps your input is limited by that: 4095 chars of the word plus a newline character (or terminating 0 byte of string, or whatever).
If you are running this under some kind of web interface in browser, the problem could even be, that the input field in the web page has that limitation.
If you need to dig into this, try to read char by char and see what you get, how many chars and how many newlines. Also examine cin.fail(), cin.eof(), cin.bad() and cin.good(). For the question code, you should expect failbit to be false, and eofbit might be true oe false depending on how the input was truncated.

Related

cout chr(10) adds a superfluous chr(13) before it [duplicate]

This question already has answers here:
c++: how to print new line without carriage return [duplicate]
(2 answers)
Closed 2 years ago.
I have two c++ exes communicating over iostream. First exe sends a stream of chars (or bytes) and second intercepts this and decodes them.
exe1.exe emits chars:
void main()
{
for (int i = 0; i < 256; ++i)
cout << static_cast<char>(i);
}
exe2.exe takes them in:
void main()
{
FILE* pipe = _popen("exe1.exe", "rb");
while (!feof(pipe))
cout << static_cast<int>(fgetc(pipe)) << endl;
_pclose(pipe);
}
One would expect to receive 256 values in serial order as so:
0,1,2,3,4,5,6,7,8,9,10,11,12,13...
But one gets
0,1,2,3,4,5,6,7,8,9,13,10,11,12,13...
There is a problem at 10, where you can see an additional 13 before it. Possibly cout wants to be helpful by adding an extra carriage return before a \n char. But it is annoying when one wants to transfer pure bytes between two processes. Yes, cout is for human readability, but is there a way to tell cout or printf to not do that? Or to use another stream which is not intended for humans to read?
Character 10 is the ASCII LF, which is treated as a line break on most platforms. On Windows specifically, the standard line break is a 13 10 (CRLF) sequence. C++ stream implementations are smart enough to know that and will convert character 10 to 13 10 on output when operating in text mode. If you don't want that to happen, you have to put the output stream into binary mode instead.

C++ using cin.ignore() to remove first non-int from the input stream [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
So For example if I input:
33a
and I want to remove "a" from the stream and store 33 into an int, how to do this using cin.ignore?
Edits:
To be more precise:so If I have input:
2
3
4a
b
or
2
3
4
a
b
I want to store those 2,3,4 into an array, and also when encountered 'a'(first non-int char), ignore 'a', and then jumped out the input reading loop(ie
while(cin>>num)
)?
TL;DR version based on question edit:
The smart way is to use a std::vector to store the read values and ignore all the messiness of an array of unknown size.
Then
while not done
read a value
if value successfully read
store value
ignore to the end of the line
else
clear stream error
ignore to the end of the line
I'm only providing a pseudocode answer because this looks too much like a homework assignment at this point. All of the required bits and pieces are discussed below and it's up to OP to assemble them correctly.
If you MUST use an array, before storing a value test to make sure you will not overrun the end of the array by storing the value.
Old answer:
Link to documentation.
cin.ignore() ignores one character.
cin.ignore(10) ignores up to 10 characters.
cin.ignore(10, ' ') ignores up to 10 characters or it finds and consumes a space.
Another common case is discarding the rest of the line: cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
So...
int val;
cin >>val;
cin.ignore();
will handle the simple case of reading an int and discarding the next character. Input of "33a" will result in 33 being stored in val, 'a' being ignored, and the end of line (enter keypress) used to trigger this chain of events is left in cin for future consumption. This could be a problem so,
int val;
cin >>val;
cin.ignore((std::numeric_limits<std::streamsize>::max(), '\n');
will read 33 into val, discard 'a` and anything else the user typed in. This may not be what you want. For example, input of "33a 44b"
int val;
cin >>val;
cin.ignore((std::numeric_limits<std::streamsize>::max(), ' ');
will read 33 into val, discard 'a' and anything else the user typed in up to the first space. Another pass through the above code will result in 44 in val, the discard of 'b', and the end of line staying in cin.
Attempting to use std::getline at this point is bad. It will instantly consume the end of line and return an empty string. However, a third pass though the above code will discard the end of line as whitespace and wait for more input from the user.
However users are lousy sources of input, so you want to protect cin >>val; from a user typing in something like "blah", hitting enter, and trying again. "blah cannot convert to an int, so cin will be set into the error state and you need to acknowledge this before continuing.
int val;
while (!(cin >>val)) // continue as long as the user has finger trouble
{
cin.clear() // clear the error state
// discard the rest of the line because who knows what other garbage is on it.
cin.ignore((std::numeric_limits<std::streamsize>::max(), '\n');
// probably want to notify the user and prompt for good input here.
}
//whichever ignore code fits your usecase
or similar will handle the bad input case.
Although it's not immediately obvious now to do it, streams actually incorporate a way to deal with this quite directly (at least assuming I've understood the question correctly).
When you read (for example) a number from a stream, the stream skips any white-space before the number. To figure out whether a character is white-space or not, the stream uses an associated locale--specifically, the locale's ctype facet.
To have the stream ignore everything except digits, we can provide a locale that classifies everything except digits as white space.
#include <locale>
#include <iostream>
#include <algorithm>
#include <vector>
#include <sstream>
#include <iterator>
class my_ctype : public std::ctype<char> {
public:
mask const *get_table() {
static std::vector<std::ctype<char>::mask>
table(table_size, (mask)space);
std::fill_n(table.begin() + '0', 10, (mask)digit);
return &table[0];
}
my_ctype(size_t refs=0) : std::ctype<char>(get_table(), false, refs) { }
};
int main() {
std::istringstream s("1 2, 9 3 a 4b 2 5");
s.imbue(std::locale(std::locale(), new my_ctype));
int i;
while (s >> i)
std::cout << i << "\n";
}
Result:
1
2
9
3
4
2
5
Note that with this, we don't have to use ignore (or anything else, except the normal stream extractor) to ignore the garbage we don't care about in the stream. The other side of this is that this is useful (at least primarily) when assigned to the stream as a whole. If you want to read 4 numbers this way, then be able to go back to reading everything normally, this probably won't be a useful technique for your situation.

how to force user to input exactly 8 characters into string

how can I limit a user to input 8 characters into string?
can something like this work?
string MyString;
getline(std::cin, MyString, 8);
or maybe there is a different idea to accomplish it
thanks in advance
clarification:
I want to enable the user to input up to 8 characters in the string, but he may enter less.
You can use a loop..
while (MyString.length() != 8) {
std::cout << "Enter exactly 8 characters:";
getline(std::cin, MyString);
}
its hard to think this will help considering my experience (1mnth!)
at codecademy.com in the "Python" language one might say something like:
my_string = "jackie"
len(my_string)
#would print 5
if my_string is <= ..... # if my string is greater or equal to print the following
print "name is too long "
Hope that generated something other than disgust
sincerely dedicated noobie
There is a difference between requesting 8 characters from the User and preventing the User from entering more than 8.
Requesting 8 from User
You can request 8 characters from the User, but the User is allowed to enter as many characters as the User wants until a newline character is entered. This is the behavior of the standard console input.
The console has buffered the all the characters. Depending on the extraction method, you will be extracting 8 characters from the input buffer into your variable. The remaining characters are still in the buffer.
Preventing User from entering more than 8
This is typically used in entering passwords. The standard C++ input facilities cannot help here.
You will need platform specific control of the input source. You will need to read each character, test for a newline and optionally echo back either the character, a uniform character like '*', or not display any characters.
Since it is platform specific, look up the API for your platform.
#include <iostream>
#include <string>
int main(){
std::string str;
bool cStr = true; //check string
while (cStr){
std::getline(std::cin, str);
if (str.size() <= 8) cStr = false;
}
}
You can add a bool object to test your string using an if-statement. If the string size is less than or equal to 8, it will then advert the bool statement to false allowing the exit of the while loop.

C++ Press Enter to Terminate Program [duplicate]

This question already has answers here:
Cin.Ignore() is not working
(4 answers)
Closed 9 years ago.
I am writing a C++ program and I need to program to end/terminate after the user hits enter.
This is what I have:
cout << "Press Enter to End" << endl;
cin.ignore(); //ends after the user hits enter
return 0;
But it doesn't work. Any advice?
I sense that you had some formatted input earlier in your program, i.e., it looks something like this:
std::cin >> value;
do_something(value);
std::cout << "press enter to end\n";
std::cin.ignore();
If that is the case, you have some character in the input buffer from the time you entered value. For example, there can be a '\n' but it can be any odd other characters, too. This character will be read when the program encounters std::cin.ignore().
What you probably want to is to get rid of the characters currently known to be in the buffer. This isn't quite what would be done as this can still miss characters which are already entered but not, yet, transferred but there is no portable approach to clear all potential characters (it is normally not a problem because hardly any user interface depends on character input from a terminal).
To ignore the characters which are known to be present you need to start off by breaking the connection between <stdio.h> and IOStreams using std::ios_base::sync_with_stdio() and later consume the known characters entered after your last read, e.g.,
#include <iostream>
int main()
{
std::ios_base::sync_with_stdio(false);
int x;
std::cin >> x;
std::cin.ignore(std::cin.rdbuf()->in_avail());
std::cout << "press enter\n";
std::cin.ignore();
}
The odd call to sync_with_stdio() is necessary to have the IOStreams actually buffer the characters received from the system rather than reading characters individually. As a nice side effect it dramatically improves the performance of using std:cin, std::cout, and the other standard stream objects.
maybe add system("pause") in the end of code; (include first). I guess you want enter to close termination.

What is wrong with my UVa code

I tried to solve this problem in UVa but I am getting a wrong answer and I cant seem to find the error
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2525
#include<cstdio>
#include<cstring>
using namespace std;
int main()
{
int t,j,k,i=1;
char a[1000];
while(scanf("%d",&t)!=EOF && t)
{
int sum=0;
getchar();
gets(a);
k=strlen(a);
for(j=0;j<k;j++)
{ if(a[j]=='a'||a[j]=='d'||a[j]=='g'||a[j]=='j'||a[j]=='m'||a[j]=='p'||a[j]=='t'||a[j]=='w'||a[j]==32)
sum=sum+1;
else if(a[j]=='b'||a[j]=='e'||a[j]=='h'||a[j]=='k'||a[j]=='n'||a[j]=='q'||a[j]=='u'||a[j]=='x')
sum=sum+2;
else if(a[j]=='c'||a[j]=='f'||a[j]=='i'||a[j]=='l'||a[j]=='o'||a[j]=='r'||a[j]=='v'||a[j]=='y')
sum=sum+3;
else if(a[j]=='s'||a[j]=='z')
sum=sum+4;
}
printf("Case #%d: %d\n",i,sum);
i++;
}
return 0;
}
In the problem description there is a single number that indicates the number of texts that will be in the input afterwards. Your original code was trying to read the number before every row of input.
The attempt to read the number in each one of the rows will fail since the input character set does not include any digits, so you could be inclined to think that there should be no difference. But there is, when you try to read a number it will start by consuming the leading whitespace. If the input is:
< space >< space >a
The output should be 3 (two '0' and one '2' keys), but the attempt to read the number out of the line will consume the two leading whitespace characters and the later gets will read the string "a", rather than " a". Your count will be off by the amount of leading whitespace.
separate your code into functions that do specific things: read the data from the file, calculate the number of key presses for each input, output the result
Benefit:
You can test each function independently. It is also easier to reason about the code.
The maximum size of an input is 100, this means you only need an array of 101 characters( including the final \0) for each input, not 1000.
Since this question is also tagged C++ try to use std::vector and std::string in your code.
The inner for seems right at a cursory glance. The befit of having a specialized function that computes the number of key presses is that you can easily verify it does the correct thing. Make sure you check it thoroughly.