Why can't the program output immidiately? - c++

When I enter "111 111" and then press enter, the output shows nothing. Then when I press enter twice, the expected output appears. Why is that?
#include<iostream>
using namespace std;
int main()
{
char seq[10];
//initialize the sequence
for (int i = 0; i<10; i++)
{
seq[i] = ' ';
}
//read characters from the keyboard
for (int i = 0; i<10; i++)
{
cin.get(seq[i]);
if (seq[i] == '\0')
{
break;
}
}
//the output should be the sequence of characters
//users typed before
cout << seq;
system("pause");
return 0;
}

You can use header file string instead, which provides more flexibility like below:
#include<iostream>
#include<string>
using namespace std;
int main()
{
string seq;
//initialize the sequence
//read characters from the keyboard
getline(cin,seq);
//the output should be the sequence of characters
//users typed before
cout << seq;
system("pause");
return 0;
}
In response to OP's question update:
In the described case, You never inputting \0 from standard input, right? Rather you are pressing enter key.
if (seq[i] == '\0'){
Instead, you can replace this checking line with:
if (seq[i] == '\n'){

You can provide std::getline() with an additional char parameter, that defines the line-delimiter. In your case, simply let it read to the next '\0'.
auto seq = std::string{};
std::getline(cin, seq, '\0');
BTW.: are you really sure, you want to read to the next '\0'? It is not too easy to enter a zero character with the keyboard. If you actually are interested in a complete line from the input, just drop the delimiter parameter: std::getline(cin, seq).

This code:
for (int i = 0; i<10; i++){
seq[i] = ' ';
}
initializes all elements in seq to spaces, not '\0'. I don't think your break statement will trigger therefore.

Your program reads 10 characters before it does anything else. So you need to provide 10 characters.
The break check never triggers. why would it.
Finally, cout << seq is not safe, as it may read memory past the end of seq.

Related

Program prints only first three characters in array in C++

My program is to read characters into an array and display it to the console. But I don't know why it only reads first 3 characters.
#include <iostream>
using namespace std;
int main() {
int length=0,i;
char str[10];
cout<<"Enter a string"<<"\n";
for(i=0; str[i] != '\0'; i++) {
cin>>str[i];
}
for(int i=0; str[i]!='\0'; i++) {
cout<<str[i];
length++;
}
cout<<"\n"<<"Length of the string="<<""<<length<<"\n";
}
The output looks like:
Here are some of the issues I noticed:
You're checking the contents of str before you even initialize it.
You're assuming the string you're fetching from the stream will be null-terminated, but that's actually not the case.
You aren't checking whether cin is working correctly
You don't check to make sure the string is 10 characters or less, this could cause you to overflow past the end of the buffer
When you're checking the length of the array, again you assume the string is null-terminated
If you want to fix these issues and still use a char buffer, see user4581301's comprehensive answer. However, I'd suggest simply switching to std::string. For example:
#include<iostream>
using namespace std;
int main()
{
string str;
cout<<"Enter a string"<<"\n";
if (cin >> str) {
cout << str << endl;
cout << "Length of the string = " << str.length() << endl;
}
}
TL;DR version
std::string str; //use std::string. practically no reasons not to in C++
if (cin >> str) // read into string and test that read succeeded.
{
std::cout << str << '\n'
<< "Length of the string=" << str.length() << endl;
}
Explaining and salvaging Asker's version
for(i=0; str[i] != '\0'; i++){ // str[i] tested here
cin>>str[i]; // but it has no assigned value until here.
uses str[i] before it is assigned a value. The program likely found a null character in the block of memory allocated for str and stopped prematurely, but technically anything can happen if you use an uninitialized variable. For example, you got the expected result 3 times before finding the null. The program could never found a null and run forever. It could have rained unicorns. Anything.
int i = 0;
do {
cin>>str[i];
} while (str[i++] != '\0');
reads then tests. But lines of data in a stream are not C-style strings and are not terminated with null.
int i = 0;
do {
cin>>str[i];
} while (!std::isspace(str[i++]));
exits when whitespace is found, typically signalling the end of a word, rather than null.
But what if cin>>str[i]; failed for some reason?
int i = 0;
do {
cin>>str[i];
} while (cin && !std::isspace(str[i++]));
Adds a test to ensure something was read. But what if there are more than 10 characters and char str[10]; is overflowed?
int i = 0;
do {
cin>>str[i];
} while (cin && !std::isspace(str[i]) && ++i < sizeof(str));
unless I am reading That is legal unless I'm reading [expr.cond] and [expr.log.and] wrong, sequencing of when ++i occurs in !std::isspace(str[i]) && ++i < sizeof(str)) is guaranteed to not affect !std::isspace(str[i])
But what if you run out of space before find the null? str is unterminated and not a string! This ruins the for loop later in the program.
int i = 0;
do {
cin>>str[i];
} while (cin && !std::isspace(str[i]) && ++i < sizeof(str));
if (i == sizeof(str))
{
str[sizeof(str)-1] = '\0';
}
I think that covers everything you're likely to run into here.
You read in character by character and store it in str[i]; but then you increment i++ before checking str[i]!='\0'.
There are two issues with this approach: First, you check a value at a position that has not been written at that point in time. Second, cin>>str[i] will never write the string termination character - it just reads in valid characters, and if input is terminated (e.g. by EOF), nothing is written.
So you are approaching this the wrong way.
If you want to read at most 10 characters up to a new line (i.e. when the user presses enter), use fgets. Or - and this is the preferred option - use cin and write into an std::string-object.
int main()
{
std::string str;
cin >> str;
std::cout << str << std::endl;
}
str[i] != '\0' checks the pre-existing data stored at str[i], not the user-input value.
Add string initialization:
char str[10] = {'\0'};
and change the reading with:
char c;
for(int i = 0; cin>> c && c!=/*add your termination cond. here*/ && i < 10;++i)
str[i] = c;
So you can ensure that the string is filled with correct values and terminated appropriately.
But better solution would be to use std::string. In that case you dont have to check the sizes, because the string grows by itself.For example:
std::string str;
for(char c; cin>>c && c!=/*add your termination cond. here*/;)
str += c;

C++ Cin input to array

I am a beginner in c++ and I want to enter a string as character by character into an array , so that I can implement a reverse function .. However unlike C when the enter is hit a '\n' is not insterted in the stream.. how can I stop data from being entered ?
my code is :
#include<iostream>
#include<array>
#define SIZE 100
using namespace std;
char *reverse(char *s)
{
array<char, SIZE>b;
int c=0;
for(int i =(SIZE-1);i>=0;i--){
b[i] = s[c];
c++;
}
return s;
}
int main()
{
cout<<"Please insert a string"<<endl;
char a[SIZE];
int i=0;
do{
cin>>a[i];
i++;
}while(a[i-1]!= '\0');
reverse(a);
return 0;
}
When you read character by character, it really reads characters, and newline is considered a white-space character.
Also the array will never be terminated as a C-style string, that's not how reading characters work. That means your loop condition is wrong.
To begin with I suggest you start using std::string for your strings. You can still read character by character. To continue you need to actually check what characters you read, and end reading once you read a newline.
Lastly, your reverse function does not work. First of all the loop itself is wrong, secondly you return the pointer to the original string, not the "reversed" array.
To help you with the reading it could be done something like
std::string str;
while (true)
{
char ch;
std::cin >> ch;
if (ch == '\n')
{
break; // End loop
}
str += ch; // Append character to string
}
Do note that not much of this is really needed as shown in the answer by Stack Danny. Even my code above could be simplified while still reading one character at a time.
Since you tagged your question as C++ (and not C) why not actually solve it with the modern C++ headers (that do exactly what you want, are tested, save and work really fast (rather than own functions))?
#include <string>
#include <algorithm>
#include <iostream>
int main(){
std::string str;
std::cout << "Enter a string: ";
std::getline(std::cin, str);
std::reverse(str.begin(), str.end());
std::cout << str << std::endl;
return 0;
}
output:
Enter a string: Hello Test 4321
1234 tseT olleH

Big Number,input char[]

I have problem with the following code:
#include<iostream>
using namespace std;
int main()
{
char a[200];
int i;
for (i = 0; cin.get() != '\n'; i++) {
cin >> a[i];
}
cout << i;
system("pause");
return 0;
}
I don't know why when i input without space 10 char for example. i si equal to 10/2=5 ?
You discard every odd symbol, cin.get() read symbol 1,
cin >> read symbol two, and again cin.get() read symbol 3,
and cin >> read symbol 4 from standard input.
You are throwing out half of your cin results.
When you use cin, a character is read, but you are not assigning it to anything inside the for loop criteria; only inside the loop body are you saving it.
Inside the loop, you read in another character (after the one you already read in during the loop's test criteria) and assign that one. The loop repeats, and the next character read is again thrown away with the line cin.get() != '\n' because you are not assigning the results to anything. And this continues, alternating characters you throw away with characters you "save" into the array.
You get two characters, once increment i variable and only second of them insert in array
int main()
{
char a[200];
int i;
\\ cin.get() - get one char and insert it in a[i]
\\ after that, compare this value with '\n'
\\ if equal, break the loop, if different, continue
for (i = 0; (a[i] = cin.get()) != '\n'; i++);
\\ last character ('\n') should be replaced with '\0'
a[i]='\0';
cout << i;
system("pause");
return 0;
}
while solution:
int main()
{
char a[200];
int i=0;
cin >> a[i];
while (a[i] != '\n')
{
i++;
cin >> a[i];
}
a[i]='\0';
cout << i;
system("pause");
return 0;
}
do - while solution:
int main()
{
char a[200];
int i=0;
do
{
cin >> a[i];
}
while(a[i++]!='\n');
a[i-1]='\0';
cout << i-1;
system("pause");
return 0;
}
As a matter of fact, you are reading the standard input (std::cin) in two different ways, storing its output only once every two character extractions.
std::basic_istream::get (cin.get()) extracts character or characters from stream. Once extracted, whey are forgotten, sent to limbo. You simply ignore them. Which is not what I suspect you want to do.
std::basic_istream::operator>> (cin >> ...) also extracts character or characters (following the type of the right hand side operand).
So, with an input of ten characters, you ignore five of them in your for condition check and store five in the loop block.
A correct way to read the characters would be to use std::getline (en.cppreference.com/w/cpp/string/basic_string/getline):
std::string input;
std::getline(cin, input);
std::cout << input << std::endl;
This example code will simply read a line and output it, verbatim, in the standart output.

failing to compare space in a string

I'm making a program which is getting inputs from the user, while each input contains ints delimited with spaces. e.g "2 3 4 5".
I implemented the atoi function well, but, whenever I try to run on the string and "skip" on the spaces I get a runtime error:
for(int i=0, num=INIT; i<4; i++)
{
if(input[i]==' ')
continue;
string tmp;
for(int j=i; input[j]!=' '; j++)
{
//add every char to the temp string
tmp+=input[j];
//means we are at the end of the number. convert to int
if(input[i+1]==' ' || input[i+1]==NULL)
{
num=m_atoi(tmp);
i=j;
}
}
}
In the line 'if(input[i+1]==' '.....' I get an exception.
Basically, I'm trying to insert just "2 2 2 2".
I realized that whenever I try to compare a real space in the string and ' ', the exception raises.
I tried to compare with the ASCII value of space which is 32 but that failed too.
Any ideas?
The problem is that you don't check for the end of the string in your main loop:
for(int j=i; input[j]!=' '; j++)
should be:
for(int j=i; input[j]!=0 && input[j]!=' '; j++)
Also, don't use NULL for the NUL char. You should use '\0' or simply 0. The macro NULL should be used only for pointers.
That said, it may be easier in your case to just use strtol or istringstream or something similar.
Not an answer to the question.
but two big for a comment.
You should note the C++ stream library automatically reads and decodes int from a space separated stream:
int main()
{
int value;
std::cin >> value; // Reads and ignores space then stores the next int into `value`
}
Thus to read multiple ints just put it in a loop:
while(std::cin >> value) // Loop will break if user hits ctrl-D or ctrl-Z
{ // Or a normal file is piped to the stdin and it is finished.
// Use value
}
To read a single line. That contains space separated values just read the line into a string (convert this to a stream then read the values.
std::string line;
std::getline(std::cin, line); // Read a line into a string
std::stringstream linestream(line); // Convert string into a stream
int value;
while(linestream >> value) // Loop as above.
{
// Use Value
}

How to cin Space in c++?

Say we have a code:
int main()
{
char a[10];
for(int i = 0; i < 10; i++)
{
cin>>a[i];
if(a[i] == ' ')
cout<<"It is a space!!!"<<endl;
}
return 0;
}
How to cin a Space symbol from standard input? If you write space, program ignores! :(
Is there any combination of symbols (e.g. '\s' or something like this) that means "Space" that I can use from standard input for my code?
It skips all whitespace (spaces, tabs, new lines, etc.) by default. You can either change its behavior, or use a slightly different mechanism. To change its behavior, use the manipulator noskipws, as follows:
cin >> noskipws >> a[i];
But, since you seem like you want to look at the individual characters, I'd suggest using get, like this prior to your loop
cin.get( a, n );
Note: get will stop retrieving chars from the stream if it either finds a newline char (\n) or after n-1 chars. It stops early so that it can append the null character (\0) to the array. You can read more about the istream interface here.
#include <iostream>
#include <string>
int main()
{
std::string a;
std::getline(std::cin,a);
for(std::string::size_type i = 0; i < a.size(); ++i)
{
if(a[i] == ' ')
std::cout<<"It is a space!!!"<<std::endl;
}
return 0;
}
To input AN ENTIRE LINE containing lot of spaces you can use getline(cin,string_variable);
eg:
string input;
getline(cin, input);
This format captures all the spaces in the sentence untill return is pressed
Use cin.get() to read the next character.
However, for this problem, it is very inefficient to read a character at a time. Use the istream::read() instead.
int main()
{
char a[10];
cin.read(a, sizeof(a));
for(int i = 0; i < 10; i++)
{
if(a[i] == ' ')
cout<<"It is a space!!!"<<<endl;
}
return 0;
}
And use == to check equality, not =.
Using cin's >> operator will drop leading whitespace and stop input at the first trailing whitespace. To grab an entire line of input, including spaces, try cin.getline(). To grab one character at a time, you can use cin.get().
I thought I'd share the answer that worked for me. The previous line ended in a newline, so most of these answers by themselves didn't work. This did:
string title;
do {
getline(cin, title);
} while (title.length() < 2);
That was assuming the input is always at least 2 characters long, which worked for my situation. You could also try simply comparing it to the string "\n".
Try this all four way to take input with space :)
#include<iostream>
#include<stdio.h>
using namespace std;
void dinput(char *a)
{
for(int i=0;; i++)
{
cin >> noskipws >> a[i];
if(a[i]=='\n')
{
a[i]='\0';
break;
}
}
}
void input(char *a)
{
//cout<<"\nInput string: ";
for(int i=0;; i++)
{
*(a+i*sizeof(char))=getchar();
if(*(a+i*sizeof(char))=='\n')
{
*(a+i*sizeof(char))='\0';
break;
}
}
}
int main()
{
char a[20];
cout<<"\n1st method\n";
input(a);
cout<<a;
cout<<"\n2nd method\n";
cin.get(a,10);
cout<<a;
cout<<"\n3rd method\n";
cin.sync();
cin.getline(a,sizeof(a));
cout<<a;
cout<<"\n4th method\n";
dinput(a);
cout<<a;
return 0;
}
I have the same problem and I just used cin.getline(input,300);.
noskipws and cin.get() sometimes are not easy to use. Since you have the right size of your array try using cin.getline() which does not care about any character and read the whole line in specified character count.