Formatting C++ output problem - c++

Let me examplify my problem , I've a function like:
void printer(int width, int hight){
for(int i=0;i<width;++i) std::cout<<" & ";
for(int i=0;i<hight;++i) std::cout<<" ^ ";
std::cout<<std::endl;
}
my problem is function printer should always output of both for loop in same width
e.g:
output could look (width 5):
&^
&&&^
or there is anyway that i print any of (from above code) for loop's output in constant width independent of no of times for loop executes

Question is unclear. Are you looking for something like the following ?
void printer(int amps, int carets, int overallWidth){
for (int i = amps + carets; i < overallWidth; i++) std::cout<<" "; // leading padding
for (int i=0;i<amps;++i) std::cout<<"&";
for (int i=0;i<carets;++i) std::cout<<"^";
std::cout<<std::endl;
}
The change was just to add a loop for outputting the padding. (also changed the parameters name for clarity)
printer(1,1,5);
printer(3,1,5);
would then produce the output shown in example
&^
&&&^
and of course, rather than being passed as a parameter, the overallWidth variable could be hardcoded; an implicit constant of the printer() function.
Edit:
The snippet above stayed very close to that of the question. There are however more idiomatic approaches, for example the following "one liner", which uses one of the string constructor overloads to produce the strings of repeated characters, and iomanip's setw() to produce the padding.
void printer(int amps, int carets, int overallWidth){
std::cout << setiosflags(ios::right) << setw(overalWidth)
<< string(amps, '&') + string (carets, '^')
<< std::endl;
}

Look into <iomanip>. Using cout you can specify a width.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << setiosflags(ios::left) << setw(10) << "Hello"
<< setiosflags(ios::right) << setw(20) << "World!";
return 0;
}

Related

Cout does not work on my other turbo c++ complier

Hello guys i am beginner on the language c++
i was trying to run this code below on my ide"codeblocks" and it works
https://www.youtube.com/watch?v=vLnPwxZdW4Y (link for the tutorial that following )
#include <iostream>
using namespace std;
int main()
{
string charactername = "arnold";
int characterage;
characterage = 10;
cout << "Hello my name is" << charactername<< endl;
cout << "i am " << characterage << endl;
return 0;
}
this code does not work on my other compiler running on dosbox ? any ideas why ?
I suggest you stop using Turbo C++ as it is a very outdated and a discontinued compiler. However, if you don't have the option of using new compilers (I had the same issue as I studied C++ at school), you will have to make the following changes:
using namespace std; cannot be used in Turbo C++. You will have to remove that and replace #include<iostream> with #include<iostream.h>
Data-type string cannot be used in Turbo C++. You will have to declare a character array instead.
You will have to use #include<stdio.h> and the function puts(); to display the character array in case of Turbo C++. Alternatively you can use a loop-statement.
This will be your final code:
#include <iostream.h>
#include <stdio.h>
int main()
{
char charactername[] = "arnold";
int characterage;
characterage = 10;
cout << "Hello my name is ";
puts(charactername);
cout << "i am " << characterage << endl;
return 0;
}
Note: The puts(); function automatically puts the cursor on the next line. So you don't need to use endl;
Or, if you want to use a loop-statement to display the character array
#include <iostream.h>
int main()
{
char charactername[] = "arnold";
int characterage;
characterage = 10;
cout << "Hello my name is ";
int i=0;
while(charactername[i]!='\0') {
cout<<charactername[i];
i++;
}
cout<<endl;
cout << "i am " << characterage << endl;
return 0;
}
'\0' is the last element of the character array. So as long as the loop does not reach the last element, it will print the character array.
a[] = "arnold"; basically means an array is created like this: a[0]='a', a[1]='r', a[2]='n',.... a[5]='d', a[6]='\0'.
Alternatively, if you use cout << charactername; instead of the while loop, it will print the whole name. (This is only in the case of a string variable (character array), for an integer array or any other array you will need the while loop)

Mean and Mode of vector array - How can I make a smaller improvement in the function

Doing an exercise to find the mean and mode of a list of numbers input by a user. I have written the program and it works, but I'm wondering if my function 'calcMode' is too large for this program. I've just started looking into functions which is a first attempt. Would it be better to write smaller functions? and if so what parts can I split? Im pretty new to C++ and also looking if I can improve this code. Is there any changes I can make to make this run more efficient?
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int calcMean(vector<int> numberList)
{
int originNumber = numberList[0];
int nextNumber;
int count = 0;
int highestCount = 0;
int mean = 0;
for (unsigned int i = 0; i <= numberList.size() - 1; i++)
{
nextNumber = numberList[i];
if (nextNumber == originNumber)
count++;
else
{
cout << "The Number " << originNumber << " appears " << count << " times." << endl;
count = 1;
originNumber = nextNumber;
}
}
if (count > highestCount)
{
highestCount = count;
mean = originNumber;
}
cout << "The Number " << originNumber << " appears " << count << " times." << endl;
return mean;
}
int main()
{
vector<int> v;
int userNumber;
cout << "Please type a list of numbers so we can arrange them and find the mean: "<<endl;
while (cin >> userNumber) v.push_back(userNumber);
sort(v.begin(), v.end());
for (int x : v) cout << x << " | ";
cout << endl;
cout<<calcMean(v)<<" is the mean"<<endl;
return 0;
}
One thing to watch out for is copying vectors when you don't need to.
The function signature
int calcMode(vector<int> numberList)
means the numberList will get copied.
int calcMode(const & vector<int> numberList)
will avoid the copy. Scott Meyer's Effective C++ talks about this.
As an aside, calling is a numberList is misleading - it isn't a list.
There are a couple of points that are worth being aware of in the for loop:
for (unsigned int i = 0; i <= numberList.size()-1; i++)
First, this might calculate the size() every time. An optimiser might get rid of this for you, but some people will write
for (unsigned int i = 0, size=numberList.size(); i <= size-1; i++)
The size is found once this way, instead of potentially each time.
They might even change the i++ to ++i. There used to a potential overhead here, since the post-increment might involve an extra temporary value
One question - are you *sure this gives the right answer?
The comparison nextNumber == originNumber is looking at the first number to begin with.
Try it with 1, 2, 2.
One final point. If this is general purpose, what happens if the list is empty?
Would it be better to write smaller functions?
Yes, you can make do the same job using std::map<>; which could be
a much appropriate way to count the repetition of the array elements.
Secondly, it would be much safer to know, what is the size of the
array. Therefore I suggest the following:
std::cout << "Enter the size of the array: " << std::endl;
std::cin >> arraySize;
In the calcMode(), you can easily const reference, so that array
will not be copied to the function.
Here is the updated code with above mentioned manner which you can refer:
#include <iostream>
#include <algorithm>
#include <map>
int calcMode(const std::map<int,int>& Map)
{
int currentRepetition = 0;
int mode = 0;
for(const auto& number: Map)
{
std::cout << "The Number " << number.first << " appears " << number.second << " times." << std::endl;
if(currentRepetition < number.second )
{
mode = number.first; // the number
currentRepetition = number.second; // the repetition of the that number
}
}
return mode;
}
int main()
{
int arraySize;
int userNumber;
std::map<int,int> Map;
std::cout << "Enter the size of the array: " << std::endl;
std::cin >> arraySize;
std::cout << "Please type a list of numbers so we can arrange them and find the mean: " << std::endl;
while (arraySize--)
{
std::cin >> userNumber;
Map[userNumber]++;
}
std::cout << calcMode(Map)<<" is the mode" << std::endl;
return 0;
}
Update: After posting this answer, I have found that you have edited your function with mean instead of mode. I really didn't get it.
Regarding mean & mode: I recommend you to read more. Because in general, a data set can have multiple modes and only one mean.
I personally wouldn't split this code up in smaller blocks, only if i'd want to reuse some code in other methods. But just for this method it's more readable like this.
The order of excecution is aroun O(n) for calc which is quite oke if you ask me

Reading into an Array Multiple Times

I'm having a little trouble with my code. It's pretty much supposed to open two files, and compare the first twenty line of the file "StudentAnswers.txt" [inputted as a char into a char array] against a char value in (each line of another file) "CorrectAnswers.txt" in another array at the same position (index). It's like a linear search, but the same position in the arrays. Then a report should be displayed, detailing which question the student missed, the given answer, the correct answer, and if the student passed (got >= 70%) or not, like the following:
Report for Student X:
2 (A/D), 3 (C/D), 5(D/A)
This student passed the exam!
Then it should clear the SAArray, and feed the next twenty lines from StudentAnswers.txt, and start the process all over again. I guess the program has to determine the number of students from (lines of 'StudentAnswers.txt' file / 20).
I'm having trouble displaying the report, and having the array clear itself after the program. I'm guessing this can be done with a while loop and an accumulator for the number of students (to be determined by above equation).
Also, Visual Studio seems to go to "Missed __ questions for a total of ___ %", and then keep looping -858993460.
Any help would be appreciated.
#include <iostream>
#include <fstream>
#include <string>
#include <array>
#include <algorithm>
using namespace std;
void GradeReturn(char[], char[], int, int, int);
string PassFail(float);
int main()
{
ifstream SA("StudentAnswers.txt");
ifstream CA("CorrectAnswers.txt");char CAArray[20];
char SAArray[20];
// char SA2Array[20];
bool isCorrect;
int correct;
int incorrect;
int counter;
correct = 0;incorrect = 0;
counter = 0;
cout << endl;
if (!SA.fail())
{
cout << "'StudentAnswers.txt' file opened successfully." << endl;
cout << "'CorrectAnswers.txt' file opened successfully." << endl << endl;
int a = 0;
int b = 0;
while (a < 20)
{
CA >> CAArray[a];
a++;
} // while loop to feed char into the array
while (b < 20)
{
SA >> SAArray[b];
b++;
}
} // while loop to feed char into array
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
return 0;
}
void GradeReturn(char CAArray[], char SAArray[], int correct, int incorrect, int counter)
{
float percent;
float hundred;
int student;
int catcher[20];
int writeCatcher; int starter;
int catcher_size;
student = 0;
writeCatcher = 0;
catcher_size = ((sizeof catcher) / 4);
while (counter < 20)
{
if ((CAArray[counter]) == (SAArray[counter]))
{
correct++;
cout << "Good job!" << endl;
} // correct handling
else
{
incorrect++;
cout << "You got question " << counter << " wrong." << endl;
counter >> catcher[writeCatcher];
writeCatcher++;
} // incorrect handling
counter++;
} // while loop to determine if a student got a question right or wrong
static_cast <float> (incorrect); // float conversion
cout << endl; // for cleanliness
percent = ((static_cast <float> (correct)) / 20); // percentage
hundred = percent * 100;
PassFail(percent);
if (PassFail(percent) == "pass")
{
student++;
cout << "Report for Student " << student << ":" << endl;
cout << "-----------------------------" << endl;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
starter = 0;
while (starter < (sizeof catcher)
{
if(1=1)
{
catcher_size
}
else
{
cout << "";
starter++;
}
}
}
else if (PassFail(percent) == "fail")
{
student++;
cout << "Missed " << incorrect << " questions out of 20 for ";
cout << hundred << " % correct." << endl << endl;
while (starter < catcher_size)
{
if ((catcher[starter]) == -858993460)
{
starter++;
}
else
{
cout << "";
starter++;
}
}
}
return;
}
string PassFail(float percent)
{
if (percent >= 0.70) // if <pass>
{
return "pass";
}
else // if <fail>
{
return "fail";
}
cout << endl;
}
To get a loop you should keep streams open instead of closing them after reading 20 lines.
As pseudo code that would be:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter);
a = 0; // Reset a
}
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
You would also need to pass correct, incorrect, counter by reference so that the GradeReturn can change their value and their by do the accumulation.
Like:
void GradeReturn(char CAArray[], char SAArray[], int& correct, int& incorrect, int& counter)
Further you shouldn't rely on being able to read exactly Nx20 lines from the files every time. A file could have, e.g. 108 (5x20 + 8) lines, so you code should be able to handle the with only 8 lines. In other words, don't hard code 20 in your function like while (counter < 20). Instead pass the number of lines to be handled and do while (counter < number_to_handle).
Something like this as pseudo code:
a = 0;
while(streams_not_empty)
{
CA >> CAArray[a];
SA >> SAArray[a];
++a;
if (a == 20)
{
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
// ^
a = 0; // Reset a
}
}
if (a != 0)
{
// Process the rest
GradeReturn(&CAArray[counter], &SAArray[counter], correct, incorrect, counter, a);
}
CA.close(); // closing "CorrectAnswers.txt"
SA.close(); // closing "StudentAnswers.txt"
One problem you have is you're trying to compare C-style strings with the == operator. This will compare them essentially as if they were pointers to char, i.e. compare whether they point at the same location in memory, not compare the contents of the string. I urge you to look up array-decay and c-string variables to understand more.
Specifically, if (PassFail(percent) == "pass") isn't going to do what you want it to. strcomp doc, strncmp doc using std::string variables instead of c-style strings would all work, but it would be better simply to compare percent to a value, i.e. if(percent >= 0.70 directly instead of calling PassFail and comparing a string.
There are many other issues here also, you at one point call PassFail but do nothing with the return value. The only side affect of PassFail is cout << endl, if that's what you intend, it's a poor decision and hard to read way to put a newline on the console.
Try asking your compiler for more warnings, that's often helpful in finding these types of issues. -Wall -Wextra work for gcc, you may have to read your compiler manual...

A c++ program that stores the positions of each bit 1 in a binary sequence

I have made this code to store the position of each bit 1 entered in a binary sequence. The output of the program is not what it is desired. The output I get for 10100 is 0x7fff9109be00. Here is the code:
#include <iostream>
#include <bitset>
using namespace std;
int main()
{
bitset <5> inpSeq;
int x = 0;
int xorArray[x];
unsigned int i;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for ( i = 0; i < inpSeq.size(); i++)
{
if ( inpSeq[i] == 1 )
{
x = x+1;
xorArray[x] = i;
}
}
cout << xorArray << "\n";
}
Update for clarity: What I had in mind was that 'cout << xorArray' will print bit 1's positions.
cout << xorArray << "\n";
This does not print the elements of xorArray; it prints its address.
You must iterate ("loop over") it:
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
Your other problem is that you're trying to use a variable-length array, which does not exist in C++. Use a vector instead.
Now it gives you your desired output:
#include <iostream>
#include <bitset>
#include <vector>
using namespace std;
int main()
{
bitset<5> inpSeq("10111");
std::vector<int> xorArray;
for (unsigned int i = 0; i < inpSeq.size(); i++) {
if (inpSeq[i] == 1)
xorArray.push_back(i);
}
for (auto x : xorArray)
cout << x << ' ';
cout << '\n';
}
If you're not using C++11 for whatever reason, you can perform that final loop the traditional way:
for (std::vector<int>::const_iterator it = xorArray.begin(),
end = xorArray.end(),
it != end; ++it) {
cout << *it << ' ';
}
Or the naive way:
for (unsigned int i = 0; i < xorArray.size(); i++)
cout << xorArray[i] << ' ';
I am a little unclear on exactly what you are trying to achieve, but I think the following might help.
#include <iostream>
#include <bitset>
#include <list>
using namespace std;
int main() {
bitset<5> inpSeq;
unsigned int i;
list<int> xorList;
cout << "Enter a 5-bit sequence: \n";
cin >> inpSeq;
for (i = 0; i < inpSeq.size(); ++i) {
if (inpSeq[i] == 1) {
xorList.push_back(i);
}
}
for (list<int>::iterator list_iter = xorList.begin();
list_iter != xorList.end(); list_iter++)
{
cout << *list_iter << endl;
}
return 0;
}
The reason why I am using a list is because you mentioned wanting to store the positions of the 1 bit. The list is being used as the container for those positions, in case you need them in another point in the program.
One of the problems with the original code was that you assigned variable 'x' the value 0. When you declared xorArray[x], that meant you were essentially creating an array of length 0. This is incorrect syntax. It looks like you actually were trying to dynamically allocate the size of the array at runtime. That requires a different syntax and usage of pointers. The list allows you to grow the data structure for each 1 bit that you encounter.
Also, you cannot print an array's values by using
cout << xorArray << endl
That will print the memory address of the first element in the array, so, xorArray[0]. Whenever you want to print the values of a data structure such as a list or array, you need to iterate across the structure and print the values one by one. That is the purpose of the second for() loop in the above code.
Lastly, the values stored are in accordance with the 0 index. If you want positions that start with 1, you'll have to use
xorList.push_back(i+1);
Hope this helps!

How do you append an int to a string in C++? [duplicate]

This question already has answers here:
How to concatenate a std::string and an int
(25 answers)
Closed 6 years ago.
int i = 4;
string text = "Player ";
cout << (text + i);
I'd like it to print Player 4.
The above is obviously wrong but it shows what I'm trying to do here. Is there an easy way to do this or do I have to start adding new includes?
With C++11, you can write:
#include <string> // to use std::string, std::to_string() and "+" operator acting on strings
int i = 4;
std::string text = "Player ";
text += std::to_string(i);
Well, if you use cout you can just write the integer directly to it, as in
std::cout << text << i;
The C++ way of converting all kinds of objects to strings is through string streams. If you don't have one handy, just create one.
#include <sstream>
std::ostringstream oss;
oss << text << i;
std::cout << oss.str();
Alternatively, you can just convert the integer and append it to the string.
oss << i;
text += oss.str();
Finally, the Boost libraries provide boost::lexical_cast, which wraps around the stringstream conversion with a syntax like the built-in type casts.
#include <boost/lexical_cast.hpp>
text += boost::lexical_cast<std::string>(i);
This also works the other way around, i.e. to parse strings.
printf("Player %d", i);
(Downvote my answer all you like; I still hate the C++ I/O operators.)
:-P
These work for general strings (in case you do not want to output to file/console, but store for later use or something).
boost.lexical_cast
MyStr += boost::lexical_cast<std::string>(MyInt);
String streams
//sstream.h
std::stringstream Stream;
Stream.str(MyStr);
Stream << MyInt;
MyStr = Stream.str();
// If you're using a stream (for example, cout), rather than std::string
someStream << MyInt;
For the record, you can also use a std::stringstream if you want to create the string before it's actually output.
cout << text << " " << i << endl;
Your example seems to indicate that you would like to display the a string followed by an integer, in which case:
string text = "Player: ";
int i = 4;
cout << text << i << endl;
would work fine.
But, if you're going to be storing the string places or passing it around, and doing this frequently, you may benefit from overloading the addition operator. I demonstrate this below:
#include <sstream>
#include <iostream>
using namespace std;
std::string operator+(std::string const &a, int b) {
std::ostringstream oss;
oss << a << b;
return oss.str();
}
int main() {
int i = 4;
string text = "Player: ";
cout << (text + i) << endl;
}
In fact, you can use templates to make this approach more powerful:
template <class T>
std::string operator+(std::string const &a, const T &b){
std::ostringstream oss;
oss << a << b;
return oss.str();
}
Now, as long as object b has a defined stream output, you can append it to your string (or, at least, a copy thereof).
Another possibility is Boost.Format:
#include <boost/format.hpp>
#include <iostream>
#include <string>
int main() {
int i = 4;
std::string text = "Player";
std::cout << boost::format("%1% %2%\n") % text % i;
}
Here a small working conversion/appending example, with some code I needed before.
#include <string>
#include <sstream>
#include <iostream>
using namespace std;
int main(){
string str;
int i = 321;
std::stringstream ss;
ss << 123;
str = "/dev/video";
cout << str << endl;
cout << str << 456 << endl;
cout << str << i << endl;
str += ss.str();
cout << str << endl;
}
the output will be:
/dev/video
/dev/video456
/dev/video321
/dev/video123
Note that in the last two lines you save the modified string before it's actually printed out, and you could use it later if needed.
For the record, you could also use Qt's QString class:
#include <QtCore/QString>
int i = 4;
QString qs = QString("Player %1").arg(i);
std::cout << qs.toLocal8bit().constData(); // prints "Player 4"
cout << text << i;
One method here is directly printing the output if its required in your problem.
cout << text << i;
Else, one of the safest method is to use
sprintf(count, "%d", i);
And then copy it to your "text" string .
for(k = 0; *(count + k); k++)
{
text += count[k];
}
Thus, you have your required output string
For more info on sprintf, follow:
http://www.cplusplus.com/reference/cstdio/sprintf
cout << text << i;
The << operator for ostream returns a reference to the ostream, so you can just keep chaining the << operations. That is, the above is basically the same as:
cout << text;
cout << i;
cout << "Player" << i ;
cout << text << " " << i << endl;
The easiest way I could figure this out is the following..
It will work as a single string and string array.
I am considering a string array, as it is complicated (little bit same will be followed with string).
I create a array of names and append some integer and char with it to show how easy it is to append some int and chars to string, hope it helps.
length is just to measure the size of array. If you are familiar with programming then size_t is a unsigned int
#include<iostream>
#include<string>
using namespace std;
int main() {
string names[] = { "amz","Waq","Mon","Sam","Has","Shak","GBy" }; //simple array
int length = sizeof(names) / sizeof(names[0]); //give you size of array
int id;
string append[7]; //as length is 7 just for sake of storing and printing output
for (size_t i = 0; i < length; i++) {
id = rand() % 20000 + 2;
append[i] = names[i] + to_string(id);
}
for (size_t i = 0; i < length; i++) {
cout << append[i] << endl;
}
}
There are a few options, and which one you want depends on the context.
The simplest way is
std::cout << text << i;
or if you want this on a single line
std::cout << text << i << endl;
If you are writing a single threaded program and if you aren't calling this code a lot (where "a lot" is thousands of times per second) then you are done.
If you are writing a multi threaded program and more than one thread is writing to cout, then this simple code can get you into trouble. Let's assume that the library that came with your compiler made cout thread safe enough than any single call to it won't be interrupted. Now let's say that one thread is using this code to write "Player 1" and another is writing "Player 2". If you are lucky you will get the following:
Player 1
Player 2
If you are unlucky you might get something like the following
Player Player 2
1
The problem is that std::cout << text << i << endl; turns into 3 function calls. The code is equivalent to the following:
std::cout << text;
std::cout << i;
std::cout << endl;
If instead you used the C-style printf, and again your compiler provided a runtime library with reasonable thread safety (each function call is atomic) then the following code would work better:
printf("Player %d\n", i);
Being able to do something in a single function call lets the io library provide synchronization under the covers, and now your whole line of text will be atomically written.
For simple programs, std::cout is great. Throw in multithreading or other complications and the less stylish printf starts to look more attractive.
You also try concatenate player's number with std::string::push_back :
Example with your code:
int i = 4;
string text = "Player ";
text.push_back(i + '0');
cout << text;
You will see in console:
Player 4
You can use the following
int i = 4;
string text = "Player ";
text+=(i+'0');
cout << (text);
If using Windows/MFC, and need the string for more than immediate output try:
int i = 4;
CString strOutput;
strOutput.Format("Player %d", i);