Why is LCOV ignoring lines? - c++

I tried running code coverage to see how good my test cases is. Then I found out there are some lines that got ignored by LCOV, like line 6,7,10,13 below. Why does LCOV does not take these into account when lines like line 6 (class domain { ) clearly ran during the test.
1 : #include "ros/ros.h"
2 : #include "gtest/gtest.h"
3 :
4 :
5 :
6 : class domath {
7 : public:
8 1 : int multiply(int a, int b) {return a * b;}
9 :
10 : };
11 :
12 5 : TEST(TestSuite, multiply_test_case1){
13 : domath math1;
14 1 : int a = 3;
15 1 : int b = 4;
16 1 : int c = math1.multiply(a,b);
17 1 : EXPECT_EQ(c,12) << "value should be 12";
18 :
19 1 : }
20 :
21 :
22 1 : int main(int argc, char **argv){
23 :
24 1 : testing::InitGoogleTest(&argc , argv);
25 1 : return RUN_ALL_TESTS();
26 :
27 3 : }
28 :

Related

(C++) Division of a negative double with a positive integer gives me positive result

I was assigned to do a small project in a programming class using NUCLEO F401RE development board. I chose to program using Mbed studio, as I think it is easier than programming on STM32 Cude IDE. However, I encountered a problem that some time when I divide negative floating point number with a positive integer, the result turned out to be positive. I decided to write a program to test the said division.
#include "mbed.h"
// main() runs in its own thread in the OS
int main()
{
int i = 1;
while (true) {
printf("Divided by %d : %f\n",i,-21.837046/i++);
}
}
Here is the result for the first 40 iteration
Divided by 1 : -21.837047
Divided by 2 : -10.918524
Divided by 3 : -7.279016
Divided by 4 : -5.459262
Divided by 5 : -4.367410
Divided by 6 : -3.639508
Divided by 7 : -3.119579
Divided by 8 : -2.729631
Divided by 9 : -2.426339
Divided by 10 : -2.183705
Divided by 11 : -1.985187
Divided by 12 : -1.819754
Divided by 13 : -1.679773
Divided by 14 : -1.559790
Divided by 15 : -1.455804
Divided by 16 : -1.364816
Divided by 17 : -1.284533
Divided by 18 : -1.213170
Divided by 19 : -1.149319
Divided by 20 : -1.091853
Divided by 21 : -1.039860
Divided by 22 : 0.992594
Divided by 23 : 0.949437
Divided by 24 : 0.909877
Divided by 25 : 0.873482
Divided by 26 : 0.839887
Divided by 27 : 0.808780
Divided by 28 : 0.779895
Divided by 29 : 0.753002
Divided by 30 : 0.727902
Divided by 31 : 0.704421
Divided by 32 : 0.682408
Divided by 33 : 0.661729
Divided by 34 : 0.642267
Divided by 35 : 0.623916
Divided by 36 : 0.606585
Divided by 37 : 0.590191
Divided by 38 : 0.574660
Divided by 39 : 0.559925
Divided by 40 : 0.545927
Notice that from i = 1 to i = 21 the results were negative as expected, but when i >= 22 the results were positive numbers. Interstingly, when I changed the numerator to a different number such as -30, the results transitioned from negative to positive at i >= 31. Different numerators have different values of i in which the results transition.
Divided by 1 : -30.000000
Divided by 2 : -15.000000
Divided by 3 : -10.000000
Divided by 4 : -7.500001
Divided by 5 : -6.000000
Divided by 6 : -5.000000
Divided by 7 : -4.285715
Divided by 8 : -3.750001
Divided by 9 : -3.333334
Divided by 10 : -3.000000
Divided by 11 : -2.727273
Divided by 12 : -2.500001
Divided by 13 : -2.307693
Divided by 14 : -2.142858
Divided by 15 : -2.000000
Divided by 16 : -1.875001
Divided by 17 : -1.764706
Divided by 18 : -1.666667
Divided by 19 : -1.578948
Divided by 20 : -1.500001
Divided by 21 : -1.428572
Divided by 22 : -1.363637
Divided by 23 : -1.304348
Divided by 24 : -1.250001
Divided by 25 : -1.200000
Divided by 26 : -1.153847
Divided by 27 : -1.111112
Divided by 28 : -1.071429
Divided by 29 : -1.034483
Divided by 30 : -1.000000
Divided by 31 : 0.967742
Divided by 32 : 0.937501
Divided by 33 : 0.909091
Divided by 34 : 0.882353
Divided by 35 : 0.857143
Divided by 36 : 0.833334
Divided by 37 : 0.810811
Divided by 38 : 0.789474
Divided by 39 : 0.769231
Divided by 40 : 0.750001

read string and numbers to vector c++

What can I do when my file s2.txt looks like
ID 1 (string)
22 30 30 4 2 4 5 7 5 3 ......................................(a few lines
of numbers)
ID 2
30 4 2 1 2 ................................. (other lines of numbers)
I want save numbers to vector but it doesn't work:
void readFromFile (){
ifstream file("s2.txt");
if( file.good() == true )
cout << "open" << endl;
else
cout << "denied" << endl;
int m=0;
while(!file.eof()) {
string ID;
int qual;
vector <int> quality;
getline(file,ID);
while (file>>qual) {
quality.push_back(qual);
cout<<quality[m]<<endl;
m++;
}
}
file.close();
}
}
main () {
readFromFile();
}
When I click "Run" only one string of numbers is save to a vector (for ID1).
PS. Reading ID is not important.
You should read each line to a string. Then check for "ID" string. If "ID" string is found at position 0 of a line then read that line as a ID line, if not, read that line as a line of integer numbers.
As suggested in the answer of Linh Dao, I made a respective sample code:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
void readFromFile(std::istream &in)
{
if (!in.good()) {
std::cerr << "ERROR!" << std::endl;
}
std::string buffer;
std::vector<int> quality;
while (std::getline(in, buffer)) {
if (buffer.size() >= 2 && buffer.compare(0, 2, "ID") == 0) {
std::cout << buffer << std::endl;
quality.clear(); // reset quality vector
} else {
// read numbers
std::istringstream in(buffer); int qual;
while (in >> qual) {
quality.push_back(qual);
std::cout << quality.back() << std::endl;
}
}
}
}
int main(void)
{
#if 0 // in OP
{ std::ifstream fIn("s2.txt");
readFromFile(fIn);
} // fIn goes out of scope -> file is closed
#else // instead
readFromFile(std::cin);
#endif // 0
return 0;
}
Input:
ID 1 (string)
22 30 30 4 2 4 5 7 5 3
22 30 30 4 2 4 5 7 5 3
ID 2
30 4 2 1 2
Output:
ID 1 (string)
22
30
30
4
2
4
5
7
5
3
22
30
30
4
2
4
5
7
5
3
ID 2
30
4
2
1
2
Life demo on ideone.
Note:
The input stream is read line by line (into std::string buffer).
The further processing depends on whether the input buffer contents starts with ID.
If not, the buffer is used with std::istringstream to extract int numbers.
If I understood the comment right, the questioner intended to output the whole collected quality vector in each iteration. Hence, I modified the first sample and added an output operator<<() for std::vector<int>:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
// a stream operator for vector<int> ouput
std::ostream& operator<<(std::ostream &out, const std::vector<int> &values)
{
const char *sep = "";
for (int value : values) {
out << sep << value; sep = " ";
}
return out;
}
void readFromFile(std::istream &in)
{
if (!in.good()) {
std::cerr << "ERROR!" << std::endl;
}
std::string buffer;
std::vector<int> quality;
while (std::getline(in, buffer)) {
if (buffer.size() >= 2 && buffer.compare(0, 2, "ID") == 0) {
std::cout << buffer << std::endl;
quality.clear(); // reset quality vector
} else {
// read numbers
std::istringstream in(buffer); int qual;
while (in >> qual) {
quality.push_back(qual);
std::cout << quality << std::endl;
}
}
}
}
int main(void)
{
#if 0 // in OP
{ std::ifstream fIn("s2.txt");
readFromFile(fIn);
} // fIn goes out of scope -> file is closed
#else // instead
readFromFile(std::cin);
#endif // 0
return 0;
}
Input: the same like above
Output:
ID 1 (string)
22
22 30
22 30 30
22 30 30 4
22 30 30 4 2
22 30 30 4 2 4
22 30 30 4 2 4 5
22 30 30 4 2 4 5 7
22 30 30 4 2 4 5 7 5
22 30 30 4 2 4 5 7 5 3
22 30 30 4 2 4 5 7 5 3 22
22 30 30 4 2 4 5 7 5 3 22 30
22 30 30 4 2 4 5 7 5 3 22 30 30
22 30 30 4 2 4 5 7 5 3 22 30 30 4
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7 5
22 30 30 4 2 4 5 7 5 3 22 30 30 4 2 4 5 7 5 3
ID 2
30
30 4
30 4 2
30 4 2 1
30 4 2 1 2
Life demo on ideone.

MVAPICH hangs on MPI_Send for message larger than eager threshold

There is a simple program in c++ / mpi (mvapich), which sends an array of type float. When i use MPI_Send,MPI_Ssend,MPI_Rsend ,if the size of the data is more than the eager threshold(64k in my program), then during the call MPI_Send my program hangs. If array is smaller than the threshold, program works fine.Source code is bellow:
#include "mpi.h"
#include <unistd.h>
#include <stdio.h>
int main(int argc,char *argv[]) {
int mype=0,size=1;
MPI_Init(&argc,&argv);
MPI_Comm_rank(MPI_COMM_WORLD,&mype);
MPI_Comm_size(MPI_COMM_WORLD,&size);
int num = 2048*2048;
float* h_pos = new float[num];
MPI_Status stat;
if(mype == 0)
{
MPI_Rsend(h_pos, 20000, MPI_FLOAT, 1, 5, MPI_COMM_WORLD);
}
if(mype == 1)
{
printf("%fkb\n", 20000.0f*sizeof(float)/1024);
MPI_Recv(h_pos, 20000, MPI_FLOAT, 0, 5, MPI_COMM_WORLD, &stat);
}
MPI_Finalize();
return 0;
}
I think my settings may be wrong,Parameters is bellow:
MVAPICH2 All Parameters
MV2_COMM_WORLD_LOCAL_RANK : 0
PMI_ID : 0
MPIRUN_RSH_LAUNCH : 0
MPISPAWN_GLOBAL_NPROCS : 2
MPISPAWN_MPIRUN_HOST : g718a
MPISPAWN_MPIRUN_ID : 10800
MPISPAWN_NNODES : 1
MPISPAWN_WORKING_DIR : /home/g718a/new_workspace/mpi_test
USE_LINEAR_SSH : 1
PMI_PORT : g718a:42714
MV2_3DTORUS_SUPPORT : 0
MV2_NUM_SA_QUERY_RETRIES : 20
MV2_NUM_SLS : 8
MV2_DEFAULT_SERVICE_LEVEL : 0
MV2_PATH_SL_QUERY : 0
MV2_USE_QOS : 0
MV2_ALLGATHER_BRUCK_THRESHOLD : 524288
MV2_ALLGATHER_RD_THRESHOLD : 81920
MV2_ALLGATHER_REVERSE_RANKING : 1
MV2_ALLGATHERV_RD_THRESHOLD : 0
MV2_ALLREDUCE_2LEVEL_MSG : 262144
MV2_ALLREDUCE_SHORT_MSG : 2048
MV2_ALLTOALL_MEDIUM_MSG : 16384
MV2_ALLTOALL_SMALL_MSG : 2048
MV2_ALLTOALL_THROTTLE_FACTOR : 4
MV2_BCAST_TWO_LEVEL_SYSTEM_SIZE : 64
MV2_GATHER_SWITCH_PT : 0
MV2_INTRA_SHMEM_REDUCE_MSG : 2048
MV2_KNOMIAL_2LEVEL_BCAST_MESSAGE_SIZE_THRESHOLD : 2048
MV2_KNOMIAL_2LEVEL_BCAST_SYSTEM_SIZE_THRESHOLD : 64
MV2_KNOMIAL_INTER_LEADER_THRESHOLD : 65536
MV2_KNOMIAL_INTER_NODE_FACTOR : 4
MV2_KNOMIAL_INTRA_NODE_FACTOR : 4
MV2_KNOMIAL_INTRA_NODE_THRESHOLD : 131072
MV2_RED_SCAT_LARGE_MSG : 524288
MV2_RED_SCAT_SHORT_MSG : 64
MV2_REDUCE_2LEVEL_MSG : 16384
MV2_REDUCE_SHORT_MSG : 8192
MV2_SCATTER_MEDIUM_MSG : 0
MV2_SCATTER_SMALL_MSG : 0
MV2_SHMEM_ALLREDUCE_MSG : 32768
MV2_SHMEM_COLL_MAX_MSG_SIZE : 131072
MV2_SHMEM_COLL_NUM_COMM : 8
MV2_SHMEM_COLL_NUM_PROCS : 2
MV2_SHMEM_COLL_SPIN_COUNT : 5
MV2_SHMEM_REDUCE_MSG : 4096
MV2_USE_BCAST_SHORT_MSG : 16384
MV2_USE_DIRECT_GATHER : 1
MV2_USE_DIRECT_GATHER_SYSTEM_SIZE_MEDIUM : 1024
MV2_USE_DIRECT_GATHER_SYSTEM_SIZE_SMALL : 384
MV2_USE_DIRECT_SCATTER : 1
MV2_USE_OSU_COLLECTIVES : 1
MV2_USE_OSU_NB_COLLECTIVES : 1
MV2_USE_KNOMIAL_2LEVEL_BCAST : 1
MV2_USE_KNOMIAL_INTER_LEADER_BCAST : 1
MV2_USE_SCATTER_RD_INTER_LEADER_BCAST : 1
MV2_USE_SCATTER_RING_INTER_LEADER_BCAST : 1
MV2_USE_SHMEM_ALLREDUCE : 1
MV2_USE_SHMEM_BARRIER : 1
MV2_USE_SHMEM_BCAST : 1
MV2_USE_SHMEM_COLL : 1
MV2_USE_SHMEM_REDUCE : 1
MV2_USE_TWO_LEVEL_GATHER : 1
MV2_USE_TWO_LEVEL_SCATTER : 1
MV2_USE_XOR_ALLTOALL : 1
MV2_DEFAULT_SRC_PATH_BITS : 0
MV2_DEFAULT_STATIC_RATE : 0
MV2_DEFAULT_TIME_OUT : 67374100
MV2_DEFAULT_MTU : 0
MV2_DEFAULT_PKEY : 0
MV2_DEFAULT_PORT : -1
MV2_DEFAULT_GID_INDEX : 0
MV2_DEFAULT_PSN : 0
MV2_DEFAULT_MAX_RECV_WQE : 128
MV2_DEFAULT_MAX_SEND_WQE : 64
MV2_DEFAULT_MAX_SG_LIST : 1
MV2_DEFAULT_MIN_RNR_TIMER : 12
MV2_DEFAULT_QP_OUS_RD_ATOM : 257
MV2_DEFAULT_RETRY_COUNT : 67900423
MV2_DEFAULT_RNR_RETRY : 202639111
MV2_DEFAULT_MAX_CQ_SIZE : 40000
MV2_DEFAULT_MAX_RDMA_DST_OPS : 4
MV2_INITIAL_PREPOST_DEPTH : 10
MV2_IWARP_MULTIPLE_CQ_THRESHOLD : 32
MV2_NUM_HCAS : 1
MV2_NUM_NODES_IN_JOB : 1
MV2_NUM_PORTS : 1
MV2_NUM_QP_PER_PORT : 1
MV2_MAX_RDMA_CONNECT_ATTEMPTS : 10
MV2_ON_DEMAND_UD_INFO_EXCHANGE : 1
MV2_PREPOST_DEPTH : 64
MV2_HOMOGENEOUS_CLUSTER : 0
MV2_COALESCE_THRESHOLD : 6
MV2_DREG_CACHE_LIMIT : 0
MV2_IBA_EAGER_THRESHOLD : 0
MV2_MAX_INLINE_SIZE : 0
MV2_MAX_R3_PENDING_DATA : 524288
MV2_MED_MSG_RAIL_SHARING_POLICY : 0
MV2_NDREG_ENTRIES : 0
MV2_NUM_RDMA_BUFFER : 0
MV2_NUM_SPINS_BEFORE_LOCK : 2000
MV2_POLLING_LEVEL : 1
MV2_POLLING_SET_LIMIT : -1
MV2_POLLING_SET_THRESHOLD : 256
MV2_R3_NOCACHE_THRESHOLD : 32768
MV2_R3_THRESHOLD : 4096
MV2_RAIL_SHARING_LARGE_MSG_THRESHOLD : 16384
MV2_RAIL_SHARING_MED_MSG_THRESHOLD : 2048
MV2_RAIL_SHARING_POLICY : 4
MV2_RDMA_EAGER_LIMIT : 32
MV2_RDMA_FAST_PATH_BUF_SIZE : 4096
MV2_RDMA_NUM_EXTRA_POLLS : 1
MV2_RNDV_EXT_SENDQ_SIZE : 5
MV2_RNDV_PROTOCOL : 3
MV2_SMALL_MSG_RAIL_SHARING_POLICY : 0
MV2_SPIN_COUNT : 5000
MV2_SRQ_LIMIT : 30
MV2_SRQ_MAX_SIZE : 4096
MV2_SRQ_SIZE : 256
MV2_STRIPING_THRESHOLD : 8192
MV2_USE_COALESCE : 0
MV2_USE_XRC : 0
MV2_VBUF_MAX : -1
MV2_VBUF_POOL_SIZE : 512
MV2_VBUF_SECONDARY_POOL_SIZE : 256
MV2_VBUF_TOTAL_SIZE : 0
MV2_USE_HWLOC_CPU_BINDING : 1
MV2_ENABLE_AFFINITY : 1
MV2_ENABLE_LEASTLOAD : 0
MV2_SMP_BATCH_SIZE : 8
MV2_SMP_EAGERSIZE : 65537
MV2_SMPI_LENGTH_QUEUE : 262144
MV2_SMP_NUM_SEND_BUFFER : 256
MV2_SMP_SEND_BUF_SIZE : 131072
MV2_USE_SHARED_MEM : 1
MV2_CUDA_BLOCK_SIZE : 0
MV2_CUDA_NUM_RNDV_BLOCKS : 8
MV2_CUDA_VECTOR_OPT : 1
MV2_CUDA_KERNEL_OPT : 1
MV2_EAGER_CUDAHOST_REG : 0
MV2_USE_CUDA : 1
MV2_CUDA_NUM_EVENTS : 64
MV2_CUDA_IPC : 1
MV2_CUDA_IPC_THRESHOLD : 0
MV2_CUDA_ENABLE_IPC_CACHE : 0
MV2_CUDA_IPC_MAX_CACHE_ENTRIES : 1
MV2_CUDA_IPC_NUM_STAGE_BUFFERS : 2
MV2_CUDA_IPC_STAGE_BUF_SIZE : 524288
MV2_CUDA_IPC_BUFFERED : 1
MV2_CUDA_IPC_BUFFERED_LIMIT : 33554432
MV2_CUDA_IPC_SYNC_LIMIT : 16384
MV2_CUDA_USE_NAIVE : 1
MV2_CUDA_REGISTER_NAIVE_BUF : 524288
MV2_CUDA_GATHER_NAIVE_LIMIT : 32768
MV2_CUDA_SCATTER_NAIVE_LIMIT : 2048
MV2_CUDA_ALLGATHER_NAIVE_LIMIT : 1048576
MV2_CUDA_ALLGATHERV_NAIVE_LIMIT : 524288
MV2_CUDA_ALLTOALL_NAIVE_LIMIT : 262144
MV2_CUDA_ALLTOALLV_NAIVE_LIMIT : 262144
MV2_CUDA_BCAST_NAIVE_LIMIT : 2097152
MV2_CUDA_GATHERV_NAIVE_LIMIT : 0
MV2_CUDA_SCATTERV_NAIVE_LIMIT : 16384
MV2_CUDA_ALLTOALL_DYNAMIC : 1
MV2_CUDA_ALLGATHER_RD_LIMIT : 1024
MV2_CUDA_ALLGATHER_FGP : 1
MV2_SMP_CUDA_PIPELINE : 1
MV2_CUDA_INIT_CONTEXT : 1
MV2_SHOW_ENV_INFO : 2
MV2_DEFAULT_PUT_GET_LIST_SIZE : 200
MV2_EAGERSIZE_1SC : 0
MV2_GET_FALLBACK_THRESHOLD : 0
MV2_PIN_POOL_SIZE : 2097152
MV2_PUT_FALLBACK_THRESHOLD : 0
MV2_ASYNC_THREAD_STACK_SIZE : 1048576
MV2_THREAD_YIELD_SPIN_THRESHOLD : 5
MV2_USE_HUGEPAGES : 1
and Configurations:
mpiname -a
MVAPICH2 2.0 Fri Jun 20 20:00:00 EDT 2014 ch3:mrail
Compilation
CC: gcc -DNDEBUG -DNVALGRIND -O2
CXX: g++ -DNDEBUG -DNVALGRIND
F77: no -L/lib -L/lib
FC: no
Configuration
-with-device=ch3:mrail --with-rdma=gen2 --enable-cuda --disable-f77 --disable-fc --disable-mcast
The program runs on 2 processes:
mpirun_rsh -hostfile hosts -n 2 MV2_USE_CUDA=1 MV2_SHOW_ENV_INFO=2 ./myTest
Any ideas?
The MPI Standard specifies that
A send that uses the ready communication mode may be started only if the matching receive is already posted. Otherwise, the operation is erroneous and its outcome is undefined.
In this program there is no guarantee that the Recv will be posted before the Rsend, so the operation may fail or hang.
I have run this on my laptop with 781.2 KiB without any deadlock. Ran it on a Blue Gene/Q with 781.2 KiB without any deadlock. So, thanks for the short test case, but I'm sorry I cannot reproduce your issue. Maybe it's specific to infiniband?
The general solution in this case is to post non-blocking sends and receives. I can provide code, but you're asking about ready-send and the eager threshold, so I'm pretty sure you know about those already and must have a good reason not to use them...
I just ran your test case using MVAPICH2-2.0 on an InfiniBand system, and I was not able to reproduce the hang. Would you be able to post a debug trace of the process which is hanging?
$ gdb attach <PID>
gdb> thread apply all bt

c++ reading in text file into vector<vector> then writing to vector or array depending on first word in internal vector

this is a progression from the question I posted c++ program for reading an unknown size csv file (filled only with floats) with constant (but unknown) number of columns into an array
. Im now moving onto the real application where I read in a file like:
MESH2D
MESHNAME "default coverage"
NUM_MATERIALS_PER_ELEM 1
E4Q 1 19 20 14 16 2
E4Q 2 17 16 15 23 2
E4Q 3 22 15 14 21 2
E4Q 4 4 3 21 20 1
E4Q 5 6 20 19 7 1
E4Q 6 18 17 10 9 1
E4Q 7 17 23 12 11 1
E4Q 8 7 19 18 8 1
E4Q 9 22 1 13 23 1
E3T 10 14 20 21 2
E3T 11 21 2 22 1
E3T 12 21 3 2 1
E3T 13 22 2 1 1
E3T 14 5 20 6 1
E3T 15 20 5 4 1
E3T 16 16 14 15 2
E3T 17 23 13 12 1
E3T 18 22 23 15 2
E3T 19 17 11 10 1
E3T 20 17 18 16 2
E3T 21 8 18 9 1
E3T 22 18 19 16 2
ND 1 -3.25811078e+002 7.70285567e+001 0.00000000e+000
ND 2 -3.24209146e+002 7.60394871e+001 0.00000000e+000
ND 3 -3.23012110e+002 7.44783503e+001 0.00000000e+000
ND 4 -3.22754089e+002 7.25326647e+001 0.00000000e+000
ND 5 -3.23617358e+002 7.08079432e+001 0.00000000e+000
ND 6 -3.25161538e+002 6.98134116e+001 0.00000000e+000
ND 7 -3.27128620e+002 6.98759747e+001 0.00000000e+000
ND 8 -3.29095703e+002 6.99385378e+001 0.00000000e+000
ND 9 -3.30301095e+002 7.14667646e+001 0.00000000e+000
ND 10 -3.30786908e+002 7.33241555e+001 0.00000000e+000
ND 11 -3.30835733e+002 7.52916270e+001 0.00000000e+000
ND 12 -3.29587322e+002 7.65401204e+001 0.00000000e+000
ND 13 -3.27743000e+002 7.72270000e+001 0.00000000e+000
ND 14 -3.26108525e+002 7.32067724e+001 0.00000000e+000
ND 15 -3.27041416e+002 7.42070316e+001 0.00000000e+000
ND 16 -3.27350377e+002 7.31716751e+001 0.00000000e+000
ND 17 -3.29153676e+002 7.40024406e+001 0.00000000e+000
ND 18 -3.28659180e+002 7.19967464e+001 0.00000000e+000
ND 19 -3.26845856e+002 7.14062637e+001 0.00000000e+000
ND 20 -3.25000347e+002 7.20534611e+001 0.00000000e+000
ND 21 -3.24701329e+002 7.39638966e+001 0.00000000e+000
ND 22 -3.26167714e+002 7.53360591e+001 0.00000000e+000
ND 23 -3.28060316e+002 7.54194849e+001 0.00000000e+000
BEGPARAMDEF
GM "Mesh"
SI 0
DY 0
TU ""
TD 0 0
NUME 3
BCPGC 0
DISP_OPTS entity 0 0 0 0 1 0 0 0
DISP_OPTS inactive 0 0 0 0 1 0 0 0
DISP_OPTS multiple 0 0 0 0 1 0 0 0
BEFONT 0 1
DISP_OPTS entity 1 0 0 0 1 0 0 0
DISP_OPTS inactive 1 0 0 0 1 0 1 0
DISP_OPTS multiple 1 0 0 0 1 0 1 0
BEFONT 1 1
DISP_OPTS entity 2 0 0 0 1 0 0 0
DISP_OPTS inactive 2 0 0 0 1 0 1 0
DISP_OPTS multiple 2 0 0 0 1 0 1 0
BEFONT 2 1
MAT 1 "material 01"
MAT 2 "material 02"
MAT_MULTI 0
ENDPARAMDEF
BEG2DMBC
END2DMBC
BEGCURVE Version: 1
ENDCURVE
called 'example.2dm' and try and write 3 2d vectors (or possibly (preferably) arrays) for the data stored in lines starting with E4Q E3T and ND. I want to use these cell difinitions to print a file with cell centres.
I think this sort of problem is very usefull to be documented on here as my last question keeps getting views.
My code so far is:
// Read in CSV
//
// Alex Byasse
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>
enum case_name {e3t, e4q, nd};
case_name checkit(std::string const& inString)
{
if (inString == "E3T") return e3t;
if (inString == "E4Q") return e4q;
if (inString == "ND") return nd;
}
int main()
{
std::vector<std::vector<std::string>> values;
std::ifstream fin("example.2dm");
for (std::string line; std::getline(fin, line); )
{
std::istringstream in(line);
values.push_back(
std::vector<std::string>(std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>()));
}
int nc = 0;
int nn = 0;
std::vector<std::vector<double>> cells;
std::vector<std::vector<double>> nodes;
for (int i = 0; i < values.size() - 1; i++) {
switch (checkit(values[i][0])){
case e3t:
cells[nc].push_back(std::stod(values[i][1]));
cells[nc].push_back(std::stod(values[i][2]));
cells[nc].push_back(std::stod(values[i][3]));
cells[nc].push_back(std::stod(values[i][4]));
cells[nc].push_back(std::stod(values[i][2]));
cells[nc].push_back(std::stod(values[i][5]));
nc++;
break;
case e4q:
cells[nc].push_back(std::stod(values[i][1]));
cells[nc].push_back(std::stod(values[i][2]));
cells[nc].push_back(std::stod(values[i][3]));
cells[nc].push_back(std::stod(values[i][4]));
cells[nc].push_back(std::stod(values[i][5]));
cells[nc].push_back(std::stod(values[i][6]));
nc++;
break;
case nd:
nodes[nn].push_back(std::stod(values[i][1]));
nodes[nn].push_back(std::stod(values[i][2]));
nodes[nn].push_back(std::stod(values[i][3]));
nn++;
break;
}
}
}
Can I get some help fixing this code and also.
Is this correct?
#include <cstdlib>
Im getting the following compilation error:
$ g++ read_csv2.cpp -std=c++0x
read_csv2.cpp: In function ‘int main()’:
read_csv2.cpp:44:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:45:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:46:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:47:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:48:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:49:33: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:53:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:54:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:55:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:56:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:57:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:58:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:62:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:63:26: error: ‘stod’ is not a member of ‘std’
read_csv2.cpp:64:26: error: ‘stod’ is not a member of ‘std’
I'm running g++ on cygwin. I've checked the man pages and -std=c++11 is an available option and I've tryed it yet I get the same error?
There are a lot of compile errors produced by your program. I suggest you to give some more time in reading the basics of C++ and STL.
std::vector<std::vector<std::string>> values; to std::vector<std::vector<std::string> > values;. Notice the difference, some C++ compilers will take >> as the right shift operator.
In many places in your code, you've used just vector instead of std::vector. Correct this or consider adding using namespace std; before the main function.
double is a primitive type. There is nothing called std::double.
Change vector::size(values)-1 to values.size() - 1.
Use ; instead of , to separate the three parts of the for statement.
switch values[i][0] it should be switch (values[i][0]).
E3T is a string, so you use "E3T" instead of 'E3T'. Single quote is for characters.
And C++ doesn't support switch with strings, so use if-else-if instead.
The places where you have cells[nc] and nodes[nd] are broken because those vectors are never increased in size.
Here's something that may do what you need without requiring std::stod. I changed it to use all of the values from the ND lines assuming that was what you meant, if not, change the 4 to a 3 in that GetValues call.
#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>
double ToDouble(const std::string& str)
{
std::stringstream s(str);
double d;
s >> d;
return d;
}
std::vector<double> GetValues(const std::vector<std::string>& src, int start, int end)
{
std::vector<double> ret;
for(int i = start; i <= end; ++i)
{
ret.push_back(ToDouble(src[i]));
}
return ret;
}
void PrintValues(const std::string& title, std::vector<std::vector<double>>& v)
{
std::cout << title << std::endl;
for(size_t line = 0; line < v.size(); ++line)
{
for(size_t val = 0; val < v[line].size(); ++val)
{
std::cout << v[line][val] << " ";
}
std::cout << std::endl;
}
std::cout << std::endl;
}
int main()
{
std::vector<std::vector<std::string>> values;
std::ifstream fin("example.2dm");
for (std::string line; std::getline(fin, line); )
{
std::istringstream in(line);
values.push_back(
std::vector<std::string>(std::istream_iterator<std::string>(in),
std::istream_iterator<std::string>()));
}
std::vector<std::vector<double>> cells;
std::vector<std::vector<double>> nodes;
for (size_t i = 0; i < values.size(); ++i)
{
if(values[i][0] == "E3T")
{
cells.push_back(GetValues(values[i], 1, 5));
}
else if(values[i][0] == "E4Q")
{
cells.push_back(GetValues(values[i], 1, 6));
}
else if(values[i][0] == "ND")
{
nodes.push_back(GetValues(values[i], 1, 4));
}
}
PrintValues("Cells", cells);
PrintValues("Nodes", nodes);
return 0;
}
The std::stod problem is odd, I thought that worked on Cygwin. What happens if you compile this program with -std=c++11?
#include <string>
#if __cplusplus < 201103L
#warning No C++11 support
#endif
#if !defined(_GLIBCXX_USE_C99)
#warning No C99 library functions
#endif
#if defined(_GLIBCXX_HAVE_BROKEN_VSWPRINTF))
#warning Broken vswprintf
#endif
int main() { }
Those are the preprocessor conditions necessary for libstdc++ to define std::stod so if compiling that produces any warning then you won't be able to use std::stod. You might need to use strtod(values[i][3].c_str(), nullptr) instead.

problem with updating a map by removing some keys and also some elements

I have a map. lets say map<int, vector<int> > mymap1.
I want to update mymap1 by deleting some “keys” and also removing unwanted “elements” from the vector part of the selected keys. The “key’ or the “element” going to be deleted is given from another vector, known as “mylabel”. Actually, What I need to remain in my map is the values whose label is equal to 1. (At the end, keys must have the elements whose label are 1 only.)
I have implemented this (see code below), but got some compiler errors.
map<int, vector<int> > mymap1;
map<int, vector<int> >::iterator map1;
for (map1=mymap1.begin();map1!=mymap1.end();map1++){
int key = map1->first;
if (mylabel[key].Label() != 1){ mymap1.erase(key);
}
else{
vector<int> &myvec = map1->second;
for (vector<int>::iterator rn=myvec.begin(); rn!=myvec.end(); rn++){
if (mylabel[*rn].Label() != 1) myvec.erase(myvec.begin()+(*rn));
}
}
}
for you to get an idea, i am showing some example of my map.
0 1 2 6 10
1 0 2 4 3 6
2 0 1 3 5 8
3 1 2 4 5 7
4 1 3 6 7
5 2 3 8 7 9
6 1 0 7 4
7 6 4 3 5 9 11 10 13 12
8 2 5 9 11 18 15 19 20 22
9 5 7 11 8
10 0 7 14 16
11 9 7 8 13
12 7 13 14
13 7 12 11 14 15
14 12 10 16 13 15 17
15 13 14 8 17 19
16 14 10 17 21
17 14 16 15 21 18
18 8 20 19 17 26 27
19 8 15 18
20 8 18
21 16 17 23 24
22 8
23 25 21 24 26
24 23 21
25 23 26
26 23 25 18
27 18 28
28 27
if i show you my mylabel, it is as follows.
for(int c=0;c<mylabel.size();c++){
cout<<c<<" : "<<"label "<<mylabel[c].Label()<<endl;
}
0 : label 0
1 : label 0
2 : label 0
3 : label 0
4 : label 0
5 : label 1
6 : label 0
7 : label 1
8 : label 0
9 : label 1
10 : label 0
11 : label 1
12 : label 0
13 : label 0
14 : label 1
15 : label 1
16 : label 1
17 : label 1
18 : label 0
19 : label 0
20 : label 0
21 : label 1
22 : label 0
23 : label 0
24 : label 0
25 : label 1
26 : label 1
27 : label 0
28 : label 0
When I am deactivating the else part and running above code I got an output. But, I want to say you that it is a wrong result. I am getting extra keys that should be deleted. I can’t figure out why I got this fault result.
if i show the list of keys what i got,
5
7
9
11
14
15
16
17
20 - wrong
21
24 - wrong
25
26
could you please help me to rectify my code in order to get my modified map. thanks in advance.
Your erasing logic is wrong, and you end up using invalid iterators. (You're literally pulling the rug out from under your feet if you erase an iterator and then keep using that iterator.)
For node-based containers (list, map, set, unordered), you typically erase as follows:
for (auto it = c.begin(); it != c.end(); )
{
if (must_delete(*it)) // or it->first
{
c.erase(it++); // advance first, then erase previous
}
else
{
++it;
}
}
(This patterns is my favourite justification for the post-fix increment operator.)
For contiguous containers (vector, deque), erasing one element at a time is inefficient, because it incurs repeated moves. The preferred idiom here is "remove/erase", but it requires that you supply a suitable predicate if you don't just want to remove straight by element value. Here's an example with lambdas, for brevity:
std::vector<int> v;
v.erase(std::remove_if(v.begin(), v.end(),
[](int n)->bool{return some_criterion(n);}),
v.end());
In your situation, you could write the lambda as [mylabel&](n)->bool{ return mylabel[n].Label() != 1; }; or write a traditional predicate object if you don't have lambdas:
struct LabelFinder
{
LabelFinder(const LabelVector & lv) : label(lv) { }
inline bool operator()(int n) const
{
return label[n].Label() != 1;
}
private:
const LabelVector & label;
};
Now use:
v.erase(std::remove_if(v.begin(), v.end(), LabelFinder(mylabel)), v.end());
The problem is in the for loop. std::vector<T>::erase() returns iterator to the new position followed by the erased item. So the loop should be written as:
for (vector<int>::iterator rn=myvec.begin(); rn!=myvec.end();)
{
if (mylabel[*rn].Label() != 1)
rn = myvec.erase(rn);
else
++rn;
}
Read the doc:
vector::erase()
By the way, I doubt on this:
rn = myvec.erase(myvec.begin()+(*rn));
Vs
rn = myvec.erase(rn);
Are you sure you want the first one?
An idiomatic way to erase elements which are not equal to one is this:
//Define this function
bool isNotOne(int n) { return n != 1; }
//then do this instead of writing manual loop
myvec.erase( remove_if(myvec.begin(), myvec.end(), isNotOne), myvec.end() );
It's called :
Erase-Remove Idiom