Search for a string in a binary file with C++ - c++

I wrote a short program to search for a string in a binary file. The file consists of text and Base64 content. If I test it with an ASCII text file, it works. If I try it with a binary file, it does not match anything.
So can you tell me:
Where's my fault?
What is the best (computational) way to search for a string in a binary file?
UPDATE: A direct string comparison works, so the problem has to be somewhere in the regex definition.
Code
19 #include<iostream>
20 #include<fstream>
21 #include<regex>
22 #include<string>
23
24 using namespace std;
25
26 int main(int argc, char* argv[]) {
27 if (argc != 2){
28 cout << "Error message";
29 }
30
31 regex type_response ("(TEST: )(.*)");
32 regex target_value ("(VALUE: )(.*)");
33 regex target_version ("(NAME: )(.*)");
34
35 ifstream infile(argv[1], ios::binary);
36
37 if (infile.is_open()){
38 string line;
39 while (getline(infile, line)){
40 if (regex_match(line ,target_version)){
41 cout << line;
42 }
43 };
44 infile.close();
45
46 return 0;
47 }
48
49 else {
50 cout << "Could not open file.\n";
51 return 1;
52 };
53 };

An ASCII file is a binary file that stores ASCII codes and an ASCII code is a 7-bit code stored in a byte. While a binary file has no such restrictions and any of the 8 bits can be used in any byte of a binary file.
In ASCII file the highest bit of each byte is not used and it means the highest bit is treated as 0. While in binary file, it maybe 0 or 1. So there are difference. You can check the hex detail of the binary file using tools like HxD.

The problem was a malformed regex, the rest of the code works.

Related

How to print table of 12 using recursion, I want it upto 10 but on running it turns out to be upto 12

I was trying to create a program to print table of 12 using recursion as I wrote a simple program for this I did get table, but table was instead upto 144 (12times12=144) instead of 120(12times10=120) I am sharing my code and output with you guys I was writing code in C++
//we will print table of 12 using concept of recursion
//a table of 12 is like this
//12 24 36 48 60 72 84 96 108 120
#include<iostream>
using namespace std;
void table(int n)
{
if(n==1)
{
cout<<12<<"\n";
return;
}
table(n-1);
cout<<n*12<<"\n";
}
int main(void)
{
table(12);
}
and now here is out put of this program
12
24
36
48
60
72
84
96
108
120
132
144
please help me what I'm missing here I am positive that adding some condition will help I tried one adding if(n==12) { return;} but it prevents does nothing as in the end it is return n*12

How to calculate the average?

I was asked to calculate the average of marks for 10 students.
First, I was able to read and retrieve the data from data.txt file which looks like this:
No. Name Test1 Test2 Test3
1 Ahmad 58 97 83
2 Dollah 78 76 70
3 Ramesh 85 75 84
4 Maimunah 87 45 74
5 Robert 74 68 97
6 Kumar 77 73 45
7 Intan 56 23 27
8 Ping 74 58 18
9 Idayu 47 98 95
10 Roslan 79 98 78
Then I have to calculate the average for each student and determine the grades.
Here are what I've done so far.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
using namespace std;
int main()
{
ifstream inFile1;
string temp;
int line=0;
inFile1.open("data.txt");
if(inFile1.fail())
{
cout << "File cannot be opened" << endl;
exit(1);
}
while(getline(inFile1, temp))
{
line++;
}
inFile1.close();
return 0;
}
This program should at least consists two prototype function: average() and grade().
This is where I got stuck.
You can check the answers here: find average salaries from file in c++.
Basically when you iterate through the file lines you should split the temp string into tokens you are interested in. How? An option would be to use getline with the delimeter ' ' or look into the std::noskipws stream manipulator or simply use operator>> to read from the file - depends on the details of your requirements.
If I correctly understand your case, I'd go with the operator>> to get the name of the student and then read using getline(inFile, gradesText) to read until end of line to get all grades for the current student.
Then I'd use a separate function to split the strings into a vector of grades. How to do the splitting you can check in Split a string in C++?. This way you could prepare a function like vector<int> split(const string& line, char delim = ' '). Within the implementation you should probably use std::stoi for the string-to-int conversion.
Afterwards, when you already have a proper collection you can calculate the mean from it with:
const double sum = std::accumulate(grades.begin(), grades.end(), 0.0);
const double gradesMean = sum / grades.size();

after msgget() , cout or printf are not working

After using msgget() system call to create a msgQ im not able to use cout or printf.
Below is my code trying to receive from a message Queue.
The "printf" at line 28 does not print anything. But it works fine if i add one more "cout" or "printf" statement(say at line 29).Please let me know for any flaws in my code.
1 #include<sys/errno.h>
2 #include<sys/wait.h>
3 #include<sys/ipc.h>
4 #include<stdio.h>
5 #include<iostream.h>
6 #include<sys/msg.h>
7 #include<sys/types.h>
8
9 struct messgQ
10 {
11 char text[1024];
12 long int mtype;
13 };
14
15
16 int main()
17 {
18 struct messgQ R;
19
20 R.mtype=1;
21
22 int qid=0;
23 qid=msgget((key_t)1234,0766|IPC_CREAT);
24 cout<<"\n 1 MsgQ created with id ="<<qid;
25
26 if( qid > 0 )
27 {
28 printf("\n MsgQ created with id =%d",qid);
29 }
30
31 int rc=0,run=1;
32 while( run )
33 {
34 memset(R.text,0x00,sizeof(R.text));
35 msgrcv(qid,&R,sizeof(R.text),1,0);
36 cout<<"\n Recvd:"<<R.text;
37 if( !strncmp(R.text,"bye",3) )
38 {
39 cout<<"\n Exiting";
40 run=0;
41 }
42 }
43 rc=msgctl(qid,IPC_RMID,NULL);
44 if (rc < 0)
45 perror(strerror(errno));
46 }
The msgget documentation says
RETURN VALUE
If successful, the return value will be the message queue identifier (a nonnegative integer), otherwise -1 with errno indicating the error.
So your check on line 26 is flawed, it should be:
if( qid >= 0 )
Regarding your output, stdout is normally line buffered when you print to a terminal. That means output isn't actually written out until you write a newline. So don't start your lines with a newline, but end with one instead.
printf(" MsgQ created with id =%d\n",qid);
cout<<"Recvd:"<<R.text << '\n';
cout<<"Exiting\n";
Alternatively, force the flushing by doing
cout.flush();
Or if you're using the C stdio functions such as printf, flush it with
fflush(stdout);

I seem to be having a issue reading in from a file [duplicate]

This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 8 years ago.
thanks for looking at this in advance.
I can get my code to compile correctly and whatnot, but when running I get stuck in an infinite seeming loop and I have to exit out manually every time. I am new to reading in data from files and I think that is probably my error but any help looking at my code would be appreciated.
In the interest of not submitting some giant file, I'm only going to submit my main function because I assume the error is in there, I'm just not sure of where.
4 #include "class.h"
5 #include <fstream>
6 using namespace std;
7
8
9 int main()
10 {
11 ifstream external; //declaring input stream for my external file
12 //external.open("external.txt"); //telling the compiler what the source of my external file is called
13 //external.close();
14
15 char time[4], course[4], section[3]; //places to store read in values
16 char dept_name[20];
17
18 table hash_table; //instance of my class
19
20 while(!external.eof()) //while it is not the end of the file
21 {
22 external.open("external.txt"); //opens file from location
23
24 external.getline(dept_name, 20); //grabs the info to be input
25 external.getline(time, 4);
26 external.getline(course, 4);
27 external.getline(section, 3);
28
29 external.close(); //closes file until new one must begin
30
31 cin.ignore(5, '\n'); //ignores five characters until next course
32 hash_table.insert(dept_name, course, section, time); //inserts to table
33 }
34 hash_table.display_all();
35 }
Don't open the file for every entry you read. Among other things, opening the file for each entry means you always start reading at the start of the file.
Change this:
20 while(!external.eof()) //while it is not the end of the file
21 {
22 external.open("external.txt"); //opens file from location
23
24 external.getline(dept_name, 20); //grabs the info to be input
25 external.getline(time, 4);
26 external.getline(course, 4);
27 external.getline(section, 3);
28
29 external.close(); //closes file until new one must begin
30
31 cin.ignore(5, '\n'); //ignores five characters until next course
32 hash_table.insert(dept_name, course, section, time); //inserts to table
33 }
to this:
20 external.open("external.txt"); //opens file from location
21 while(!external.eof()) //while it is not the end of the file
22 {
23
24 external.getline(dept_name, 20); //grabs the info to be input
25 external.getline(time, 4);
26 external.getline(course, 4);
27 external.getline(section, 3);
28
29
30 cin.ignore(5, '\n'); //ignores five characters until next course
31 hash_table.insert(dept_name, course, section, time); //inserts to table
32 }
33 external.close(); //closes file

How do I parse a text file with unknown amount of variables on a line?

I am reading in a text file. The first number is the part #. The Next is the part name. Followed by its subparts-which can be anything from nothing to a lot of different numbers.
How do I parse this out with an unknown amount of variables I would like to read in? Thanks!
For example:
12 Engine 11 14 39 26
11 Fan 9 6
9 Fanblade
6 Bearing
14 Compressor 11 6
39 Combustor 65 63
65 nozzle
63 Fuel-Line
26 Turbine 9 6 77
77 Gear
And what I have been using but obviously only grabbing the first number after the part name:
while(getline(file_in, line)) {
istringstream strm;
strm.str(line);
string id;
string name;
string parent;
strm >> id;
strm >> name;
strm >> parent;
cout << "Got ID "<<id<<" Name "<<name<<" Parent "<<parent<<endl;
}
Something like this:
vector<string> parents;
while(strm >> parent)
{
parents.push_back(parent);
}