I am running a C++ program to sort strings as numbers.
I am saving strings in a char array vector but want to sort numbers as numbers so I am converting number strings into long doubles by calling "tonum()" then converting them back to strings when I am done by calling "tostring()". I am calling "numstr()" strictly for readability and debugging. I convert numbers 0 through 7 and the 6th number across for each value changes every time I run it. In my actual program, the first 5 numbers also seem to change. How do I get consistent results for a long double so that I can properly sort long doubles in char arrays?
#include<iostream>
std::string::size_type sz;
//___________________________________________________
std::string tonum(std::string str)
{
const int len = sizeof(long double);
std::string out = "0000000000000000";
union
{
long double dbl;
char array[len];
};
try
{
dbl = stold(str);
}
catch(std::exception &err)
{
dbl = 0;
}
for (int i = 0; i < len; i++)
{
std::cout << (int)array[i] << "\n";
out[len-i-1] = array[i];
}
return(out);
}
//___________________________________________________
std::string fromnum(std::string str)
{
const int len = sizeof(long double);
std::string out = "";
union
{
long double dbl;
char array[len];
};
for (int i = 0; i < len; i++)
{
array[len-i-1] = str[i];
}
out = std::to_string(dbl);
return(out);
}
//_____________________________________________________
std::string numstr(std::string str)
{
std::string out = fromnum(str) + ":";
for (int i = 0; i < str.length(); i++)
{
std::string look = std::to_string(str[i]);
int lookint = stold(look,&sz);
if (lookint < 0) lookint += 256;
std::string look2 = std::to_string(lookint);
out += look2 + " ";
}
return(out);
}
//_____________________________________________________
int main()
{
std::cout << numstr(tonum("0")) << "\n";
std::cout << numstr(tonum("1")) << "\n";
std::cout << numstr(tonum("2")) << "\n";
std::cout << numstr(tonum("3")) << "\n";
std::cout << numstr(tonum("4")) << "\n";
std::cout << numstr(tonum("5")) << "\n";
std::cout << numstr(tonum("6")) << "\n";
std::cout << numstr(tonum("7")) << "\n";
}
//_____________________________________________________
Related
I'm a student, learning pointers for the first time. My assignment doesn't allow the use of string classes and should be using pointer notation to access all elements within an array (no []).
Why am I not able to access an array inside of a struct via pointers? Is my syntax off?
#include <iostream>
using namespace std;
struct person
{
int favNums[4];
};
// Notation works here
void strCopy(char *from, char *to, int len)
{
for (int i = 0; i < len; i++)
{
*(to + i) = *(from + i);
}
}
// But doesn't work here
void sayNumsPointerNotation(person peep)
{
for (int i = 0; i < 4; i++)
{
//cout << peep.*(favNums + i) << endl;
}
}
// Would like to accomplish this.
void sayNums(person peep)
{
for (int i = 0; i < 4; i++)
{
cout << peep.favNums[i] << endl;
}
}
int main()
{
// Array outside of struct
char from[5] = "Word";
char to[5];
strCopy(from, to, 5);
cout << to << endl << endl;
// Array inside of struct non-pointer
person peep;
peep.favNums[0] = 0;
peep.favNums[1] = 1;
peep.favNums[2] = 2;
peep.favNums[3] = 3;
sayNums(peep);
cout << endl;
sayNumsPointerNotation(peep);
cout << endl;
}
This should work, hopefully you understand what was wrong.
#include <iostream>
using namespace std;
struct person
{
int favNums[4];
};
// Notation works here
void strCopy(char *from, char *to, int len)
{
for (int i = 0; i < len; i++)
{
*(to + i) = *(from + i);
}
}
// But doesn't work here (now it works)
void sayNumsPointerNotation(person* peep)
{
for (int i = 0; i < 4; i++)
{
cout << *(peep->favNums + i) << endl;
}
}
// Would like to accomplish this.
void sayNums(person peep)
{
for (int i = 0; i < 4; i++)
{
cout << peep.favNums[i] << endl;
}
}
int main()
{
// Array outside of struct
char from[5] = "Word";
char to[5];
strCopy(from, to, 5);
cout << to << endl << endl;
// Array inside of struct non-pointer
person peep;
peep.favNums[0] = 0;
peep.favNums[1] = 1;
peep.favNums[2] = 2;
peep.favNums[3] = 3;
sayNums(peep);
cout << endl;
sayNumsPointerNotation(&peep);
cout << endl;
}
Instead of
cout << peep.*(favNums + i) << endl;
Try this:
cout << *(peep.favNums + i) << endl;
Use
cout << *(peep.favNums + i) << endl;
.*, on the other hand, is a "member pointer", and means something different.
For self-study, here there are my 2 version of strncat (one with pointer+offset notation and one array version):
// 08_38.cpp
#include <iostream>
#include <cstring>
char * strncatPtr(char * a, char * b, size_t n);
char * strncatArr(char * a, char * b, size_t n);
int main (void) {
char string1[20] = "foobarqwerty";
char string2[20] = "asd";
// strncat
std::cout << "-----------------------" << std::endl;
std::cout << "--------STRNCAT--------" << std::endl;
std::cout << "-----------------------" << std::endl;
std::cout << strncat(string2, string1, 6) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatPtr(string2, string1, 4) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
std::cout << strncatArr(string2, string1, 3) << std::endl;
std::cout << strcpy(string2, "asd") << std::endl;
return 0;
}
// ------------------------------------
char * strncatPtr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; *(a+i) != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((*(a+i+j) = *(b+j)) != '\0') && (j < n-1);
j++);
return a;
}
char * strncatArr(char * a, char * b, size_t n){
unsigned int i = 0;
// go to the end;
for(; a[i] != '\0'; i++);
// and start copying
for(unsigned int j = 0;
((a[i+j] = b[j]) != '\0') && (j < n-1);
j++);
return a;
}
I don't get why when i test them it considers size = 6 for every function call
-----------------------
--------STRNCAT--------
-----------------------
asdfoobar
asd
asdfoobar
asd
asdfoobar
asd
but if i test them separately, by commenting 2 different calls each time, they works fine... could you please enlighten me?
If the number of chars copied is less then the length of the string being concatenated then you are not adding a null-terminator to indicate the end of the string.
I've been messing with OpenGL and c++ lately (with FreeGLUT and GLEW) and started to try and import .obj files from 3DS Max 2014. Everything is fine if i manual type the vertices and indices but, when trying to get them from a file i get strange numbers.
when getting the indices instead of 1 there was 1000 and instead of 3 there was 3965 and when there was a 12 is was 1212 (there are ones and threes etc but sometimes they are random)
Here is the code I use to import: http://pastebin.com/1ds6fgj9
or
std::vector<std::string> Object::split(std::string str, char splitter){
char charText[1000];
int number = 0;
int numberOfWords = 0;
char current[10][100];
std::vector<std::string> tokens;
strcpy(charText, str.c_str());
int size = sizeof(charText) / sizeof(*charText);
//std::cout << size << " size\n";
for (int i = 0; i < splitter; i++){
if (charText[i] == splitter){
tokens.push_back(current[numberOfWords]);
numberOfWords++;
number = 0;
}
else{
current[numberOfWords][number] = charText[i];
number++;
}
}
return tokens;
}
Object::Object(std::string fileName, Vector3f pos, Vector3f rot, float Size, Vector3f color){
Position = pos;
Rotation = rot;
size = Size;
colors = color;
std::string data;
std::ifstream file(fileName);
std::string line;
Vector3f _verts[1024];
int noVerts = 0;
unsigned int _inds[1024];
int noIndices = 0;
while (getline(file, line)) // same as: while (getline( myfile, line ).good())
{
char charText[1024];
strcpy(charText, line.c_str());
if (charText[0] == 'v' && charText[1] != 'n' && charText[1] != 't'){
std::vector<std::string> splitLine = split(line, ' ');
_verts[noVerts] = Vector3f(atoi(splitLine[1].c_str()), atoi(splitLine[2].c_str()), atoi(splitLine[3].c_str()));
//std::cout << "Vertices Number:" << noVerts << " x:" << _verts[noVerts].getX() << " y:" << _verts[noVerts].getY() << " z:" << _verts[noVerts].getZ() << "\n";
noVerts++;
}
if (charText[0] == 'f'){
std::vector<std::string> splitLine = split(line, ' ');
for (int i = 0; i < 3; i++){
std::vector<std::string> ssl = split(splitLine[i+1], '/');
//std::cout << atoi(splitLine[i].c_str()) << "\n";
std::cout << i << ": " << atoi(ssl[0].c_str()) << " " << atoi(ssl[1].c_str()) << " " << atoi(ssl[2].c_str()) << "\n";
_inds[noIndices] = atoi(ssl[0].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[1].c_str());
noIndices++;
_inds[noIndices] = atoi(ssl[2].c_str());
noIndices++;
//std::cout << "number of indices:" << noIndices<< "\n";
}
}
}
verts = _verts;
inds = _inds;
SizeV = sizeof(verts);
SizeI = sizeof(inds);
noPoints = SizeI / sizeof(*inds);
length = SizeV / sizeof(*verts);
Matrix4f posM, rotM, sizeM;
sizeM.InitScaleTransform(size, size, size);
rotM.InitRotateTransform(rot.getX(), rot.getY(), rot.getZ());
posM.InitTranslationTransform(pos.getX(), pos.getY(), pos.getZ());
M = posM * rotM * sizeM;
for (unsigned int i = 0; i < length; i++){
verts[i] = _verts[i];
}
}
I think it is an error in my code when reading the file but if not just ask to see my other code.
[EDIT]
It does this for all obj files (not tried exporting with a different program and the obj files I have tried have very few faces).
This is a part of a program that I am writing to compute the addition of two integers as strings. (Writing my own bigInt class).
There appears to be a problem when I am adding the two integers together. Because they are both in vectors of char type, I had to add a '0' to each element of the vector before concatenating it into a string.
However, the results are still not what I am expecting:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string const Number = "1000";
string const Number2 = "1000";
vector<char> reverse;
vector<char> reverse2;
//cout << (rostrNumber[1] - '0') << endl;
cout << "Original Number: " << Number << endl;
reverse.clear();
for (int i = Number.size() - 1; i >= 0; i--)
{
reverse.push_back(Number[i]);
}
cout << "Reversed: " << endl;
cout << reverse[0] << reverse[1] << reverse[2] << reverse[3] << endl;
cout << endl << endl;
reverse2.clear();
{
for (int i = Number2.size() - 1; i >= 0; i--)
{
reverse2.push_back(Number[i]);
}
}
cout << "Adding these two integers" << endl;
vector<char> const rcvN1 = reverse;
vector<char> const rcvN2 = reverse2;
vector<char> Results;
Results.clear();
//Local copies
vector<char> vN1 = rcvN1;
vector<char> vN2 = rcvN2;
int iSize1 = vN1.size();
int iSize2 = vN2.size();
int i, iSize = iSize2;
int iC = 0, iR;
for (i = 0; i<iSize; i++)
{
iR = vN1[i] + vN2[i] + iC;
if (iR > 9)
{
iR -= 10;
iC = 1;
}
else
iC = 0;
Results.push_back(iR);
cout << Results[0] << endl;
}
if (iC > 0)
Results.push_back(iC);
string ostr;
vector<char>::const_reverse_iterator rIter = Results.rbegin();
for (; rIter != Results.rend(); rIter++)
ostr += *rIter +'0';
cout << "Results: " << ostr << endl;
system("PAUSE");
return 0;
}
I want to convert an int to a string so can cout it. This code is not working as expected:
for (int i = 1; i<1000000, i++;)
{
cout << "testing: " + i;
}
You should do this in the following way -
for (int i = 1; i<1000000, i++;)
{
cout << "testing: "<<i<<endl;
}
The << operator will take care of printing the values appropriately.
If you still want to know how to convert an integer to string, then the following is the way to do it using the stringstream -
#include <iostream>
#include <sstream>
using namespace std;
int main()
{
int number = 123;
stringstream ss;
ss << number;
cout << ss.str() << endl;
return 0;
}
Use std::stringstream as:
for (int i = 1; i<1000000, i++;)
{
std::stringstream ss("testing: ");
ss << i;
std::string s = ss.str();
//do whatever you want to do with s
std::cout << s << std::endl; //prints it to output stream
}
But if you just want to print it to output stream, then you don't even need that. You can simply do this:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing : " << i;
}
Do this instead:
for (int i = 1; i<1000000, i++;)
{
std::cout << "testing: " << i << std::endl;
}
The implementation of << operator will do the necessary conversion before printing it out. Use "endl", so each statement will print a separate line.