I'm trying to figure out a way to print out a list of memory addresses stored in a file, where there will be 4 or so columns. So it'd print out 4 addresses, each one separated by a '\t', and then do a new line.
I wrote this and it works, except the problem is that once the addresses become 8 long, the tab just gets even wider so it looks bad.
cout << hex;
for (int i = 0; i < getSizeA(); i++) {
fread(&buffer, sizeof(uint32_t), 1, in);
if (i % 4) {
cout << "\t";
}
else {
cout << "\n";
}
cout << buffer;
}
cout << endl << dec;
It looks like this when it's 7 or less
and then the tabs get wider after they're 8 long:
I could probably just add another if statement for that, but it'd probably make my code even more ugly.
Is there a better way to do this than what I'm doing? Namely, a way to separate them using '\t'?
Related
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 2 months ago.
Improve this question
I did not write this code.
i'm on my 3rd day of coding in C++ and i'm having a hard time understanding how incremnent works in general.
int main()
{
int antal_ord {};
double medellangd {};
string kort_ord;
string langt_ord;
int min_length {100};
int max_length {};
string S;
cout << "Mata in en text:\n" << endl;
while (cin >> S)
{
if (S.length() > max_length)
{
max_length = S.length();
langt_ord = S;
}
if (S.length() < min_length)
{
min_length = S.length();
kort_ord = S;
}
medellangd+=S.length();
antal_ord++;
}
if (antal_ord == 0)
{
cout << "Inga ord matades in." << endl;
}
else {
medellangd = (medellangd / antal_ord);
round(medellangd);
cout << "Texten innehöll " << antal_ord << " ord." << endl;
cout << "Det kortaste ordet var " << '"' << kort_ord << '"' << " med "
<< kort_ord.length() << " tecken." << endl;
cout << "Det längsta ordet var " << '"' << langt_ord << '"' << " med "
<< langt_ord.length() << " tecken." << endl;
cout << "Medelordlängden var "<< fixed << setprecision(1) << medellangd << " tecken.";
}
return 0;
}
antal_ord is the variable for the amount of words written in this scenario.
In the line where it says "cout << "Texten innehöll " << antal_ord << " ord." << endl;" how does it know how many words have been written? The only time this variable is used before this line is when the variable gets incremented, but how does that let the variable know how many words have been written in total?
and also the .length command, does it basically just count the amount of letters written?
There's really nothing special going on here. Every time you read one word with cin >> S, you increment antal_ord by one. Since you started with zero words written and antal_ord==0, at the end antal_ord will equal the number of words read from cin.
Similarly, S.length() returns the number of letters currently in S. In your case, that is exactly the number of letters read from cin since you didn't chance S after reading. But if you did S += " some extra letters, then S.length() will of course change.
When you'll learn about most programming languages, you'll start off with basics: syntax, data types, declarations (vars + funcs as well as other possible concepts), loops, calls, math operations and other code-control techniques relevant to each programming language.
What you'll see about most (and I;ll try to "rewind" from the generalization I started with and back down to C/C++) is that you have the following type of math operation variations when it comes to addition (let's focus on this, as it's more on point with the question).
result in a separate variable, in our case b: b = a + 1;
result in the same variable: a += 1;
incrementing the value of the variable: a++;
Expanding on it:
In the first case, b will have its value overwritten and is dependent on a different values (in this case the value of a and 1). What you need to focus on here is that a is NOT changed.
In this case, a receives a new value and is incremented by the right-side-value, in our case 1. a is changed by adding one (not incrementing)
In our case, similar to #2, the value of 8a* is updated, but the incrementation is done by 1.
Apart from syntactic sugar or code style preference, the difference between each is also in the way the variables are assigned their values (more formally said, in the assembly code "underneath"). This topic is a lot more complicated for someone that started programming, but focusing on the question, the answer is simply that ++ increments the value by 1.
Also note that there is a difference in certain coding flows between ++a and a++. Mainly in loops. For ++a the value is set before executing the code, using the already incremented value in the code, while a++ uses the current value of a first, then increments it.
Try it like this:
int i = 0;
while (++i < 100)
{
std::cout << i << std::endl;
}
... versus...
int i = 0;
while (i++ < 100)
{
std::cout << i << std::endl;
}
Then count how many lines each case wrote.
There is also a small caveat you should be aware of, it's a bit more advanced, so it's just a little "FYI" for you. There are two C++ techniques called "function overloading" and "operator (re)definition". Let's focus on the second one. You could build your own data type (for example a struct or class) and implement your own operators that do something other than what their arithmetic counterparts do. You'll see this in iterator definitions. In that case ++ is not "actual value incrementation" (so it's not a math calculation), but rather switching to the next item in a list. Once you reach std::vector lessons you'll encounter that.
I am in need of assistance to create an vertical bar graph with required limitations of learning experience. Such as, using only the fundamental basics listed: if statement, boolean, loop, string, arithmetic and comparison operators. Basically giving an idea of how limited my experience is in the language for clarification. Now, I have completed this problem already but the output does not seem to look like a desirable graph in my opinion so this is why posting. I will provide the problem and valid code I used to complete this problem.
Write a program that provides the option of tallying up the results of a poll with 3 possible
values. The first input to the program is the poll question; the next three inputs are the possible
answers. The first answer is indicated by 1, the second by 2, the third by 3. The answers are
tallied until a 0 is entered. The program should then show the results of the poll—try making a
bar graph that shows the results properly scaled to fit on your screen no matter how many
results were entered.
#include<iostream>
int main()
{
bool poll = false;
int Tech = 0, Edu = 0, Agri = 0;
std::cout << "VOTING POLL" << std::endl;
std::cout << "----------------------------" << std::endl;
std::cout << "----------------------------" << std::endl;
while(!poll)
{
std::cout << "Of the year 2022, in the United States of America, what should be the top priority of our concerns?" << std::endl;
std::cout << " 1.Technology\n 2.Education\n 3.Agriculture" << std::endl;
std::cout << "\n";
int pollAnswer;
std::cin >> pollAnswer;
if(pollAnswer == 1)
{
Tech++;
}
else if(pollAnswer == 2)
{
Edu++;
}
else if(pollAnswer == 3)
{
Agri++;
}
else if(pollAnswer == 0)
{
poll = true;
}
else
{
std::cout << "\n" << "Invalid. Please choose an answer from the above listing." << std::endl;
}
}
std::cout << "Technology: ";
while(Tech > 0)
{
std::cout << "* ";
Tech--;
}
std::cout << std::endl;
std::cout << "Education: ";
while(Edu > 0)
{
std::cout << "# ";
Edu--;
}
std::cout << std::endl;
std::cout << "Agriculture: ";
while(Agri > 0)
{
std::cout << "| ";
Agri--;
}
}
using only the fundamental basics listed: if statement, boolean, loop, string, arithmetic and comparison operators.
Those are enough to write a sort of scanline algorithm:
Establish a maximum height for the bars and scale all the (three) values accordingly. This isn't mentioned in your requirements, but it seems better to avoid too high (or too low) bars.
for each line of output (you may initialize a loop variable row at max_height and decrease it down to 0):
print some spaces, so that you can add the labels after this loop.
if the value of the first scaled variable (say, Tech) is less than or equal to row, print a ' ' (a space) otherwise print the character chosen to represent that bar ('*', I think).
repeat for all the other bars and then add a '\n' (newline) to end this row.
Print the labels, like "Technology" and the likes, correctly spaced.
I'll leave all the details of the implementation to the reader.
I think the first thing to do would be to make sure all the labels take up the same amount of space, so the bars in the graph all start from the same location on the left.
The text suggests scaling the graph to fit the screen. To do that we probably want to take the largest of the three counts, and figure out what to multiply that by so it'll be close to (but not greater than) the screen width (e.g., 80 columns), then multiply all three values by that scale factor.
I wouldn't use spaces in the bars, so each bar would look more "solid".
Possible result:
Technology: ****************************************
Education: ##########################
Agriculture: ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
If you want vertical bars instead of horizontal, you'd typically do that by storing the characters into (for one possibility) a 2D array. Then when you're done creating the graph in that 2D array, you scan across the array "sideways" to print out its contents, and scan through the other direction "backwards", so your labels end up at the bottom of the screen. I'd start by filling the array with space characters, then write out the contents of the bars into the array. Then after that's one, you print it out to the screen.
I'm working on a midterm project for my coding class, and while I've gotten the majority of kinks worked out I'm struggling with comparing two string values and determining if they are equal or not. The strings in question are ANSWERKEYand studentAnswers. The former is a constant that the latter is compared to.
The code in question is as follows.
if (studentAnswers == ANSWERKEY)
{
percentScore = 100.0;
cout << "Score: " << percentScore << " % " << 'A' << endl;
}
else if (studentAnswers != ANSWERKEY)
{
int count = 0;
double answerCount = 0.0;
while (count < ANSWERKEY.length())
{
if (studentAnswers.substr(count, count+1) == ANSWERKEY.substr(count, count+1)
{
answerCount++;
count++;
}
else
{
cout << "Incorrect answer." << endl;
count++;
}
}
percentScore = ((answerCount) / (double)ANSWERKEY.length()) * 100.0;
cout << "Percent score is " << percentScore << "%" << endl;
}
The exact issue I'm facing is that I can't work out a better way to compare the strings. With the current method, the output is the following:
The intro to the code runs fine. Only when I get to checking the answers against the key, in this case "abcdefabcdefabcdefab", do I run into issues. Regardless of what characters are changed, the program marks roughly half of all characters as mismatching and drops the score down because of it.
I've thought of using a pair of arrays, but then I can't find a solution to setting up the array when some values of it are empty. If the student's answers are too short, e.g. only 15 characters long, I don't know how to compare the blank space, or even store it in the array.
Thank you for any help you can give.
First:
if (studentAnswers == ANSWERKEY)
{...}
else if (studentAnswers != ANSWERKEY)
{ ...}
looks like an overkill when comparing strings. And where is the else part ?
Second, this is risky. Read the IEE754 and articles about cancellation, or even SO:
double answerCount = 0.0;
...
answerCount++
Third:
You are checking character by character using substr. To me it feels like using a hammer to kill a bacteria.
studentAnswers.substr(count, count+1) == ANSWERKEY.substr(count, count+1)
Fourth:
What if studentAnswers is shorter than ANSWERKEY ?
Conclusion:
You need to clarify inputs/expected outputs and use the debugger to better understand what is happening during execution. Carefully check all your variables at each step fo your program.
I'm trying to make sure that the second column in the output is aligned and it seemed like setw would be the solution but not matter what I do the second column is always off. This is the output I get from the code below...
1> 123
10> 234
but I want it to be...
1> 123
10> 234
The only other thing I can think of is to actually get the number of digits of what the actual number of elements are and the index then do some sort of length calc from that. That seems like a lot of handling just to get the second column right aligned.
I also tried << right but since I'm printing line by line in a loop this won't make a difference
int main()
{
int array[2] = {123,234};
int array2[2] = {1, 10};
for(int i = 0; i < 2; i++){
cout << array2[i] << "> " << setw(4) << array[i] << endl;
}
return 0;
}
Using setw ():
You need to set width for the array2[i] element instead of the array[i] element to get the alignment you are looking for.
cout << setw (2) << array2[i] << "> " << array[i] << endl;
Alternative Method 1:
Use printf for formatted printing here.
printf ("%-2d> %4d\n", array2[i], array[i]);
%-2d - the -2 left aligns the integer with width 2.
%4d - the 4 right aligns the integer with width 4.
Alternative Method 2:
Use tabs, or the \t character.
cout << array2[i] << ">\t" << array[i] << endl;
The \t moves your cursor bar to the next tabstop and so you end up getting data aligned in columns like you need. I would not recommend that you use this method because tab widths are unpredictable.
Use a single '\t' character, it TABs automaticly the other column. Example:
for(int i = 0; i < 10; i++)
cout << "x=" << (rand()%10000000+2000)/30 << "\t\ty=" << rand()%2000 << endl;
The output was:
x=+231096 y=+1383
x=+154630 y=+777
x=+141344 y=+1793
x=+325416 y=+1386
x=+321447 y=+649
x=+16400 y=+362
x=+84068 y=+690
x=+250530 y=+1763
x=+12847 y=+540
x=+115257 y=+1172
NOTE: I'm using g++ with flag -std=c++11 for C++11, I don't know its affects results.
Hi I'm not sure if this is the right place to ask this question.
Anyway I have written this code to parse a molecule formula and split it into atoms and amount of each atoms.
For instance if I input "H2O" I will for the atom array get {"H", "O"} and in the amount array I will get {2, 1}. I haven't taken account for amount that is larger than 9, since I don't think there are molecule which can bind to something that is larger than 8.
Anyway I'm quite newbie, so I wonder if this piece of code can be made better?
string formula = "H2O";
int no, k = 0, a = 0;
string atom[10];
int amount[10];
bool flag = true;
stringstream ss(formula);
for(int i = 0; i < formula.size(); ++i)
{
no = atoi(&formula[i]);
if(no == 0 && (flag || islower(formula[i]) ) )
{
cout << "k = " << k << endl;
atom[k] += formula[i];
flag = false;
cout << "FOO1 " << atom[k] << endl;
amount[a] = 1;
}
else if(no != 0)
{
amount[a] = no;
cout << "FOO2 " << amount[a] << endl;
a++;
flag = true;
k++;
}
else
{
k++;
a++;
atom[k] = formula[i];
cout << "FOO3 " << atom[k] << endl;
amount[a] = 1;
flag = false;
}
cout << no << endl;
}
Have you considered an approach with regular expressions? Do you have access to Boost or TR1 regular expressions? An individual atom and its count can easily be represented as:
(after edits based on comments)
([A-Z][a-z]{0,2})([0-9]*)
Then you just need to repeatedly find this pattern in your input string and extract the different parts.
There are many potential improvements that could be made, of course. But as a newbie, I guess you only want the immediate ones. The first improvement is to change this from a program that has a hard coded formula to a program that reads a formula from the user. Then try testing yout program by inputting different formulae, and check that the output is correct.
What if you modified it to be like this algorithm? This would maybe be less code, but would definitely be more clear:
// while not at end of input
// gather an uppercase letter
// gather any lowercase letters
// gather any numbers
// set the element in your array
This could be implemented with 3 very simple loops inside of your main loop, and would make your intentions to future maintainers much more obvious.