The format of the file is:
ITEM: TIMESTEP
0
ITEM: NUMBER OF ATOMS
32768
ITEM: BOX BOUNDS pp pp ff
0.0000000000000000e+00 3.2000000000000000e+01
0.0000000000000000e+00 3.2000000000000000e+01
0.0000000000000000e+00 3.2000000000000000e+01
ITEM: ATOMS type x y z
1 0.292418 1.13983 1.28999
......
I read the header for each timestamp into a dummy string, and value of time step into an array. My code can read two timestamps correctly (65554 lines), but tellg() sets into -1 and I only get the last read values in my output. And also, the file never reaches EOF and my code continues for eternity.
#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv)
{
string f = argv[1];int ens=1;string file;
fstream xyz("readas.xyz",ios_base::out); //to write data to cross-check what I read
fstream* Pxyz = &xyz;
float x,y,z,type;
int* time = (int*) malloc(100*sizeof(int));
int step;
string dummy;
while(ens < atoi(argv[2])) //this is to open different files to read
{
file=f+to_string(ens);
cout<<"Reading "+file<<endl;
fstream fobj(file,ios_base::in);
fstream* f= &fobj; //reading from this file
if(f->is_open())
{
*time=0;step=0;
while(true)
{
*f>>dummy>>dummy;
if(f->fail())break;
*f>>*(time+(++step));
*Pxyz << "32768" << "\n" << *(time+step) << endl;
*f>>dummy>>dummy>>dummy>>dummy;
*f>>dummy;
*f>>dummy>>dummy>>dummy>>dummy>>dummy>>dummy;
*f>>dummy>>dummy;
*f>>dummy>>dummy;
*f>>dummy>>dummy;
*f>>dummy>>dummy>>dummy>>dummy>>dummy>>dummy;
for(int i=0;i<32768;i++)
{
*f>>type>>x>>y>>z;
*Pxyz <<f->tellg() << " " << *(time+step) << " " << i << " " << type << " " << x << " " << y << " " << z << " " <<endl;
}
}
f->close(); //closing this file
}
++ens;
}
return 0;
}
The point at which the problem starts:
tellg time i and other values
1754887 10 32766 2 31.3309 31.9485 31.6061
1754914 10 32767 1 31.6358 31.1965 30.9986
32768
10
-1 10 0 0 31.6358 31.1965 30.9986
-1 10 1 0 31.6358 31.1965 30.9986
.......
int gas;
// Input Code
int user_code;
std::cout << std::endl;
std::cout << "Please enter the Code: ";
std::cin >> user_code;
std::cout << "The value you entered is " << user_code;
std::cout << std::endl;
int array1[16] = { 42011, 42017, 42029, 42045,
42091, 42101, 34001, 34005,
34007, 34009, 34011, 34015,
34033, 10001, 10003, 24015 }; // 0.2387 (23.87%)
int array2[45] = { 11001, 24003, 24510, 24005, 24009,
24013, 24017, 24019, 24021, 24025,
24027, 24029, 24031, 24033, 24035,
24037, 24041, 24043, 51510, 51013,
51043, 51047, 51600, 51059, 51610,
51061, 51069, 51630, 51099, 51107,
51683, 51685, 51153, 51157, 51177,
51179, 51187, 51840, 54003, 54027,
54037, 54065, 42001, 42055, 42133 }; //0.2710 (27.10%)
int * array1_search;
array1_search = std::find(array1, array1+ 16, user_code);
int * array2_search;
array2_search = std::find(array2, array2 + 45, user_code);
if (array1_search != array1+ 16) {
std::cout << "Codefound in Array1: " << *array1_search << '\n';
gas= 0.2387;
}
else if (array2_search != array2_search + 45) {
std::cout << "Code found in Array2: " << *array2_search << '\n';
gas= 0.2710;
}
else {
std::cout << "Not found \n";
gas= 0.1506;
}
Above is my current code. I am trying to have the user input a variable user_code value and then iterate over the two arrays array1[16] and array2[45]. If the user input value is on the first array1 I want to assign gas 0.2387 and if the input value is on the other array2 I want to assign gas 0.2710, and if it is not within any array gas should be 0.1506.
So basically I want to assign a value depending on which array the user's input is contained in. I am very new to c++, what is the best way to go about this?
It seems to work fine if I enter a number that is within array1 or array2 and it correctly identifies that is found in array1 or array2. The problem is when I enter a number I know is not within either array to trigger the else statement it identifies it as being in array2. For example, when I enter 12345 as a user_code it says "Code found in Array2: 0". I know 12345 is not contained in array2 and I do not understand why *array2_search is assigned 0. What can I do to fix this so if a user_code is entered that is not contained within array1 or array2 it goes to the else statement?
else if (array2_search != array2_search + 45) {
Should be
else if (array2_search != array2 + 45) {
or better using std::end of C++11:
if (array1_search != std::end(array1)) {
else if (array2_search != std::end(array2)) {
And int gas; => double gas; if you want to be able to store floating point values, not just integers (0.2387 and 0.2710 would give integer 0).
Using standard containers and newer c++ features if you have C++11 minimum you can then do something like this:
int main() {
// Use Constants Instead of "Hard Coded Values"
// If you noticed these are not even needed.
// const unsigned code1 = 16;
// const unsigned code2 = 45;
// Made gas a float instead of an int due to the decimal values
// I also initialized it with the default value if the code is
// not found in either container.
float gas = 0.1506f; // Default Price If Not Found
// created your first array as a const std::vector<int> and
// used its initializer list to populate its contents: this vector
// can not be modified: remove the const if this container
// will need to have entries added in the future.
const std::vector<int> arr1 { 42011, 42017, 42029, 42045,
42091, 42101, 34001, 34005,
34007, 34009, 34011, 34015,
34033, 10001, 10003, 24015 }; // 0.2387 (23.87%)
// did the same for the second array
const std::vector<int> arr2 { 11001, 24003, 24510, 24005, 24009,
24013, 24017, 24019, 24021, 24025,
24027, 24029, 24031, 24033, 24035,
24037, 24041, 24043, 51510, 51013,
51043, 51047, 51600, 51059, 51610,
51061, 51069, 51630, 51099, 51107,
51683, 51685, 51153, 51157, 51177,
51179, 51187, 51840, 54003, 54027,
54037, 54065, 42001, 42055, 42133 }; //0.2710 (27.10%)
// No changes made here same basic user I/O.
int user_code = 0;
std::cout << "Please enter the Code: ";
std::cin >> user_code;
std::cout << "The value you entered is " << user_code;
std::cout << "\n";
// Created 2 flags for later.
bool b1found = false;
bool b2found = false;
// auto for loop ranged based.
for ( auto code : arr1 ) {
if ( code == user_code ) {
b1found = true; // Set flag
gas = 0.2387f; // Set new gas
// Output code & gas
std::cout << "Code found in Arr1: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
for ( auto code : arr2 ) {
if ( code == user_code ) {
b2found = true; // set flag
gas = 0.2710f; // set gas
// output code & gas
std::cout << "Code found in Arr2: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
// If code not found in either output "not found" and display default gas
if ( !b1found && !b2found ) {
std::cout << "Not found\n";
std::cout << "gas = " << gas << '\n';
}
std::cout << "\nPress any key and enter to quit." << std::endl;
char c;
std::cin >> c;
return 0;
}
You can even simplify this a little more by removing the two bool flags. We know that if a value is found in arr1 or arr2 that the gas value will be changed, So all we really have to do is check to see if it has been changed.
// auto for loop ranged based.
for ( auto code : arr1 ) {
if ( code == user_code ) {
gas = 0.2387f; // Set new gas
// Output code & gas
std::cout << "Code found in Arr1: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
for ( auto code : arr2 ) {
if ( code == user_code ) {
gas = 0.2710f; // set gas
// output code & gas
std::cout << "Code found in Arr2: " << code << '\n';
std::cout << "gas = " << gas << '\n';
}
}
const float defaultGas = 0.1506;
// If code not found in either output "not found" and display default gas
if ( gas == defaultGas ) {
std::cout << "Not found\n";
std::cout << "gas = " << gas << '\n';
}
Please do not try to modify the code. This code works fine.I took it from a book.I just need some help to understand the behavior of the code.
#include <iostream>
#include <ctime>
using namespace std;
void suffle2(int[][13]);
int main(){
int deck[4][13] = { 0 };
srand(time(0));
suffle2(deck);
return 0;
}
void suffle2(int d[4][13])
{
int row, column;
for (int card = 1; card <= 20; card++)
{
do{
row = rand() % 4;
column = rand() % 13;
cout << "d[" << row << "]" << "[" << column << "]" << "=" << d[row][column]<<endl;
} while (d[row][column] != 0);
d[row][column] = card;
cout << "d[" << row << "]" << "[" << column << "]" << "=" << d[row][column] <<endl;
}
}
Both cout << "d[" << row << "]" << "[" << column << "]" << "=" << d[row][column] <<endl;
I code to understand the behavior.My question is:
deck[4][13] has initialized to 0.So the while loop should not work cause it should always
find d[row][column] == 0 but it is not..it is working fine.
second question is,suppose the output is following:
d[0][4]=0
d[0][4]=1
d[2][4]=0
d[2][4]=2
d[1][12]=0
d[1][12]=3--------duplicate
d[3][11]=0
d[3][11]=4
d[0][6]=0
d[0][6]=5
d[1][12]=3--------duplicate
d[1][11]=0
d[1][11]=6
d[0][7]=0
d[0][7]=7<--------------------duplicate
d[1][6]=0
d[1][6]=8
d[0][6]=5
d[0][11]=0
d[0][11]=9
d[2][11]=0
d[2][11]=10
d[3][11]=4
d[3][2]=0
d[3][2]=11
d[2][11]=10
d[1][10]=0
d[1][10]=12
d[1][6]=8
d[0][9]=0
d[0][9]=13
d[0][1]=0
d[0][1]=14
d[3][4]=0
d[3][4]=15
d[0][7]=7 <---------------------duplicate
d[0][2]=0
d[0][2]=16
d[0][3]=0
d[0][3]=17
d[2][11]=10
d[0][5]=0
d[0][5]=18
d[0][9]=13
d[0][10]=0
d[0][10]=19
d[1][6]=8
d[1][7]=0
d[1][7]=20
Press any key to continue . . .
In the for loop the card value is incremental but when the duplicate card value is found for the same index of array, it is taking the very first value for that index.Why it is not changing the increment value?Please help me to understand the code.
You are right, all values of deck are 0 at the beginning and the loop works because the do{}while(condition); is executing at least once before checking condition. The loop is looking here for the first uninitialized card.
Duplicate output is just what the loop is currently checking, it finds an initialized card so it keeps looking for an uninitialized one (this is the first cout).
I'm fairly new to coding in c++, and I'm working on a menu system for a text RPG I'm working on. You can view your stats, view your inventory, view item stats, and discard items. However, after the item is discarded, which ever slot the discarded item was in remains empty, and in a game it doesn't make sense to have object 2 be discarded, and then what was object number 3 remain object 3. Object 3 should become 2. So I was wondering how I could do this with my current code.
#include <iostream>
#include <string>
using namespace std;
bool running = 1;
void titleFunc();
void newGameFunc();
void menuFuncNav();
void menuFuncInfo();
void menuFuncItems();
string itemNames[] = {"Iron Short Sword", "Iron Long Sword", "Iron Two-Handed Sword", "Iron War Hammer", "Iron Mace", "Iron Dagger", "Wooden Staff", "Wooden Shield", "Oak Shortbow", "Oak Longbow", "Oak Crossbow", "Hard Leather Chest-Piece", "Hard Leather Leggings", "Soft Leather Chest-Piece", "Soft Leather Leggings", "Cloak"};
short playerItemCount = 0;
int userInput = 0;
int talkInput = 0;
int playerInfo[3];
int playerLocation = 0;
const int MAX_ITEMS = 100;
int playerItems[MAX_ITEMS][11];
void menuFuncItems()
{
int i = 0;
for( int i = 0; i < playerItemCount; i++ )
{
cout << i+1 << ": ";
cout << itemNames[playerItems[i][0]];
cout << endl;
}
cin >> i;
if( playerItems[i - 1][1] == 1 )
{
cout << "Press 1 to view stats." << endl;
cout << "Press 2 to equip." << endl;
cout << "Press 3 to discard." << endl;
cin >> userInput;
cout << endl;
if( userInput == 1 )
{
cout << "Name: " << itemNames[playerItems[i - 1][0]] << endl;
cout << "Physical Attack:" << playerItems[i - 1][2] << endl;
}
else if( userInput == 2 )
{
}
else
{
playerItems[i - 1][0]--;
playerItems[i - 1][0]--;
cout << "Item discarded." << endl;
}
}
So in this code, the player discards the item in the first inventory slot.
Iron Longsword
Wooden shield
Hard Leather Chest-Piece
Hard Leather Leggings
Should become, after item 1 is discarded:
Wooden Shield
Hard Leather Chest-Piece
Hard Leather Leggings
Sorry if I did something wrong in the post. This is my first post on this site. :) Thank you.
For example you can do the following
for ( int ( *p )[11] = playerItems + i; p != playerItems + playerItemCount; ++p )
{
std::copy( *p, *p + 11, *( p - 1 ) );
}
--playerItemCount;
If you replace
int playerItems[MAX_ITEMS][11];
with
std::vector<int> playerItems; // assuming you store all the items for a given player here
or
std::vector<std::vector<int>> playerItems; // if you want the 2D array for whatever implementation you have
Then erasing an element is as simple as calling playerItems.erase(it); (where it is an iterator "pointing" to the element you want to remove.
Alternatively, if you want a faster insertion/removal (but slower random access), you can use std::list. If you really want to have fun, you can store them in a std::map with the name of the item as the key (instead of using an index to make to the item name string in another array).
I am getting a segmentation fault in console while running the program
i am using codeblocks in ubuntu(linux)
it compiles with 0 errors and 0 warnings
code in pastebin
http://pastebin.com/wgSHPQjc
here is the code
#include <iostream>
#include <string>
using namespace std;
class Year
{
public:
Year(string sone, string stwo, string sthree, string sfour, string sfive, string ssix, string sseven, string seight) // constructor
{
subjectName[0] = sone;
subjectName[1] = stwo;
subjectName[2] = sthree;
subjectName[3] = sfour;
subjectName[4] = sfive;
subjectName[5] = ssix;
subjectName[6] = sseven;
subjectName[7] = seight;
sum = 0;
percentage = 0;
}
void nameOfSem(string semName) // semster name
{
name = semName;
cout << "Enter your " << name << " marks"<< endl;
}
//no of subjects in semster and store marks in an array
void readMarks(int noOfSubjects)
{
subjects = noOfSubjects;
for(int i=0; i<subjects; i++)
{
cout << subjectName[i]; // print out subject name stored in the array
cin >> yearName[i]; // input from keyboard of marks
// while loop so that user enters marks from 0 to 100
while (yearName[i]<0 || yearName[i] > 100 )
{
cout << "incorrect input please enter again: ";
cin >> yearName[i];
}
}
}
// function for calculating avarage
void avarage()
{
for(int j=0; j<subjects; j++) // addtion of marks (addtion of array)
{
sum += yearName[j];
}
cout << "the total is : " << sum << endl;
percentage = float(sum) / float(subjects);
cout << "The percentage is : " << percentage << endl;
}
int sum; // for storing sum of marks
string name; // for storing name of the semister
int subjects; // for storing number of subjects in semister
float percentage; // calculating percentage in the sem
int yearName[]; // array for string marks
string subjectName[]; // array for storin g subject names
};
// main function
int main()
{
cout << "Welcome to xxx uni " << endl;
// constructor for storing subjects name in the array
Year first("Appiled Physics ", "Electronic Devices circuits ", "Basic electrical Engineering ", "C & Data Structures", "English ", "Mathematical Methods ", "mathematics 1 ", "Engineering Drawing ");
// name of the sem
first.nameOfSem("First Year");
//no of subjects and storing marks in the array
first.readMarks(8);
//calculating avarage
first.avarage();
/*
Year two( " " , " ", " ")
second year object
*/
return 0;
}
int yearName[]; // array for string marks
string subjectName[]; // array for storin g subject names
These two lines should NOT compile if your compiler is Standard conformant.
Use std::vector :
std::vector<int> yearName;
std::vector<string> subjectName;
And then use push_back function to add elements to them.
Year(string sone, string stwo, string sthree, /*...*/)
{
subjectName.push_back(sone);
subjectName.push_back(stwo);
subjectName.push_back(sthree);
//so on
}