#include <iostream>
using namespace std;
int main()
{
int n,t=0,k=0;
cin>>n;
char data[n][100];
int num[n];
for(int i=0;i<n;i++)
{
while(1)
{
cin>>data[i][t];
cout<<data[i][t]<<endl;
if(data[i][t]=='\n') break;
k++;
if(k%2==1) t++;
}
cout<<i;
num[i]=(t-2)/2;
k=0;
t=0;
}
for(int i=0;i<n;i++)
{
while(1)
{
cout<<data[i][t];
if(t==num[i]) break;
t++;
}
t=0;
}
}
here is the code I have written in c++ which gives the even numbered characters from the starting half of every word given by the user but when giving input after pressing enter the loop should break but the loop is not breaking
while(1)
{
cin>>data[i][t];
cout<<data[i][t]<<endl;
if(data[i][t]=='\n') break;
k++;
if(k%2==1) t++;
}
By default formatted input using the "input" operators >> skip white-space, and newline is a white-space character. So what's happening is that the >> operator simply waits for some non-white-space input to be entered.
To tell the input to not skip white-space you have to use the std::noskipws manipulator:
cin>>noskipws>>data[i][t];
There are some ways to implement in C++ what OP is trying to do. I'd start avoiding Variable Length Arrays, which aren't in the Standard and using std::strings and std::vectors instead.
One option is to read an entire line from input with std::getline and then process the resulting string to keep only the first half of even chars:
#include <iostream>
#include <string>
#include <vector>
int main() {
using std::cin;
using std::cout;
using std::string;
cout << "How many lines?\n";
int n;
cin >> n;
std::vector<string> half_words;
string line;
while ( n > 0 && std::getline(cin, line) ) {
if ( line.empty() ) // skip empty lines and trailing newlines
continue;
string word;
auto length = line.length() / 2;
for ( string::size_type i = 1; i < length; i += 2 ) {
word += line[i];
}
half_words.push_back(word);
--n;
}
cout << "\nShrinked words:\n\n";
for ( const auto &s : half_words ) {
cout << s << '\n';
}
return 0;
}
Another is, as Joachim Pileborg did in his answer, to disable skipping of leading whitespaces by the formatted input functions with std::noskipws manipolator and then read a char at a time:
// ...
// disables skipping of whitespace and then consume the trailing newline
char odd, even;
cin >> std::noskipws >> odd;
std::vector<string> half_words;
while ( n > 0 ) {
string word;
// read every character in a row till a newline, but store in a string
// only the even ones
while ( cin >> odd && odd != '\n'
&& cin >> even && even != '\n' ) {
word += even;
}
// add the shrinked line to the vector of strings
auto half = word.length() / 2;
half_words.emplace_back(word.begin(), word.begin() + half);
--n;
}
// ...
Related
I am trying to get input data from a txt file on Linux / Mint. So, after compiling the code I run the following command: ./a.out output.txt
I need to fill a two-dimensional array but like a jagged array (the number of columns in each row is different). So I want to split it by looking character what is read from file. If the character is '\ n', I want to fill the second line. But I guess I can not read the '\ n' character. I hope I can explain the problem.
I'm writing the code, maybe it will be more clearer.
my input.txt file is:
my c++ code part is for getting input:
for (int i = 0; i<n; i++) {
char ch;
cin >> ch;
int j = 0;
while (ch != '\n') {
arr[i][j] = ch;
cin >> ch;
j++;
}
}
I want to that, if the character is equals the '\n' then program goes on to fill the array to next row.
arr[0][0] = 'a';
arr[0][1] = 'f'
arr[0][2] = 'h'
arr[1][0] = 'b'
arr[1][1] = 'e'
arr[1][2] = 'g'
arr[2][0] = 'c' .......)
When you do cin >> ch it will skip whitespace, which includes spaces, tabs and newline characters. Perhaps, you need to read entire lines using std::getline, and then process each line separately.
For example:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
char ch;
std::string line;
int ln = 0;
while (getline(cin, line)) // read entire line
{
istringstream is;
is.str(line);
while (is >> ch) // now read individual chars from that line
cout << "line: " << ln << " char: " << ch << endl;
ln++;
}
}
And your loop should be something like this:
std::string line;
for (int i=0; i<n; ++i)
{
char ch;
if (!std::getline(cin, line))
break;
std::istringstream is;
is.str(line);
for (int j=0; is >> ch; ++j)
arr[i][j] = ch;
}
You omitted details on how you declare your arr, but it doesn't seem like the code you've shown would handle it properly. Perhaps, it would be better to use vectors:
std::vector<std::vector<char> > arr;
std::string line;
char ch;
while (std::getline(cin, line)) // cin should probably be replaced with ifstream
{
std::istringstream is;
is.str(line);
arr.push_back(vector<char>());
for (int j=0; is >> ch; ++j)
arr.back().push_back(ch);
}
#include<sstream>
#include<iostream>
using namespace std;
int main(){
string line = "test one two three. \n another one \n";
string arr[8];
cout<<line;
int i = 0;
stringstream ssin(line);
while (ssin.good() && i < 8){
ssin >> arr[i];
++i;
}
for(i = 0; i < 8; i++){
cout << arr[i];
}
return 0;
}
//Now i want to print that elements that just come before the newline ("\n") in the string.
Don't think of "test one two three. \n another one \n" as one line of text. It is not. It is two lines of text.
You need to change your strategy of reading a little bit.
int main()
{
string input = "test one two three. \n another one \n";
string arr[8];
int i = 0;
stringstream ssin_1(input);
string line;
// Read only the tokens from the first line.
if ( std::getline(ssin_1, line) )
{
stringstream ssin_2(line);
while ( ssin_2 >> arr[i] && i < 8)
{
++i;
}
}
// Don't print all the elements of arr
// Print only what has been read.
for(int j = 0; j < i; j++){
cout << arr[j] << " ";
}
return 0;
}
Your ssin >> arr[i] skips whitespace, losing all knowledge of which arr entries were followed by newlines.
Instead, you can divide input into lines first, then words, while tracking the newlines:
std::vector<size_t> newline_after_word_index;
std::vector<std::string> words;
while (getline(ssin, line))
{
std::istringstream line_ss(line);
std::string word;
while (line_ss >> word)
words.push_back(word);
newline_after_word_index.push_back(words.size());
}
You can then use indices from newline_after_word_index to print out the words[] entry beforehand....
http://www.cplusplus.com/reference/string/string/find/
#include<sstream>
#include<iostream>
using namespace std;
int main(){
string line = "test one two three. \n another one \n";
size_t found = line.find("\n");
for (int i=0; i<=found; i++){
cout << line[i];
}
return 0; }
I am trying to read a single character multiple times. The catch is that I need to prevent user errors. So for example:
char arr[10];
for(int i = 0; i < 10; i++)
{
cin.get(arr[i]);
}
Where the inputs should be something like a, b, c, d, .... But if someone were to enter ab for the first entry I want to capture the a and then ignore the b. I know about cin.ignore however I don't know how I would go about ignoring an arbitrary number of alphanumeric characters or symbols considering that I want to ignore a potentially unlimited number of characters and then stop ignoring and read again.
How can I either ignore an arbitrary number of characters and then stop ignoring or how can I actually flush the buffer for cin.
Most input is line feed so if you want to ignore all characters in the input stream until you hit a newline then you could use:
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
Since we ignore up to the streamsize there should not be an extra content in the input buffer.
If you want user to hit enter after each symbol, then code could be as simple as this:
char arr[10];
for(int i = 0; i < 10; )
{
std::string line;
std::getline( std::cin, line );
// check that line is not empty
if( line.empty() ) {
std::cout << "missing input" << std::endl;
continue;
}
arr[i++] = line[0]; // get only first symbol and ignore the rest
}
if you have something else in mind, I am afraid that will not work with std::cin - you do not see any input until user presses enter. In that case you would have to use OS specific functions to get unbuffered input.
The following is the code that you want, if your inputing like this a 'enter' b 'enter' c 'enter' etc...
#include <iostream>
#include <string>
using namespace std;
int main() {
char arr[10];
string line;
for (int i = 0; i < 10; i++)
{
getline(cin, line);
arr[i] = line[0];
cout << endl << "Here is the Char: " << arr[i] << endl;
}
return 0;
}
BUT if you enter input like this in one line: a,b,c,d,e,f,g,h,i,j 'enter' then you want the following code:
#include <iostream>
#include <string>
using namespace std;
int main() {
char arr[10];
string line;
int i = 0;
size_t end;
getline(cin, line);
end = 0;
int counter = 0;
if (line != "") {
while (end != string::npos && counter < 10) {
if (counter == 0) {
arr[counter] = line[0];
}
else {
end = line.find(",", end + 1);
arr[counter] = line[end + 1];
}
counter++;
}
}
for (int i = 0; i < 10; i++) {
cout << endl << "Here is the Char: " << arr[i] << endl;
}
return 0;
}
I need to read a sentence word by word until "ENTER" key is pressed. I used a do..while loop to read words until ENTER key is pressed. Please suggest me some conditions for checking ENTER key press (or) others ways for reading similar input.
#include<iostream>
#include<string.h>
using namespace std;
int main(){
char a[100][20]={'\0'};
int i=0;
do{
cin>>a[i++];
} while( \\ Enter key is not pressed );
for(int j= 0 ; j < i ; j++)
cout<< a[j] << " ";
return 0;
}
The statement
cin>>a[i++];
blocks at the prompt already, until the ENTER key is pressed. Thus the solution is to read a single line at once (using std::getline()), and parse the words from it in a separate step.
As your question is tagged c++, you can do the following:
#include <iostream>
#include <vector>
#include <string>
#include <sstream>
int main() {
std::string sentence;
std::cout << "Enter a sentence please: "; std::cout.flush();
std::getline(std::cin,sentence);
std::istringstream iss(sentence);
std::vector<std::string> words;
std::string word;
while(iss >> word) {
words.push_back(word);
}
for(std::vector<std::string>::const_iterator it = words.begin();
it != words.end();
++it) {
std::cout << *it << ' ';
}
std::cout << std::endl; return 0;
}
See the fully working demo please.
As an improvement the current standard provides an even simpler syntax for the for() loop:
for(auto word : words) {
std::cout << word << ' ';
}
while (cin.peek() != '\n') {
cin >> a[i++];
}
First, I must say that πάντα ῥεῖ's solution is better.
But it might be to much for you if, you are beginner.
Besides, I think you want in 2-D array, not vectors.
#include<iostream>
#include<string.h>
using namespace std;
int main(){
/*
All of this is simplified.
For example there are no check if user entered word larger than 100 chars.
And that's not all, but because of simplicity, and easy of understanding....
*/
char a[100][20]={'\0'};
char c;
char buffer[2000];
int i=0, j, k = 0;
/*
Read in advance all to way to ENTER, because on ENTER key all data is flushed to our application.
Untill user hits ENTER other chars before it are buffered.
*/
cin.getline(buffer, 2000, '\n');
do {
c = buffer[k++]; //read one char from our local buffer
j = 0;
//while we don't hit word delimiter (space), we fill current word at possition i
// and of cource while we don't reach end of sentence.
while(c != ' ' && c != '\0'){
a[i][j++] = c; //place current char to matrix
c = buffer[k++]; //and get next one
}
i++; //end of word, go to next one
//if previous 'while' stopped because we reached end of sentence, then stop.
if(c == '\0'){
break;
}
}while(i < 20);
for(j= 0 ; j < i ; j++)
cout<< a[j] << " ";
cout << endl;
return 0;
}
How about using this as your while statement
while( getchar() != '\n' );
You'll need the <stdio.h> header file for this.
See the ideone link
You can try
cin.getline(buffer, 1000);
#include <iostream>
#include <string>
#include <fstream>
#include <cstring>
using namespace std;
int hmlines(ifstream &a){
int i=0;
string line;
while (getline(a,line)){
cout << line << endl;
i++;
}
return i;
}
int hmwords(ifstream &a){
int i=0;
char c;
while ((c=a.get()) && (c!=EOF)){
if(c==' '){
i++;
}
}
return i;
}
int main()
{
int l=0;
int w=0;
string filename;
ifstream matos;
start:
cout << "give me the name of the file i wish to count lines, words and chars: ";
cin >> filename;
matos.open(filename.c_str());
if (matos.fail()){
goto start;
}
l = hmlines(matos);
matos.seekg(0, ios::beg);
w = hmwords(matos);
/*c = hmchars(matos);*/
cout << "The # of lines are :" << l << ". The # of words are : " << w ;
matos.close();
}
The file that i am trying to open has the following contents.
Twinkle, twinkle, little bat!
How I wonder what you're at!
Up above the world you fly,
Like a teatray in the sky.
The output i get is:
give me the name of the file i wish to count lines, words and chars: ert.txt
Twinkle, twinkle, little bat!
How I wonder what you're at!
Up above the world you fly,
Like a teatray in the sky.
The # of lines are :4. The # of words are : 0
int hmwords(ifstream &a){
int i;
You've forgotten to initialize i. It can contain absolutely anything at that point.
Also note that operator>> on streams skips whitespace by default. Your word counting loop needs the noskipws modifier.
a >> noskipws >> c;
Another problem is that after you call hmlines, matos is at end of stream. You need to reset it if you want to read the file again. Try something like:
l = hmlines(matos);
matos.clear();
matos.seekg(0, ios::beg);
w = hmwords(matos);
(The clear() is necessary, otherwise seekg has no effect.)
Formatted input eats whitespaces. You can just count tokens directly:
int i = 0;
std::string dummy;
// Count words from the standard input, aka "cat myfile | ./myprog"
while (cin >> dummy) ++i;
// Count files from an input stream "a", aka "./myprog myfile"
while (a >> dummy) ++i;