C++ fstream keep reading the same first 5 lines? - c++

I'm really frustrated. I'm trying to read a txt file which has the following content:
Arenas
Edward
239924731
2525976612
Autry
Richard
527646269
6028236739
Using this code :
#include <iostream>
#include <fstream>
#include <sstream>
using namespace std;
int main(int argc, const char * argv[])
{
string line;
string last, first;
int uin, number;
ifstream phoneBook;
phoneBook.open("PhoneBook.txt");
while (!phoneBook.eof()) {
phoneBook >> last >> first >> uin >> number;
cout << last << ", " << first << ", " << uin << ", " << number <<endl;
}
return 0;
}
The output would be the same contact endlessly
Arenas, Edward, 239924731, 2147483647
Arenas, Edward, 239924731, 2147483647
Arenas, Edward, 239924731, 2147483647
Arenas, Edward, 239924731, 2147483647
Arenas, Edward, 239924731, 2147483647
I also tried this version of while loop:
while (phoneBook >> last >> first >> uin >> number) {
cout << last << ", " << first << ", " << uin << ", " << number <<endl;
}
For some reasons, the compiler doesn't even step into the loop. It would just jump to return 0;

Your number values are too big to fit into a four-byte signed integer. Maximum value for that is 2147483647 (2^31 - 1), which is why you get that printing out at the end. (You weren't asking about that issue; I don't know how I noticed it myself!)
But what I'm also wondering about is that extra line that you have in between each record. I found this question that discusses fstreams and delimiters. I wonder if it's getting stuck at the blank line, reading nothing, and then just outputting the same values of last, first, uin, and number.

There may be a different type of error. The best method to use is ios::good:
while (!phoneBook.good()) {

Related

Stringing together multiples of the same string (an asterisk) determined by an input file. C++

Essentially, the objective is to read an input file (hence inFile and inFileName) and output a population growth with asterisks representing each 1000 people using an ID (ex. 1375892), going from the year 1900 to 2020 in 20-year increments.
So, 1 asterisk for 1000 people, 3 asterisks for 3000 people, etc. The input file has numbers like 5000 and 7000 that I need to use to calculate the number of asterisks I need (by dividing by 1000). Even with that, I'm trying to figure out the final step in converting asteriskNum (the number of asterisks I need to use) and have it output the string of asterisks, not an integer of how many asterisks I need.
I definitely know I'm missing SOMETHING, but even after asking my teacher and scouring through my textbook and notes, I can't figure out how to solve this specific issue.
#include<iostream>
#include<iomanip>
#include<string>
#include<fstream>
using namespace std;
int main(){
string asterisk = "*";
string firstName;
int PopNum{0};
int year{1900};
int asteriskNum{};
const string INTROLINE{"POPULATION GROWTH \n(each * represents 1000 people)"};
cout << INTROLINE << "\n";
string inFileName="DL8_L5_Morrison.txt";
ifstream inFile{inFileName};
if (inFile){
cout << inFileName << " opened for reading. \n";
inFile >> firstName;
while (not inFile.eof()){
inFile >> PopNum;
asteriskNum = PopNum/1000;
cout << year << " " << asteriskNum << " " << << "\n";
year+=20;
inFile.close();
}
else {
cout << inFileName << " did not open for reading. \n";}
cout<<"Goodbye!\n";
return EXIT_SUCCESS;
}
}
You can use a std::string object and use the constructor that takes a count and character as arguments (constructor version #2 here). This will work with an int for the count argument, but it is better to cast it to a size_t type (or just have the calculated value as a size_t in the first place):
//...
asteriskNum = PopNum/1000;
cout << year << " " << std::string(static_cast<size_t>(asteriskNum), '*') << std::endl;
//...

how to convert an ostringstream hex string character pairs to a single unit8_t equivalent binary value

I am trying to do the following:
I have an assembled ostringstream object that contains a hex payload to be transmitted. Say, it might be
03125412349876543210af (this is representing the data using hex convention in my string)
This string is representing 11 bytes, so for example the last byte to be transmitted is 0xaf (two characters giving me 8 bits of actual data).
I wish to read each pair of characters, for example the '03' pair of characters in the string and convert that into a uint8_t element which I will push onto a vector of uint8_t elements. Essentially I will create a new vector of uint8_t elements based on the contents of the string, then transmit the vector.
My test program below works OK for 'int' but does not give me what I want for uint8_t. Is there an elegant and/or straightforward way to do what I am trying to do that anyone can suggest?
(Note: example 3 was to see what happens if a non-hex-legal value was used. In example 1, a value like 34r0 would convert 34(hex) to an equivalent int and ignore the r and everything following it).
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
// example 1: making a hex string an int - works
std::stringstream str1;
std::string s1 = "5f";
str1 << s1;
int value1;
str1 >> std::hex >> value1;
cout << value1 << endl; // produces 95 - perfect
cout << "~~~~~~~~~" << endl;
// example 2: making a hex string a uint8 - not the result I want
std::stringstream str2;
std::string s2 = "5f";
str2 << s2;
uint8_t value2;
str2 >> std::hex >> value2;
cout << value2 << endl; // produces 5 - not what I want!
cout << "~~~~~~~~~~~" << endl;
// example 3: using non-hex values
std::stringstream str3;
std::string s3 = "wx";
str3 << s3;
uint8_t value3;
str3 >> std::hex >> value3;
cout << value3 << endl; // produces w - not what I want!
// this does not work either
uint8_t value4;
cout << "~~~~~~~~~~~~~~" << endl;
value4 = (uint8_t)value1;
cout << value4 << endl; // produces - - not what I want!
cout << "............." << endl;
return 0;
}
The output from this test program looks like the below:
Hello world!
95
~~~~~~~~~
5
~~~~~~~~~~~
w
~~~~~~~~~~~~~~
_
.............
Process returned 0 (0x0) execution time : 0.022 s
Press any key to continue.
Example 1 works OK, but using int - this is not what I need.
In example 2 you are extracting a uint8_t, 8 bits, so one char from the string, the 5.
In example 3 is the same, you extract the first char, so the w.
For the last example, it prints a char (8 bits), 95 is the ASCII - character. If you want to show the number, cast the value to int.
value4 = (uint8_t)value1;
cout << (int)value4 << endl;
Thanks to Manuel for his answer. This is one way to solve the problem. I'd still like to know if there is a more elegant way to do this.
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main()
{
cout << "Hello world!" << endl;
// example 1: making a hex string an int - works
std::stringstream str1;
std::string s1 = "5f";
str1 << s1;
int value1;
str1 >> std::hex >> value1;
cout << "value 1 as int: " << value1 << endl; // produces 95 int - OK but an int
uint8_t value2;
value2 = (uint8_t)value1;
cout << "value 2 as uint8: " << (int)value2 << endl; // produces 01011111 = 95 or '-' - correct
return 0;
}
Which produces:
Hello world!
value 1 as int: 95
value 2 as uint8: 95
Process returned 0 (0x0) execution time : 0.022 s
Press any key to continue.

Why is my output different from input? (C++)

Input : 7182933164
Output : 2147483647
(it isnt all of the code i know there are missing } )
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
string line;
ifstream file("Numbers.txt");
int num;
cout << "Enter credit card number : " << endl;
cin >> num;
cout << "enterned : " << num << endl;
Use std:: string to represent code numbers instead.
The value 7182933164 is such a huge number that it crosses the value of the integer it could holds (i.e. -2147483648 to 2147483647). Use long type modifier to accept such values. And if there's only positive integer required, added unsigned before long.
Do something like:
...
long num; // dependent upon the computer architecture
...
If that doesn't works, try long long. Although it's working fine in OnlineGDB (example).

Output shows no zero

FYI I'm a beginner in C++. This is just a part of the complete code, the problem is the 'student.id', if the input starts with '0' e.g.'06042010', the output shows no zero(in this case would be '6042010'! And the point is, I want that first zero to be shown. Thanks.
#include<iostream>
using namespace std;
struct students
{
char name[15];
char surname[10];
int id;
};
int main()
{
students student;
cout<<"Name: ";
cin>>student.name;
cout<<"Surname: ";
cin>>student.surname;
cout<<"ID: ";
cin>>student.id;
cout<<"\nStudent: "<<student.name<<" "<<student.surname<<" ID "<<student.id<<endl;
return 0;
}
If you need to preserve leading zeros, you should store id as a string and not an int.
If your IDs will always be a particular length, you can use C's printf function instead of streams, which gives you more power;
printf( "Student: %s %s ID %08d\n", student.name, student.surname, student.id );
That will always print 8 digits of ID, and will prefix with 0s as needed (if it was just %8d it would prefix with spaces).
But as already pointed out, you're likely better off storing it as a string, because then you will be able to increase the length of the IDs in the future without needing to adjust all the old IDs.
If you need or want to keep the student id a number for some reason you can also us the following:
#include <iomanip>
const int width = 8; //The length of your student ID numbers
cout << "\nStudent: " << student.name << " " <<student.surname
<< " ID " << setfill('0') << setw(width) << student.id << setfill(' ') << endl;
If your ID numbers are not all the same length you will have to detect how long they are and use the appropriate width in each setw() call.

Converting ascii substr to int

first year college having problem converting ascii into int.
The problem is this piece of code
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
When I run this on codeblocks at home it returns an incorrect value, when I run it again I get a different incorrect value.
When I run it at on Borlands at college, the screen just ups and disappears before I can read it, so I can't use the system clock here either.
It's Easter hols now so even though I'm at college, I can't annoy my tutors because they're not.
#include <iostream.h>
#include <conio.h>
#include <string>
//#include <time.h>
//#include <ctype.h>
using namespace std;
int main() {
bool q = false;
do {
// convert hours to minutes ... then total all the minutes
// multiply total minutes by $25.00/hr
// format (hh:mm:ss)
string theTime;
cout << "\t\tPlease enter time " << endl;
cout <<"\t\t";
cin >> theTime;
cout << "\t\t"<< theTime << "\n\n";
string hours = theTime.substr (0, 2);
cout <<"\t\t"<< hours << endl;
unsigned short ihours = (((hours[0]-48)*10 + (hours[1] -48))*60);
cout << "\t\t"<< ihours << endl;
string minutes = theTime.substr (3, 2);
cout <<"\t\t"<< minutes << endl;
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
cout << "\t\t" << iminutes << endl;
cout << "\n\n\t\tTotal Minutes " <<(ihours + iminutes);
cout << "\n\n\t\tTotal Value " <<(ihours + iminutes)*(25.00/60) << "\n\n";
}
while (!q);
cout << "\t\tPress any key to continue ...";
getch();
return 0;
}
You set minutes to be a substring of theTime. So minutes has 2 characters. The first one starting at position 0 within minutes.
So this
unsigned short iminutes = ((minutes[3]-48)*10) + (minutes[4]-48);
is wrong as it accesses characters 3 and 4 in minutes which don't exist, because minutes is only two characters long. It only has characters as positions 0 and 1.
should be this
unsigned short iminutes = ((minutes[0]-48)*10) + (minutes[1]-48);
or you could use this:
unsigned short iminutes = ((theTime[3]-48)*10) + (theTime[4]-48);
The problem is that even though you get the characters at position 3 and 4 from the original string, the new string is just two characters (i.e. only have index 0 and 1).
istringstream iss(theTime.substr(0, 2));
iss >> ihour;