This is the program I have written which copies all the lines from diskData.dat file to 24HrDiskData.dat file. As of now I am copying all the lines from one file to another I wish to copy last n lines from diskData.dat to 24HrDiskData.dat
#include <iostream>
#include <stdio.h>
#include <fstream>
#include <stdlib.h>
using namespace std;
int main(int argc, char *argv[]) {
FILE *HrData;
char tempData[1024];
int flag = 0;
ofstream fout;
fout.open("24HrDiskData.dat", ios::app); // open file for appending
assert (!fout.fail());
if ((HrData = fopen("/home/xvishuk/diskData.dat", "r")) == NULL) {
printf("\nFile cannot be opened");
}
while (fgets(tempData, 1024, HrData) != NULL) {
fout << tempData; // write the data to the file
}
return 0;
}
Sample pattern of Delimited data
|Sat Mar 26 18:47:57 2016|1|1|182|60.66|3|30|4782|31|68|4|3467750|110|43.1562|64|
|Sat Mar 26 19:01:49 2016|1|1|140|46.26|3.03|30|4782|30|68|4|3467764|96|43.1562|64|
|Sat Mar 26 19:15:40 2016|1|1|184|61.07|3.01|30|4782|30|68|4|3467777|112|43.1562|64|
|Sat Mar 26 19:29:30 2016|1|1|180|59.91|3|30|4782|32|68|4|3467791|98|43.1562|64|
|Sat Mar 26 19:43:20 2016|1|1|194|64.61|3|30|4782|32|68|4|3467805|114|43.1562|64|
|Sat Mar 26 19:57:17 2016|1|1|170|56.62|3|30|4782|30|68|4|3467818|102|43.1562|64|
|Sat Mar 26 20:11:14 2016|1|1|140|46.32|3.02|30|4782|30|68|4|3467832|118|43.1562|64|
|Sat Mar 26 20:25:12 2016|1|1|176|58.35|3.02|30|4782|30|68|4|3467846|104|43.1562|64|
|Sat Mar 26 20:39:10 2016|1|1|202|66.9|3.02|30|4782|30|68|4|3467859|120|43.1562|64|
|Sat Mar 26 20:53:11 2016|1|1|198|65.85|3.01|30|4782|31|68|4|3467873|106|43.1562|64|
|Sat Mar 26 21:07:12 2016|1|1|184|60.97|3.02|30|4782|32|68|4|3467887|92|43.1562|64|
|Sat Mar 26 21:21:11 2016|1|1|152|50.28|3.02|30|4782|31|68|4|3467901|108|43.1562|64|
|Sat Mar 26 21:35:16 2016|1|1|168|55.77|3.01|30|4782|30|68|4|3467915|94|43.1562|64|
|Sat Mar 26 21:49:20 2016|1|1|172|57.03|3.02|30|4782|31|68|4|3467928|112|43.1562|64|
|Sat Mar 26 22:03:26 2016|1|1|152|50.56|3.01|30|4782|33|68|4|3467942|98|43.1562|64|
|Sat Mar 26 22:17:32 2016|1|1|174|57.86|3.01|30|4782|31|68|4|3467956|114|43.1562|64|
|Sat Mar 26 22:31:38 2016|1|1|156|51.86|3.01|30|4782|30|68|4|3467970|100|43.1562|64|
|Sat Mar 26 22:45:44 2016|1|1|202|66.57|3.03|30|4782|30|68|4|3467984|116|43.1562|64|
|Sat Mar 26 22:59:55 2016|1|1|188|62.4|3.01|30|4782|31|68|4|3467998|102|43.1562|64|
|Sat Mar 26 23:14:06 2016|1|1|164|53.95|3.04|30|4782|32|68|4|3468012|118|43.1562|64|
|Sat Mar 26 23:28:17 2016|1|1|168|55.78|3.01|30|4782|31|68|4|3468026|104|43.1562|64|
|Sat Mar 26 23:42:28 2016|1|1|176|58.33|3.02|30|4782|30|68|4|3468040|120|43.1562|64|
|Sat Mar 26 23:56:39 2016|1|1|170|55.76|3.05|30|4782|30|68|4|3468053|106|43.1562|64|
|Sun Mar 27 00:10:54 2016|1|1|172|56.97|3.02|30|4782|31|68|4|3468067|92|43.1562|64|
|Sun Mar 27 00:25:13 2016|1|1|184|61.23|3.01|30|4782|33|68|4|3468081|108|43.1562|64|
|Sun Mar 27 00:39:26 2016|1|1|188|62.12|3.03|30|4782|31|68|4|3468096|94|43.1562|64|
|Sun Mar 27 00:53:42 2016|1|1|170|56.42|3.01|30|4782|30|68|4|3468110|110|43.1562|64|
|Sun Mar 27 01:07:58 2016|1|1|174|57.8|3.01|30|4782|31|68|4|3468124|96|43.1562|64|
Expected Output
The last 10 records.
|Sat Mar 26 22:45:44 2016|1|1|202|66.57|3.03|30|4782|30|68|4|3467984|116|43.1562|64|
|Sat Mar 26 22:59:55 2016|1|1|188|62.4|3.01|30|4782|31|68|4|3467998|102|43.1562|64|
|Sat Mar 26 23:14:06 2016|1|1|164|53.95|3.04|30|4782|32|68|4|3468012|118|43.1562|64|
|Sat Mar 26 23:28:17 2016|1|1|168|55.78|3.01|30|4782|31|68|4|3468026|104|43.1562|64|
|Sat Mar 26 23:42:28 2016|1|1|176|58.33|3.02|30|4782|30|68|4|3468040|120|43.1562|64|
|Sat Mar 26 23:56:39 2016|1|1|170|55.76|3.05|30|4782|30|68|4|3468053|106|43.1562|64|
|Sun Mar 27 00:10:54 2016|1|1|172|56.97|3.02|30|4782|31|68|4|3468067|92|43.1562|64|
|Sun Mar 27 00:25:13 2016|1|1|184|61.23|3.01|30|4782|33|68|4|3468081|108|43.1562|64|
|Sun Mar 27 00:39:26 2016|1|1|188|62.12|3.03|30|4782|31|68|4|3468096|94|43.1562|64|
|Sun Mar 27 00:53:42 2016|1|1|170|56.42|3.01|30|4782|30|68|4|3468110|110|43.1562|64|
To only write the last n lines, you could allocate an array of n strings and store the lines into it as you read them, only keeping the last n when the array fills up, using modular index to avoid unnecessary copying.
When you reach the end of file, output the lines from the array.
Also avoid mixing C and C++. Either use <stdio.h> or <iostream>, but using both at the same time is error prone and inelegant.
Here is a simple implementation in C:
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100
int main(void) {
char line[1024];
char *stash[N] = { NULL };
int i, j;
FILE *HrData, *fout;
if ((fout = fopen("24HrDiskData.dat", "a")) == NULL) {
fprintf(stderr, "cannot open 24HrDiskData.dat for appending: %s\n",
strerror(errno));
return 1;
}
if ((HrData = fopen("/home/xvishuk/diskData.dat", "r")) == NULL) {
fprintf(stderr, "cannot open input file: %s\n",
strerror(errno));
return 1;
}
for (i = 0; fgets(line, 1024, HrData) != NULL;) {
free(stash[i]);
stash[i] = strdup(line);
i = (i + 1) % N;
}
fclose(HrData);
for (j = i;;) {
if (stash[i])
fputs(stash[i], fout);
i = (i + 1) % N;
if (i == j)
break;
}
fclose(fout);
return 0;
}
Two passes.
First pass, count the lines and store their file positions.
Second pass, calculate the line number you want to start copying from. Look up its file position in the container. Seek to the file position. Start copying.
Edit 1: Example code
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
int main(void)
{
std::string text_line;
std::vector<std::streampos> file_positions;
std::ifstream input_file("my_file.txt");
file_positions.push_back(input_file.tellg());
while (std::getline(input_file, text_line))
{
file_positions.push_back(input_file.tellg());
}
// The total lines is file_positions.size().
// Return the last 13 lines
const unsigned int total_lines = file_positions.size();
std::streampos seek_position = 0;
unsigned int index = 0U;
if (total_lines > 13U)
{
index = total_lines - 13U;
}
input_file.clear();
input_file.seekg(file_positions[index]);
// Copy text lines to output file...
return 0;
}
Edit 2 - More efficient method
You could maintain a container of N text lines as you read through the file.
#include <deque>
//...
int main(void)
{
std::deque<std::string> text_lines(N);
while (std::getline(input_file, text_line))
{
if (text_lines.size() == N)
{
text_lines.pop_front();
}
text_lines.push_back(text_line);
}
// Now copy the text lines from the `std::deque` to the output file.
//...
return 0;
}
Related
I'm trying to loop so that my program can get the weight of all files in a folder, and if the weight of any of these is equal to X, it will do an action, I need to know how I can loop like this, and i have a func to know whats the file size
std::ifstream::pos_type filesize(const char* filename)
{
std::ifstream in(filename, std::ifstream::ate | std::ifstream::binary);
return in.tellg();
}
Here's a short example program that demonstrates how to use C++17's <filesystem> library to iterate over a directory. If your compiler is fairly up-to-date, it should support C++17 without issue.
#include <filesystem>
#include <iostream>
int main() {
namespace fs = std::filesystem;
fs::path pwd(""); // Current directory program was executed from
pwd = fs::absolute(pwd);
for (auto& i : fs::directory_iterator(pwd)) {
try {
if (fs::file_size(i.path()) / 1024 > 2048) {
std::cout << i.path() << " is larger than 2MB\n";
}
} catch (fs::filesystem_error& e) {
std::cerr << e.what() << '\n';
}
}
}
This was the contents of the directory:
.
├── a.out
├── fiveKB
├── fourMB
├── main.cpp
└── oneMB
0 directories, 5 files
And information about the files:
drwxr-xr-x 7 user staff 224B Jul 29 22:11 ./
drwxr-xr-x 13 user staff 416B Jul 29 21:59 ../
-rwxr-xr-x 1 user staff 47K Jul 29 22:10 a.out*
-rw-r--r-- 1 user staff 5.0K Jul 29 21:58 fiveKB
-rw-r--r-- 1 user staff 4.0M Jul 29 21:59 fourMB
-rw-r--r-- 1 user staff 450B Jul 29 22:11 main.cpp
-rw-r--r-- 1 user staff 1.0M Jul 29 21:59 oneMB
And finally, the output:
"/Users/user/Documents/tmp/test/fourMB" is larger than 2MB
I try to log with Boost library 1.61, rotating file once size exceeded 5Ko. But, every time program runs, it begins from the first log file, exceeding max size !
That is, it appends text to flog000.txt, then to flog001.txt.
But the desired behaviour was: append to the last file (flog002.txt) then continue with flog003.txt...
Here is my code:
#include <boost/log/common.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/core.hpp>
#include <boost/log/utility/setup/file.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
void init()
{
boost::log::add_file_log
(
boost::log::keywords::file_name = "flog%3N.txt",
boost::log::keywords::open_mode = std::ios_base::app,
boost::log::keywords::rotation_size = 5 * 1024,
boost::log::keywords::auto_flush = true
);
}
int main()
{
init();
boost::log::sources::logger lg;
boost::log::add_common_attributes();
for (int i(0); i < 1000; ++i)
{
BOOST_LOG(lg) << "Hello : " << i << std::endl;
}
return 0;
}
"There's no file collecting" - this is at least a part of the problem.
It does seem impossible to have scanning and append to an existing as well.
However, if you do scanning, you can at least prevent extra log messages from being wrongly appended to the older log files:
Live On Coliru
#include <boost/log/common.hpp>
#include <boost/log/core.hpp>
#include <boost/log/sinks/text_ostream_backend.hpp>
#include <boost/log/sources/logger.hpp>
#include <boost/log/utility/setup/common_attributes.hpp>
#include <boost/log/utility/setup/file.hpp>
void init() {
auto s = boost::log::add_file_log(
boost::log::keywords::file_name = "flog%3N.txt",
boost::log::keywords::open_mode = std::ios_base::app,
boost::log::keywords::rotation_size = 5 * 1024,
boost::log::keywords::auto_flush = true
);
auto be = s->locked_backend();
be->set_file_collector(boost::log::sinks::file::make_collector(
boost::log::keywords::target = "./", // log file & target have same dir
boost::log::keywords::max_size = 50 * 1024,
boost::log::keywords::min_free_space = 100000
));
be->scan_for_files(boost::log::sinks::file::scan_method::scan_matching, true);
}
int main() {
init();
boost::log::sources::logger lg;
boost::log::add_common_attributes();
for (int i(0); i < 1000; ++i) {
BOOST_LOG(lg) << "Hello : " << i << std::endl;
}
}
After one run:
-rw-rw-r-- 1 sehe sehe 5116 jun 6 00:27 flog000.txt
-rw-rw-r-- 1 sehe sehe 5109 jun 6 00:27 flog001.txt
-rw-rw-r-- 1 sehe sehe 2665 jun 6 00:27 flog002.txt
After two runs:
-rw-rw-r-- 1 sehe sehe 5116 jun 6 00:27 flog003.txt
-rw-rw-r-- 1 sehe sehe 5109 jun 6 00:27 flog004.txt
-rw-rw-r-- 1 sehe sehe 2665 jun 6 00:27 flog005.txt
After three runs:
-rw-rw-r-- 1 sehe sehe 5116 jun 6 00:28 flog006.txt
-rw-rw-r-- 1 sehe sehe 5109 jun 6 00:28 flog007.txt
-rw-rw-r-- 1 sehe sehe 2665 jun 6 00:28 flog008.txt
The following snippet from a long long bunch of C++ sources and header files (which I will be happy to share in case they are needed) shows the user-defined function(or object?) Read being called as part of a Multi-threading operation that is going on.
As part of identifying the problem, I printed flags just before and after the function is called:
std::cout<<"Before calling\n";
and
std::cout<<"After calling\n";
I have also inserted a flag to be printed just after the function is called:
std::cout<<"Entered the function";
The entire application compiles perfectly and also runs smoothly - until this function Read is called, it never gets executed.
In the output, you get the "Before calling" and "After calling" but never the "Entered function".
Operating system used is Ubuntu 16.04, with the g++ compiler.
As of now I am only sharing two snippets related to the question - (since a single file is around 1500 lines of code; I think it should suffice, let me know if otherwise)
Following is the snippet of the thread in which function is called (at line 130) and then is the other file where the function is defined.
Thread where the Function is called:
1 void* StartGenericReadThread(void *ThreadAr)
2 { //std::cout<<"flag GenericThread\n";
3 //printf("\nSuccess");
4 int PORT = ((ThreadArg*)ThreadAr)->PORT;
5 #ifdef WIN32
6 Sleep(4000);
7 #else
8 sleep(4);
9 #endif
10 DSDMux *Mux;
11 DSDConfigReader *cfg;
12 SNMPTrap Trap;
13 DSDMessageSender *DMS;
14 Mux = ((ThreadArg*)ThreadAr)->Mux;
15 cfg = ((ThreadArg*)ThreadAr)->cfg;
16 DMS = ((ThreadArg*)ThreadAr)->MSG;
17
18
19 strcpy(DMS->SNMP_DET.DSD_MAN_IP,cfg->DSDSetting.DSD_MANAGER_IP);
20 strcpy(DMS->SNMP_DET.SNMP_MAN_IP,cfg->DSDSetting.SNMP_TRAP_IP);
21 DMS->SNMP_DET.SNMP_MAN_PORT = cfg->DSDSetting.SNMP_TRAP_PORT;
22 DMS->SNMP_DET.DSD_MAN_PORT = 162;
23
24 if ( checkflag != 1) //EDITED
25 {std::cout<<"\nDSD Manager IP set to
26 "<<cfg->DSDSetting.DSD_MANAGER_IP<<"\n";
27 std::cout<<"SNMP TRAP IP set to
28 "<<cfg->DSDSetting.SNMP_TRAP_IP<<"\n";
29
30 std::cout<<"SNMP TRAP PORT set to "<<cfg->DSDSetting.SNMP_TRAP_PORT<<"\n";
31 checkflag=1;
32 }
33
34 try
35 { //std::cout<<"Entered try\n";
36 bool IPLostErrSet(false),IPGainset(false),FIFOreaderr(false);
37 //DSDCo
38 int nStatus, nLatched,inFifoLoad,MaxBuffRead,lostCount(0);
39 dr = theInput[PORT].SetRxControl(DTAPI_RXCTRL_RCV);
40
41 if ( DTAPI_OK != dr )
42 { //std::cout<<"\nSetRXControl is not OK";
43 // return NULL; EDITED
44 }
45
46 #ifdef WIN32
47 while(!_kbhit())
48 #else
49 while(1)
50 #endif
51 { //EDITED
52 //MaxBuffRead=(inFifoLoad/188)*188;
53 //int DmaSize = ( inFifoLoad > c_ReadBufferSize ) ? c_ReadBufferSize : MaxBuffRead;
54
55 theInput[PORT].GetFlags(nStatus, nLatched);
56 if ( 0 != (DTAPI_RX_FIFO_OVF & nLatched) )
57 {
58 printf("Fifo overflow for input port %d\t\t\t\t\t[Error]\n",PORT+1);
59 DMS->SendLog(FIFO_OVERFLOW,PORT+1);
60 theInput[PORT].ClearFifo();
61 dr = theInput[PORT].SetRxControl(DTAPI_RXCTRL_RCV);
62 if ( DTAPI_OK != dr )
63 {
64 printf("\nError");
65
66 }
67 else
68 DMS->SendLog(FIFO_OVERFLOW_CLR,PORT+1);
69 }
70 theInput[PORT].GetFifoLoad(inFifoLoad);
71 inFifoLoad = MINBUFFSIZE + 512;
72 if (inFifoLoad < MINBUFFSIZE+512)
73 {
74 lostCount++;
75 if(lostCount>1000&&!IPLostErrSet)
76 {
77 lostCount=0;
78 printf("\nInput lost on port %d\t\t\t\t\t\t[ERROR]",PORT+1);
79
80 DMS->SendLog(INPUT_LOST,PORT+1);
81 int pid;
82 /*for(pid=21;pid<8191;pid++)
83 {
84 if(cfg->MuxCfg.PORT[PORT].PID[pid].Mux)
85 DMS->SendLog(PID_REMUX_ERR,pid,PORT+1);
86 }*/
87 Mux->PSI.PATdata.Table[PORT].Section[0].no_of_programs = 0;
88 IPGainset = false;
89 IPLostErrSet = true;
90 }
91
92 #ifdef WIN32
93 Sleep(1);
94 #else
95 usleep(1000);
96 #endif
97 continue;
98 }
99 lostCount = 0;
100 //std::cout<<"\nWill check for IPGAINSET now\n";
101 if(!IPGainset)
102 { //std::cout<<"IPGAINSET IS FALSE\n";
103 cfg->OutputConf.Status=true;
104 printf("\nInput signal detected on port %d\t\t\t\t\t[ OK ]",PORT+1);
105
106 DMS->SendLog(INPUT_GAIN,PORT+1);
107 /*int pid;
108 for(pid=21;pid<8191;pid++)
109 {
110 if(cfg->MuxCfg.PORT[PORT].PID[pid].Mux)
111 {
112 //std::cout<<pid;
113 DMS->SendLog(PID_REMUX,pid,PORT+1);
114 }
115 };*/
116 IPLostErrSet = false;
117 IPGainset = true;
118 }
119 //std::cout<<"IPGAINSET is TRUE\n";
120 //printf("\t%d",inFifoLoad);
121 MaxBuffRead=(inFifoLoad/188)*188;
122 int DmaSize = ( inFifoLoad > c_ReadBufferSize ) ? c_ReadBufferSize : MaxBuffRead;
123
124 // fifold=(int)DmaSize;
125 // char data[65424*10];
126
127
128 std::cout<<"Before Calling\n";
129
130 dr = theInput[PORT].Read(Mux->TSPacket[PORT].data,DmaSize);
131
132 std::cout<<"After Calling\n";
133
134 if ( DTAPI_OK != dr )
135 {// std::cout<<"Error in executing Read function\n";
136 if(!FIFOreaderr)
137 DMS->SendLog(FIFO_READ_ERR,dr,PORT+1);
138
139 }
140 else
141 {
142 Mux->ParseAndMuxTS(PORT,DmaSize,cfg,fs);
143
144 }
145 }
146 return NULL;
147
148 }
149 catch(...)
150 {
151 // printf("Error in StartGenericReadThread\n");
152 DMS->SendLog(INTERNAL_ERR,0,0,0,"StartGenericReadThread");
153 return NULL;
154 }
155 }
Now following is the snippet of the function definition (which is in another file):
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include "DTAPI.h"
#include "DtapiUtility.h"
#include "Dta1xxIoCtl.h"
#include "Dta1xxCodes.h"
#include "Dtu2xxIoCtl.h"
#include "Dtu2xxCodes.h"
#include <iostream>
//+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ TsInpChannel implementation +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- TsInpChannel::Read -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
// Read data bytes from the input channel using DMA transfers.
//
DTAPI_RESULT TsInpChannel::Read(
char* pBuffer, // [in] Pointer to data to be read from Device
int NumBytesToRead) // [in] Number of bytes to be read from Device
{
std::cout<<"Entered the function\n";
// Must be attached.
//if (!m_Attached) EDITED
// return DTAPI_E_NOT_ATTACHED; EDITED
// Validity check on parameters
if (NumBytesToRead<0 || NumBytesToRead%4!=0)
return DTAPI_E_INVALID_SIZE;
if ((atoi)(pBuffer)%4 != 0)
return DTAPI_E_INVALID_BUF;
// Avoid strange effects when NumBytesToRead is zero
if (NumBytesToRead == 0)
return DTAPI_OK;
DTAPI_RESULT dr;
// Processing is dependent on device category
if (m_HwFuncDesc.m_DvcDesc.m_Category == DTAPI_CAT_PCI) {
//-.-.-.-.-.-.-.-.-.- Call the appropiate device IoCtl handler -.-.-.-.-.-.-.-.-.-
DTA1XX_IOCTL_DATA iod;
memset(&iod, 0, sizeof(DTA1XX_IOCTL_DATA));
iod.m_nChIdx = GetIndexOnDevice();
iod.m_Data.m_DataTransDesc.m_pBuffer = pBuffer;
iod.m_Data.m_DataTransDesc.m_nNumBytesToTr = NumBytesToRead;
dr = ioctl(m_fdDevice, DTA1XX_IOCTL_DMA_USERMEM_READ, &iod);
if ( dr != DTAPI_OK )
return dr;
}
else if (Category() == DTAPI_CAT_USB) {
// Read using file IO
int ret = read(m_fdDevice, pBuffer, NumBytesToRead);
if ( ret < 0 )
return DTAPI_E_DEV_DRIVER;
}
else //EDITED
{ std::cout<<"\n Beginning to read file at /home/rtpl/Desktop/ts.mp4";
char * storedfilepath = "/home/rtpl/Desktop/ts.mp4";
int *vedant = open(storedfilepath,O_RDONLY);
int ret = read(vedant, pBuffer, NumBytestoRead);
if ( ret < 0)
std::cout<<"\n File contents cannot be read";
//return DTAPI_E_INTERNAL; // Unknown device category
}
return DTAPI_OK;
}
//.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- TsInpChannel::ReadDirect -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
//
DTAPI_RESULT TsInpChannel::ReadDirect(
char* pBuffer, // [in] Buffer to store data
int NumBytesToRead, // [in] Number of bytes to be read
int& NumBytesRead) // [out] Number of bytes read
{
return DTAPI_E_NOT_SUPPORTED;
}
//-.-.-.-.-.-.-.-.-.-.-.-.-.-.- TsInpChannel::ReadUsingDma -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.
//
// Old name of Read. Still here for backward compatibility.
//
DTAPI_RESULT TsInpChannel::ReadUsingDma(
char* pBuffer, // [in] Buffer to store data
int NumBytesToRead) // [in] Number of bytes to be written to PCI card
{
return Read(pBuffer, NumBytesToRead);
}
Background
I'm running linux... and I'm trying to write a basic little c++ program that connects to a postgresql database.
I'm trying to follow this article
http://www.tutorialspoint.com/postgresql/postgresql_c_cpp.htm
Problem
I've been able to compile the library... and I can see now that I have the following folder on my computer
/usr/local/include/pqxx
But when i try to write some basic code and compile it, I get the following error:
devbox2:/var/abus# g++ testdb.cpp -lpqxx -lpq
testdb.cpp:2:22: fatal error: pqxx/pqxx: No such file or directory
#include <pqxx/pqxx>
^
compilation terminated.
Source Code
Here's what the code looks like:
1 #include <iostream>
2 #include <pqxx/pqxx>
3
4 using namespace std;
5 using namespace pqxx;
6
7 int main(int argc, char* argv[])
8 {
9 try{
10 connection C("dbname=testdestination user=testuser password=testpassword \
11 hostaddr=127.0.0.1 port=5432");
12 if (C.is_open()) {
13 cout << "Opened database successfully: " << C.dbname() << endl;
14 } else {
15 cout << "Can't open database" << endl;
16 return 1;
17 }
18 C.disconnect ();
19 }catch (const std::exception &e){
20 cerr << e.what() << std::endl;
21 return 1;
22 }
23 }
What I've tried so far:
I've been poking around the /usr/local/include/pqxx folder and I can see that there is a file called pqxx... but it doesn't have any extension on it.
Here's a snippet from the ls -lah command for that folder:
-rw-r--r-- 1 root root 637 Dec 8 21:42 pipeline
-rw-r--r-- 1 root root 7.5K Dec 8 21:42 pipeline.hxx
-rw-r--r-- 1 root root 1.1K Dec 8 21:42 pqxx
-rw-r--r-- 1 root root 728 Dec 8 21:42 prepared_statement
-rw-r--r-- 1 root root 8.2K Dec 8 21:42 prepared_statement.hxx
I've also made sure that my PATH includes the /usr/local/include/pqxx folder. This is what my PATH looks like:
PATH='/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/lib/gcc:/usr/local/include/pqxx:/usr/local/include'
I'm not sure what else I should check. Any suggestions would be appreciated.
Thanks.
To find the include files, you must add an -I option, e.g.
g++ -I/usr/local/include testdb.cpp -lpqxx -lpq
Adding directories to PATH doesn't help here, PATH is for locating executables from the shell.
This is my code for one of the classes unforunately I keep getting an error saying that 'weapon is not a type' which I'm aware of just uncertain of what type this would be.
knight.h
1 #ifndef KNIGHT_H
2 #define KNIGHT_H
3
4 using namespace std;
5
6 class knight
7 {
8 private:
9 string name;
10 int stamina;
12 weapon weapon_in_hand(string weapon_type, int sr, int hc);*The problem is here*
13
14 public:
15 void on_horse();
16 knight(string name, int stamina, string weapon_type, int sr,int hc);
17 bool hit();
18 void unhorse_yourself();
19 bool are_you_exhausted();
20 void display();
21 };
22 #endif
~
"knight.h" 22L, 418C 1,1 All
and this what it connects to
25 bool hit()
26 {
27 stamina=stamina-weapon_in_hand.stamina_required();
28 if(weapon_in_hand.did_you_hit()==true)
29 return true;
30 else
31 return false;
32 knight::knight(string n, int st, string weapon_type, int sr,int hc)
33 :name(n), stamina(st), weapon_in_hand(weapon_type, sr, hc)
34 {
35 }
The error here is that you haven't declared what a weapon is.
Do you have a header file that you forgot to include?
The compiler starts over for each .c/.cpp file you write, so make sure you #include headers to get the type definitions you are looking for.
The type weapon is not defined. You must include weapon.h at the top of knight.h (right before the using). If this doesn't exist, you have to create this class.