How can I get a hex value in c++ to a proper string? - c++

I am still working on a database for movies and I would like to show the user what he has input to the file.
However when i use cout << lisafilm << it provides me with hex value. Therefore, I need to conver hex to string.
Snippet of trouble.
void sisend()
{
string nimi;
int aasta;
long int hinne;
string vaadatud;
ofstream lisafilm("andmebaas.txt", ios::app);
cout <<"Sisestage filmi nimi." << endl;
cin >> nimi;
cout << "Sisestage filmi aasta." << endl;
cin >> aasta;
cout << "Sisestage filmi hinne." << endl;
cin >> hinne;
cout << "Kas olete filmi juba vaadanud?" << endl;
cout << "Vastake 'Jah' voi 'Ei'" << endl;
cin >> vaadatud;
lisafilm<< nimi << " " << aasta << " " << hinne<< " " << vaadatud << endl;
lisafilm.close();
{
system("CLS");
int hex_str = lisafilm ;
cout << "Aitah kasutamast andmebaasi." << endl;
system("pause");
cin.get ();
}
main();
}

when i use cout << lisafilm it provides me with hex value
This is because you are trying to output an ofstream. When this happens, operator void* gets called, producing an arbitrary hex sequence which is tied to your stream, but ultimately is very much useless.

Try this:
std::stringstream ss;
ss << std::hex << lisafilm;
const std::string s = ss.str();

lisafilm is a stream, not a string
If you want to copy lisafilm to cout something like cout << lisafilm.rdbuf(); would do the trick (assuming that lisafilm is an ostream or istream and that lisafilm's position is the start of the file.
Your code is very poorly formatted, I don't think what you posted would compile. If you clean it up stackoverflow may be able to help you more.

Related

Infinite loop reading file into array

I have an infinite loop while trying to read a file. File is saved from user input, then it is to be read, finally, displayed using a separate function.
Here is my read function. The loop is not finding the eof(); from the file. I can't see what the issue is. No compiler errors.
void read(HouseholdItems items[AMOUNT], fstream& myFile, fstream& yourFile)
{
myFile.open("insured.dat", ios::in | ios::binary); // Open myFile
yourFile.open("uninsured.dat", ios::in | ios::binary); // Open yourFile
for(int i = 0; i < AMOUNT; i++)
{
myFile.read(reinterpret_cast <char*>(&items[i]),sizeof(&items[i]));
yourFile.read(reinterpret_cast <char*>(&items[i]),sizeof(&items[i]));
for(i = 0; i < AMOUNT; i++)
{
while (myFile)
{
cout << "description: ";
cout << items[i].description << endl;
cout << "quantity: ";
cout << items[i].quantity << endl;
cout << "price: ";
cout << items[i].price << endl;
cout << "insured: ";
cout << items[i].insured << endl;
}
}
}
myFile.close();
yourFile.close();
}
The following loop can never end : no modification is made to myFile inside its body :
while (myFile)
{
cout << "description: ";
cout << items[i].description << endl;
cout << "quantity: ";
cout << items[i].quantity << endl;
cout << "price: ";
cout << items[i].price << endl;
cout << "insured: ";
cout << items[i].insured << endl;
}
You have to read the file inside the while loop for it to end.
Besides, you most likely have a variable name conflict: you have two for loops that use the same variable i ; which is presumably not what you want.
Your problem is while(myFile), since nothing about myFile changes in that loop. It isn't clear what it is you mean for that loop to accomplish, so I can't say what to replace it with. (It does seem problematic that you have nested for loops, but don't seem to have a table of data.)
The answers by #ScottHunter and #Ekelog already answer the real problem. The following are peripheral problems.
These lines are not right:
myFile.read(reinterpret_cast <char*>(&items[i]),sizeof(&items[i]));
yourFile.read(reinterpret_cast <char*>(&items[i]),sizeof(&items[i]));
You need to use:
myFile.read(reinterpret_cast <char*>(&items[i]),sizeof(items[i]));
// ^^ Drop the &
yourFile.read(reinterpret_cast <char*>(&items[i]),sizeof(items[i]));
// ^^ Drop the &
try this in while
while (!myFile.eof())
{
cout << "description: ";
cout << items[i].description << endl;
cout << "quantity: ";
cout << items[i].quantity << endl;
cout << "price: ";
cout << items[i].price << endl;
cout << "insured: ";
cout << items[i].insured << endl;
}
See inline comments:
void read(HouseholdItems items[AMOUNT], fstream& myFile, fstream& yourFile)
{
// since you open and close those files here, you probably
// want to declare them here instead as a function parameter
myFile.open("insured.dat", ios::in | ios::binary); // Open myFile
yourFile.open("uninsured.dat", ios::in | ios::binary); // Open yourFile
// test in the loop
for(int i = 0; i < AMOUNT && myFile && yourFile; i++)
{
// these two reads do not make sense, the second one
// will overwrite the data just read by the first one...
// maybe you meant that one of the file might be smaller?
// or maybe to compare the results in some ways (in which
// case you need two arrays)
myFile.read(reinterpret_cast <char*>(&items[i]),sizeof(items[i]));
yourFile.read(reinterpret_cast <char*>(&items[i]),sizeof(items[i]));
// write current result
cout << "description: ";
cout << items[i].description << endl;
cout << "quantity: ";
cout << items[i].quantity << endl;
cout << "price: ";
cout << items[i].price << endl;
cout << "insured: ";
cout << items[i].insured << endl;
}
myFile.close();
yourFile.close();
}
As a side note:
Your second for() loop reused the i variable which means it would not work at all as expected.
As pointed out by others the sizeof() was wrong, you could also use sizeof(items[0]) since all items are equal in size.
As mentioned by SamIAm, the while() was blocking because the file was not being read so the EOF never actually reached in the file.
As shown in the comments, the file objects should probably be defined in the function instead of outside and passed in as references.

Check for non-numeric inputs in a C++ program

How do you check for non-numeric input using C++? I am using cin to read in a float value, and I want to check if non-numerical input is entered via stdin. I have tried to use scanf using the %d designator, but my output was corrupted. When using cin, I get the correct format, but when I enter, a string such as "dsffsw", I get an infinite loop.
The commented code was my attempt to capture the float, and type cast it as string, and check if it is a valid float, but the check always comes up false.
I have tried using other methods I have found on the message boards, but they want to use scanf in C and not cin in C++. How do you do this in C++? Or in C if it is not feasible.
while (!flag) {
cout << "Enter amount:" << endl;
cin >> amount;
cout << "BEGIN The amount you entered is: " << strtod(&end,&pend) << endl;
//if (!strtod(((const char *)&amount), NULL)) {
// cout << "This is not a float!" << endl;
// cout << "i = " << strtod(((const char *)&amount), NULL) << endl;
// //amount = 0.0;
//}
change = (int) ceil(amount * 100);
cout << "change = " << change << endl;
cout << "100s= " << change/100 << endl;
change %= 100;
cout << "25s= " << change/25 << endl;
change %= 25;
cout << "10s= " << change/10 << endl;
change %= 10;
cout << "5s= " << change/5 << endl;
change %= 5;
cout << "1s= " << change << endl;
cout << "END The amount you entered is: " << amount << endl;
}
return 0;
}
int amount;
cout << "Enter amount:" << endl;
while(!(cin >> amount)) {
string garbage;
cin.clear();
getline(cin,garbage);
cout << "Invalid amount. "
<< "Enter Numeric value for amount:" << endl;
}
I think you task relates to the so called defensive programming, one of it`s ideas is to prevent situations like one you described (function expects one type and user enters another).
I offer you to judge whether input is correct using method that returns stream state , which is good(),
so I think it will look something like this:
int amount = 0;
while (cin.good()) {
cout << "Enter amount:" << endl;
cin >> amount;

Ofstream not creating a new file correctly

I've tried to write a simple database program. The problem is that ofstream does NOT want to make a new file.
Here's an extract from the offending code.
void newd()
{
string name, extension, location, fname;
cout << "Input the filename for the new database (no extension, and no backslashes)." << endl << "> ";
getline(cin, name);
cout << endl << "The extension (no dot). If no extension is added, the default is .cla ." << endl << "> ";
getline(cin, extension);
cout << endl << "The full directory (double backslashes). Enter q to quit." << endl << "Also, just fyi, this will overwrite any files that are already there." << endl << "> ";
getline(cin, location);
cout << endl;
if (extension == "")
{
extension = "cla";
}
if (location == "q")
{
}
else
{
fname = location + name + "." + extension;
cout << fname << endl;
ofstream writeDB(fname);
int n = 1; //setting a throwaway inteher
string tmpField, tmpEntry; //temp variable for newest field, entry
for(;;)
{
cout << "Input the name of the " << n << "th field. If you don't want any more, press enter." << endl;
getline(cin, tmpField);
if (tmpField == "")
{
break;
}
n++;
writeDB << tmpField << ": |";
int j = 1; //another one
for (;;)
{
cout << "Enter the name of the " << j++ << "th entry for " << tmpField << "." << endl << "If you don't want any more, press enter." << endl;
getline(cin, tmpEntry);
if (tmpEntry == "")
{
break;
}
writeDB << " " << tmpEntry << " |";
}
writeDB << "¬";
}
cout << "Finished writing database. If you want to edit it, open it." << endl;
}
}
EDIT: OK, just tried
#include <fstream>
using namespace std;
int main()
{
ofstream writeDB ("C:\\test.cla");
writeDB << "test";
writeDB.close();
return 0;
}
and that didn't work, so it is access permission problems.
ofstream writeDB(fname); //-> replace fname with fname.c_str()
If you lookup the documentation of the ofstream constructor, you will see something like:
explicit ofstream ( const char * filename, ios_base::openmode mode = ios_base::out );
The second argument is optional, but the first one is a const char*, and not a string. To solve this problem the most simple way is to convert your string to something called a C-string (char*, which is basically an array of chars); to do that just use c_str() (it«s part of the library).
Other than that, you could just place the information directly on a C-str, and then pass it normally to the ofstream constructor.

Seemingly simple issue with calling information from an array in C++

This seems like it should be easy, which is why it is driving me especially insane. Hopefully someone out there will see the problem right off. I'm just trying to build arrays from an array built from a user input. It seems to create an array that is bigger than the one I meant for it to. Here's the program:
int main()
{
ifstream inFile;
ofstream outFile;
int numReq, fileSize;
string lang, dash;
char fileName[40];
char confirm[10];
char confirm2[10];
int character;
char year[3];
char month[1];
char day[1];
char hour[1];
cout << "What file to process?" << endl;
cin >> fileName;
year[0] = fileName[14];
year[1] = fileName[15];
year[2] = fileName[16];
year[3] = fileName[17];
cout << "year = " << year << "." << endl;
month[0] = fileName[18];
month[1] = fileName[19];
cout << "month = " << month << "." << endl;
cout << "so I gotta know, what is..." << endl;
cout << "month[0]? " << month[0] << endl;
cout << "month[1]? " << month[1] << endl;
cout << "month[2]? " << month[2] << endl;
cout << "month[3]? " << month[3] << endl;
cout << "month[4]? " << month[4] << endl;
cout << "month[5]? " << month[5] << endl;
cout << "month[6]? " << month[6] << endl;
day[0] = fileName[20];
day[1] = fileName[21];
cout << "day = " << day << "." << endl;
hour[0] = fileName[23];
hour[1] = fileName[24];
cout << "hour = " << hour << "." << endl;
cout << "so, 'fileName[23]' is = " << fileName[23] << "?" << endl;
cin >> confirm;
cout << "So, the year is " << year << ", the month is " << month
<< ", the day is " << day << ", the hour is " << hour << "?" << endl;
cin >> confirm;
//cout << "Is this what you chose? " << fileName << endl;
//cin >> confirm;
//cout << "Which character to manipulate?" << endl;
//cin >> character;
//cout << "This one? " << fileName[character] << endl;
//cin >> confirm2;
inFile.open(fileName);
assert (!inFile.fail());
outFile.open("revisedPracticeFile1.txt");
outFile << fixed << showpoint; // I have no idea what this is...
outFile << setprecision(2); // .. or this for that matter.
cout << "Processing data" << endl;
inFile >> lang;
while (!inFile.eof() ){
if (lang.length() <= 2){
outFile << lang << " ";
// I should keep in mind, that, for whatever reason, it seemed like the
//item 'setw(6)' made the program work when I put it in, but didn't seem
//to make the program stop working when I took it out. Curious..
inFile >> dash >> numReq >> fileSize;
outFile << numReq << " " << fileSize << endl;
}
else{
inFile >> dash >> numReq >> fileSize;
cout << "took out " << lang << " " << numReq << " " << fileSize << endl;
}
inFile >> lang;
}
inFile.close();
//assert(!inFile.fail());
outFile.close();
return 0;
}
...And, this is what happens when I run the program:
What file to process?
projectcounts-20090101-010000
year = 2009.
month = 01009.
so I gotta know, what is...
month[0]? 0
month[1]? 1
month[2]? 0
month[3]? 0
month[4]? 9
month[5]?
month[6]?
day = 011009.
hour = 0111009.
so, 'fileName[23]' is = 0?
yes
So, the year is 1009, the month is 11009, the day is 111009, the hour is 0111009?
^C
... So what gives?
The syntax char year[3]; declares an array with 3 element. But, then you use it to store 4 elements. There are similar issues with your other arrays.
Also, you're using char arrays as strings. That's a C (not C++) way to do things. Of course you're allowed to do this if you want. But, these c-style strings use the convention that the last item is a zero.
Thus, if you wanted a C-style string to store the work 'foo', you could do it like this
char string[10]; // anything bigger than 3 works
string[0] = 'f';
string[1] = 'o';
string[2] = 'o';
string[3] = '\0'; // this zero tells functions like `printf` that the string has ended.
Without that last zero, functions like printf will just keep outputting memory locations until it happens upon a zero somewhere.
EDIT: Consider using c++ std::string for your string processing.

C++ doesn't convert string from data

I want to write a little program which should be used in supermarkets. everything is fictitious and it's only for learning purposes.
However, The tool generate a new data for every new article. in the data there are 2 lines, the name and the prise.
The data is named as the article number of the product. So the user enter a articlenumber and the tool looks for a data with this number, if it found it, it reads the 2 lines and initiates the variables.
But for some reasons it does not convert and copy the strings correctly.
here is the part which loads the data.
int ware::load()
{
string inhalt;
cout << "please insert article number" << endl;
cin >> articlenumber;
productname.open(articlenumber, ios::in);
if (!productname.is_open())
{
cout << "can't find the product." << endl;
return 1;
}
if (productname.is_open())
{
while (!productname.eof())
{
getline(productname, inhalt);
strcpy(name,inhalt.c_str());
getline(productname, inhalt);
price = atoi (inhalt.c_str());
cout << inhalt << endl;
}
warenname.close();
}
cout << endl << endl <<
"number: " << inhalt <<
" preis: " << price <<
" name: " << name <<
endl << endl; //this is a test and will be deleted in the final
}
hope you can help me!
Here is the class:
class ware{
private:
char articlenumber[9];
char name[20];
int price;
fstream warennamefstream;
ifstream warenname;
public:
void newarticle(); //this to make a new product.
void scan(); //this to 'scan' a product (entering the article number ;D)
void output(); //later to output a bill
int load(); //load the datas.
};
hope everything is fine now.
First, you have a using namespace std; somewhere in your code. This occasionally leads to subtle bugs. Delete it. ( Using std Namespace )
int ware::load()
{
string inhalt;
cout << "please insert article number" << endl;
cin >> articlenumber;
The type of articlenumber is incorrect. Declare it std::string, not char[]. ( What is a buffer overflow and how do I cause one? )
productname.open(articlenumber, ios::in);
There is no reason to have an ifstream lying around waiting to be used. Also, there is no point in providing ios::in -- it is the default. Just use the one-argument form of the ifstream constructor.
if (!productname.is_open())
{
cout << "can't find the product." << endl;
return 1;
}
Don't bother checking to see if the file opened. Your users don't care if the file was present or not, they care whether the file was present AND you retrieved the essential data.
if (productname.is_open())
{
while (!productname.eof())
{
getline(productname, inhalt);
strcpy(name,inhalt.c_str());
getline(productname, inhalt);
price = atoi (inhalt.c_str());
cout << inhalt << endl;
}
warenname.close();
}
This loop is just wrong.
Never invoke eof(). It doesn't do what you think it does, and will cause bugs.
Why is this a loop? Aren't there only two lines in the file?
There is no point in calling close. Just let the file close when the istream goes out of scope.
Why is warename different than productname?
Don't store your data in char[]. This is the 21st century. Use std::string.
.
cout << endl << endl <<
"number: " << inhalt <<
" preis: " << price <<
" name: " << name <<
endl << endl; //this is a test and will be deleted in the final
Never use endl when you mean to say '\n'. Each of those endl manipulators invokes flush, which can be very expensive. ( What is the C++ iostream endl fiasco? )
You forgot to return a value.
Try this instead:
int ware::load()
{
// This declaration should be local
std::string articlenumber;
cout << "please insert article number" << endl;
cin >> articlenumber;
// This declaration should be local
std::ifstream productname(articlenumber.c_str());
// These declarations can be class members:
std::string name;
int price;
std::string number;
if(getline(productname, name) &&
productname>>price &&
productname>>number)
{
cout << "\n\n" <<
"number: " number <<
" preis: " << price <<
" name: " << name <<
"\n\n"; //this is a test and will be deleted in the final
return 0;
} else {
cout << "can't find the product." << endl;
return 1;
}
}