C++: How to output a string two letters at a time? - c++

I am trying to read from a file that contains sentences and output them two letters at a time.
IE:
>hello world
Output:
he ll ow or ld
Here is what I have.
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
using namespace std;
int main()
{
string input;
ifstream infile;
infile.open("wordpairs.txt");
while(!infile.eof())
{
getline(infile, input);
for(int i = 0; i < input.length(); i++) //accidentally posted wrong code last time. My apologies.
{
cout << input[i] << input[i+1] << " ";
}
cout << endl;
}
infile.close();
return 0;
}
Edit & Run
and this is what it currently outputs for lets say for example, "hello world"
output:
h he el ll lo ow eo or rl ld d
How do I fix it? I figure it has something to do with my for loop calling input[i + 1], but i dont know how to combine words other than doing that.

This will print anything in pairs of 2 letters:
#include <iostream>
int main()
{
std::string input = "lo zpxcpzx zxpc pzx cpxz c lol";
for (size_t i = 0, printed = 0; i < input.length(); ++i)
{
if (isspace(input[i]))
continue;
std::cout << input[i];
printed++;
if (printed % 2 == 0)
std::cout << " ";
}
return 0;
}
Prints:
lo zp xc pz xz xp cp zx cp xz cl ol

try to modify i++ to i+=2, because you need to skip the second as first

The following takes two characters at a time and prints them. It uses the for syntax to initialize the chars and then to only proceed if reading two characters was successful.
for(char c1{}, c2{}; infile >> c1 >> c2;) {
std::cout << c1 << c2 << ' ';
}

try to use this instead i+=2, in order to avoid repetition.
if it reaches length() , then try using i<s.length().
i have taken s as the string here

Related

An extra character appears while converting a char array to string in C++

So I have written a code where I take three strings at each iteration and store all the combinations of length three(maintaining the order) taking each character from those three strings. I use a char array to make those combinations and then I convert that char array to a string and insert in an unordered_set. While doing so, I encountered a problem where I see an extra character being added at the end of some strings.
Here is my code:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
char charArr[3];
string strArr[3];
unordered_set<string> aSet;
cin >> n;
while(n-- > 0) {
cin >> strArr[0] >> strArr[1] >> strArr[2];
for(int x=0; x<strArr[0].size(); x++) {
charArr[0]=strArr[0][x];
for(int y=0; y<strArr[1].size(); y++) {
charArr[1]=strArr[1][y];
for(int z=0; z<strArr[2].size(); z++) {
charArr[2]=strArr[2][z];
string tempStr(charArr);
cout << "Len = " << tempStr.length() << "\n";
aSet.insert(tempStr);
}
}
}
}
cout << "Check aaz = " << aSet.count("aaz") << "\n";
for(auto it=aSet.begin(); it!=aSet.end(); it++) {
cout << *it << "\n";
}
}
Here is a sample input:
2
a a z
c a c
Here is the output:
Len = 4
Len = 3
Check aaz = 0
cac
aaz
Here is a picture of how it looks in my pc:
However when I ran the same code for same input in ideone, it gave me the correct answer. Which is as follows:
Len = 3
Len = 3
Check aaz = 1
cac
aaz
Can anybody please explain what's going on here?
N.B: I'm using CodeBlocks and C++14

Upon running the i get a pop up windows screen saying "prg.exe has stopped working."

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
int main()
{
char str[100];
cout << "Enter a string : ";
gets(str);
cout << "The words containing y in their last place are : ";
cout << "\n";
for(int i = 0; str[i] != '\0'; i++)
{
int j = i + 1;
if((str[i] == 'y') && (str[j] == ' '))
{
int k;
cout << 134;
char stress[50];
int m = 0;
k = i;
for(; (str[k] != ' ') || (k != 0); k--, m++)
{
stress[m] = str[k];
}
stress[m] = '\0';
int g;
for(g = 0; stress[g] != '\0'; g++)
;
char strain[g];
for(int n = 0, q = k - 1; q >= 0; n++, q--)
{
strain[n] = stress[q];
}
strain[g] = '\0';
for(int p = 0; p < g; p++)
{
cout << strain[p];
}
cout << "\n";
cout << 1;
}
cout << 12;
}
return 0;
}
This c++ program is to display the word containing 'y' as its last letter. I used cout<<12 cout<<1 etc.. to know which part of program is working.
Dont get confused by seeing strain and stress. They are just strings.
I am using codeblocks in windows 7
Upon running the program i get a pop up windows screen saying "prg.exe has stopped working."
Please someone tell me why this error is occuring.
I use codeblocks
I will be really grateful.
You might have errors because of using gets() function, because when you are using gets() you need to know the amount of characters you will get. It was officialy removed by 2011 standart, but almost every C implementation uses it. So to avoid that dangerous function you can use:
getline(), which is very easy to use - like that:
getline(cin,str);
fgets(), it is used like gets, but you need to mention how many characters you will read:
fgets(str, num_of_chars, cin);

Reversing char array

When I print out text2 I see that it is definitely not the reverse of the string I gave it and I'm not sure why that is. When I put in "test" I get stuff like "ȍ\2200+". Can I use strncpy on char arrays? Maybe it needs to be done with a loop - not sure. Any help would be appreciated. :)
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char text[79], text2[79];
bool input = true;
while (input) {
cout << "Please give me a line of text to examine: ";
cin.getline(text, 79);
for(int i = 0; i < strlen(text); i++ )
cout << text[i];
// test to see if it is a palindrome
strncpy(text, text2, 80);
reverse(text2, text2 + strlen(text2));
printf("%s", text2); `// when I print this out I get something odd`
if (strcmp(text, text2) == 0)
cout << " is a palindrome!" << endl;
else
cout << " is not a palindrome." << endl;
if (strcmp(text, "END") == 0)
input = false;
else
cout << "\ntype END to exit the program" << endl;
} // end while loop
} // end main
It seems you're using strncpy in a wrong way: you probably want to copy text into text2, not the other way around.
There's a much simpler way to test whether a string is a palindrome, namely:
bool is_palindrome(const char* s, size_t n) {
size_t i, j;
i = 0, j = n-1;
while (i < j && s[i++] == s[j--])
;
return i >= j;
}
Why not use std::vector<char> and std::reverse from <algorithm> to handle your problem?
I would do something like below: (note that I'm using C++11 range-based for loop and auto which you can change to a regular for loop and use std::string line if you don't have a compiler supporting this).
int main()
{
cout << "Please give me a line of text to examine: ";
auto line = ""s;
getline(cin, line);
// Push back every character to the vector
vector<char> vtext;
for (const auto &elem : line)
vtext.push_back(elem);
// Create a copy of the vector<char> and reverse the copy
vector<char> vtext_reversed{vtext};
reverse(begin(vtext_reversed), end(vtext_reversed));
// Print the line reversed
cout << "\nThis is the line reversed: ";
for (const auto &elem : vtext_reversed)
cout << elem;
}
Typically you'll see this reversal technique for char*:
void reverse(char* s) {
if(!s) return;
size_t n = strlen(s);
for(size_t i = 0; i < n/2; ++i) {
char tmp = s[i];
s[i] = s[n - i - 1];
s[n - i - 1] = tmp;
}
}
This will not work, however, with non-ASCII characters. The reason is that non-ASCII characters require multiple bytes to represent.
You will need to use wide characters to handle multi-byte codepoints, but the logic should follow above.

Use of cin and getline for strings

I was recently doing a problem in C++:
Write a program to work out if a series of 5 digits are consecutive
numbers. To make this easier, assumes the digits are a string:
string numbers = "10-9-8-7-6";
Make sure your code works for the following sequence, as well:
string numbers = "1-2-3-4-5";
I solved it, however I saw when I used cin for the string the console window threw some exception & didn't execute the program but on replacing it with getline, it worked perfectly.
Could anyone explain me the reason behind it because logically both should work properly.
The program is:
#include<iostream>
#include<string>
using namespace std;
void change(int x, int y, int &inc, int &dec)
{
if (x - y == 1)
++dec;
else if (y - x == 1)
++inc;
}
int main()
{
string s = "", snum = "";
cout << "enter 5 nos and use \'-\' to separate them: ";
cin >> s;
int i = 0, x = 0, y = 0, inc = 0, dec = 0;
for (char &ch : s)
{
if (ch == '-')
{
++i;
if (i == 1)
{
y = stoi(snum);
cout << y << endl;
}
else
{
x = y;
y = stoi(snum);
cout << x << " " << y << endl;
change(x, y, inc, dec);
}
snum = "";
}
else
snum += ch;
}
x = y;
y = stoi(snum);
cout << x << " " << y << endl;
change(x, y, inc, dec);
if (inc == 4 || dec == 4)
cout << "ORDERED";
else
cout << "UNORDERED";
return 0;
}
If you have to enter everything at the same time such as:
10 9 8 7 6
All on one line then cin does not record all that at the same time.
Concerning cin it only takes the characters before a space (" ") for example. Getline however takes that entire line and uses it. Another way to do the same thing would be to use the cstdio library and have it set up with either using printf or puts to prompt, and then use gets to gather all the information from the puts prompt. This is what I assume why it works.
Example:
cstdio library
char string[50];
printf("Enter a string of text");
gets(string);
cout << string << endl;
*EDIT
After the comment below I realized what you are asking, and if you are assuming the numbers are strings, and they are separated with hyphens and no spaces then it should work fine. It shouldn't be the problem of cin by maybe something else?
If there are spaces involved in your code then what I wrote above EDIT will be a simple solution to THAT problem.
If you need to get a formatted string, I recommend you scanf like this:
if( 5 == scanf("%d-%d-%d-%d-%d", &a, &b, &c, &d, &e) )
//welldone
// work with above 5 int easily :)
else
// Please enter again
This way you don't have to work with string at all and life would be easier.
You can easily check if these 5 are consecutive or not .
If you need not a new solution and want to get your code fixed, tell me in comment.

How to read a txt file into a 2d array

Hey guys I am new to reading txt files to arrays, so I need to read this txt file temperature.txt to a two dimensional array. Here is the file I need to read, and the code I tried writing up it complies but Im not sure if it is reading it correctly
T(F) R1 R2 R3 R4
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
UPDATE I re did this again without looking at your answers but will this work ?
using namespace std;
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
int main ()
{
char temp[11] [5];
ifstream tempin ("c:\\mydoc2\\temperaturedata.txt");
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]>>temp[8]
>>temp[9]>>temp[10];
while(!tempin.fail())
{
cout<< temp[0] << " " << temp[1] << " " << temp[2] << " " << temp[3]<< " " << temp[4]<< " " << temp[5] << " " << temp [6] <<
" " << temp [7] << " " << temp[8] << " " << temp[9] << " " << temp[10];
tempin>>temp[0]>>temp[1]>>temp[2]>>temp[3]>>temp[4]>>temp[5]>>temp[6]>>temp[7]
>>temp[8]>>temp[9]>>temp[10];
}
cout << endl << endl;
system("pause");
return 0;
}
You have a string myArray[5]; but you're reading 55 elements - that should not work!
There are lots of errors in your code.
1) You have written a read function but you never call it, so it never executes.
2) There is no 2D array in your code. 2D arrays look like this double myArray[10][10];. (that's a 10 by 10 2D array of doubles).
3) You're trying to read floating point numbers, but your array is an array of strings.
4) Your array is size 5 but you try and read 55 items into it.
5) After you open the file you have an infinite loop which just prints out "No file\n". Not sure why you want to print out error messages in a loop. Normally you just print an error message once.
I could go on, but I think the main point is that you're a beginner, and you currently aren't able to write three lines of code without introducing an error (sorry to be harsh but based on the above that is true). So the important lesson is that you should not try to write more than three lines of code at once.
Try something like this
a) Write some code which opens a file, test it and check that it does open the file
b) Add some code to a) to read one number, test it and check that it does read one number.
c) Replace the read one number code with code that reads a 1D array of numbers. Test it and check that it works.
etc. etc.
The point is to build up gradually to the program you want, and test each stage as you go. I can't emphasise how important that is. Every professional programmer works like this, but because you're a beginner the steps you have to take are much smaller than an experienced programmer.
Try something like this:
#include <stdlib.h>
#include <fstream>
#include <sstream>
#include <string>
#include <iostream>
using namespace std;
int main() {
string line;
ifstream myfile ("C:/temps.txt");
int dim_x = 12;
int dim_y = 5;
double temps[dim_x][dim_y] ;
//init the array if neccesary
for(int x = 0;x<dim_x;x++)
for(int y = 0; y<dim_y;y++)
temps[x][y]=0;
if (myfile.is_open()){
for ( int x=0; getline (myfile,line); x++ ){
int y=0;
istringstream iss(line);
while(iss){
string sub;
iss >> sub;
temps[x][y] = ::atof(sub.c_str());
y++;
}
}
myfile.close();
}
cout << "TEMPS:" << endl;
for(int x = 0;x<dim_x;x++){
for(int y = 0; y<dim_y;y++)
cout<<temps[x][y]<<" ";
cout<<endl;
}
return 0;
}
I made some improvements
#include <fstream>
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
void read ();
int main ()
{
read();
return 0;
}
void read()
{
ifstream indata(".\\temperaturedata.txt");
if(indata == NULL)
{
cout<< "Opening file failed."<< endl;
return;
}
const int columns = 5;
const int rows = 11;
double myArray[rows][columns];
string tmp;
getline(indata, tmp);
for(int i = 0; i < rows; ++i)
{
for (int j = 0; j < columns; ++j)
{
cout << "\t" << flush;
indata >> myArray[i][j];
cout.setf(ios::fixed);
cout << setprecision(2) << myArray[i][j] <<flush;
}
cout << endl;
}
indata.close();
}
If the content of your file is like this:
95.0 95.20 66.10 43.10 29.00
96.0 96.10 67.60 43.50 31.20
97.0 97.40 67.00 43.70 30.50
98.0 97.20 69.10 44.10 30.70
99.0 98.90 68.00 44.70 32.80
100.0 99.50 71.10 45.10 31.50
101.0 101.00 71.20 45.30 31.60
102.0 101.60 71.00 45.70 30.50
103.0 101.80 73.10 46.30 32.50
104.0 103.70 73.50 46.60 32.70
105.0 105.60 72.80 47.10 33.60
then, it's quite easy for you to get these values. But there are some errors in your code:
while(!indata.fail()) : This line will cause a dead loop. Use if(!indata) instead.
You will need a 2-dimension array of type double instead of string
Here is what could work:
#include<fstream>
#include<iostream>
#include<cmath>
#include<iomanip>
#include<stdlib.h>
using namespace std;
void read ();
int main ()
{
read();
system("PAUSE");
return 0;
}
void read()
{
ifstream indata("E:\\temperature.txt"); //that's my path,you should use yours.
if(!indata)
{
cout<<"No file."<< endl;
}
if(indata.is_open())
{
double myArray[11][5];
for(int i = 0; i < 11; ++i)
{
for(int j = 0; j < 5; ++j)
{
indata >> myArray[i][j];
//cout<<myArray[i][j]<<"\t";
}
//cout<<endl;
}
}
}
This could work when your txt file doesn't include the first line:T(F) R1 R2 R3 R4, if this line did exit,you should use getline() to move your file pointer to the second line, where you could read the data.