search string in textfile [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
Say you have a text file like this
all you want from the text is the "size value"
but repeats more that thousand time with different value
"field_pic_flag : 0
bottom_field_flag : 0
idr_pic_id : 0
Found NAL at offset ,size 28813 !! Found NAL"
"field_pic_flag : 0
bottom_field_flag : 0
idr_pic_id : 0
Found NAL at offset ,size 210 !! Found NAL"
Results
i just want a code to write a text file with this format as shown below
size 28813
size 210
and so on

If using C/C++ is not mandatory, then grep is probably your friend :
grep "size [0-9]*" -o yourfile.txt > all_sizes.txt
And if you only need the 50 first results, head it is :
head -n 50 all_sizes > result.txt
(Now, this assumes you're using some kind of Unix, or OS X ...)

I saw that the question is tagged as C/C++. If you're allowed to use C++ 11, than you can easily use the new introduced regex library.
In the code bellow the data is stored directly in a string, but you can easily read it from a file. The results is saved in the result.txt file, been displayed on the screen at the same time.
#include <iostream>
#include <string>
#include <regex> // The new library introduced in C++ 11
#include <fstream>
int main()
{
const int n = 50;
int i = 0;
std::ofstream outputFile;
outputFile.open("result.txt");
// You can read this string from your input file
std::string s("\"field_pic_flag : 0\
bottom_field_flag : 0\
idr_pic_id : 0\
Found NAL at offset, size 28813 !!Found NAL\"\
\"field_pic_flag : 0\
bottom_field_flag : 0\
idr_pic_id : 0\
Found NAL at offset, size 210 !!Found NAL\"");
std::smatch m;
std::regex e("size [0-9]*");
while (std::regex_search(s, m, e) && i++<n) {
for (auto x : m) {
std::cout << x << " ";
outputFile << x << " ";
}
std::cout << std::endl;
outputFile << std::endl;
s = m.suffix().str();
}
outputFile.close();
return 0;
}
A classical solution will require a little more effort.

Related

How to fix this code to read this file in C++? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Here's my code, which should be able to read the file, but it gives me this:
Error: Invalid format in file
What's wrong in this code?
int main()
{
std::map<std::string, std::vector<std::string>> routes;
print_rasse();
std::string inp;
std::cout << "Give a name for input file: ";
std::getline(std::cin, inp);
std::ifstream file(inp);
std::string row;
if ( not file ) {
std::cout << "Error: File could not be read." << std::endl;
return EXIT_FAILURE;
}
while(getline(file, row)){
if (count(row.begin(), row.end(),';'+!1)){
std::cout << "Error: Invalid format in file." << std::endl;
return EXIT_FAILURE;
}
}
}
The .txt file which I'm trying to read contains this:
West;Pyynikintori;0
West;Tuulensuu;0.5
West;Keskustori;1.5
West;Koskipuisto;1.8
West;Rautatieasema;2.2
West;Tulli;2.5
West;Sammonaukio;2.8
East;Sammonaukio;
East;Kaleva;0.2
East;Uintikeskus;0.3
East;Kalevanrinne;0.6
East;Hakametsa;1
East;Turtola;3
East;Hallila;5
East;Hervanta;7
East;Hervannan kampus;7.1
South;Hervannan kampus
South;Etela-Hervanta;0.4
South;Hervantajarvi;0.7
Hospital;Sammonaukio
Hospital;Kalevan kirkko;0.1
Hospital;Hippos;0.4
Hospital;TAYS;0.6
Hospital;Kaupin kampus;0.7
In this statement:
if (count(row.begin(), row.end(),';'+!1))
!1 is effectively the same as 0, so ';'+0 is just ';'. The statement is effectively this:
if (count(row.begin(), row.end(), ';'))
It is counting the number of ; characters in the row. An integer implicitly converts to a bool, where 0 is false and non-0 is true. So, if there are any matching characters in the row, the if will evaluate as true, otherwise as false.
Since each line in the .txt file shown has 2 ; characters in it, count() will return 2, thus the if will be true, and so the code will display the error message.
You probably meant to do this instead:
if (count(row.begin(), row.end(), ';') != 2)

When using Boost::mapped_file, why does the size of the file appear to cap at 65,356 bytes? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
For my program, I am using boost::mapped_file to memory map a file that I want to access for a pattern detection algorithm. In order to test the construction of the mapped files, and the following execution of my algorithm I have been testing the mapping of the file by specifying the size of the file that I want, creating the file and filling it with random characters, and then mapping that file. The problem is that I have run into a weird error, and I am not quite sure what is happening.
The error I am getting is that once my file reaches size=65,536 bytes, when attempting to use the boost::mapped_file_source::size() method, the return value is 0. Any file sizes that I try to use after this are just an incremented version of 65,536 meaning that a file size=65,538 returns a size of 2.
I was curious if this had to do with the alignment of the mapped file, which I saw referred to here. However, when I called the boost::mapped_file_source::alignment() method, it returned 4096, which I don't understand. What does alignment mean, and how does it play into this problem?
Also, why does boost::mapped_file_source::size() return 0 when the file_size>65,536 bytes? I know that 65,536 is equal to the alignment value (4096) * 16, but I don't understand why.
You should show the relevant code. Docs
explicit mapped_file_source( const std::string& path,
size_type length = max_length,
boost::intmax_t offset = 0 );
Specifically, if length is not specified it will use the filesize.
Boost IOStreams does NOT have the limitation you describe, as you can easily show:
Live On Coliru
#include <boost/iostreams/device/mapped_file.hpp>
#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
static constexpr auto PATH = "path";
void test(std::size_t length) {
int fd =::creat(PATH, 0600);
if (::ftruncate(fd, length) || ::close(fd))
::perror("whoops");
boost::iostreams::mapped_file_source m(PATH);
std::cout
<< m.size() << " = "
<< std::hex << std::showbase << m.size() << "\n";
}
int main() {
test(0XFFFF);
test(0X1FFFF);
test(0X2FFFF);
}
Prints
65535 = 0xffff
0x1ffff = 0x1ffff
0x2ffff = 0x2ffff

How to continue to execute the C++ code after gnuplot was called? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am using gcc as a compiler and gnuplot-iostream.h as a stream to combine C++ code and the gnuplot features.
What I am doing:
I try to make a fit of the data via gnuplot and extract the final fit parameters from the generated fit.log file for further processing.
What's the problem:
When executing the code like this
std::cout << "Starting to fit" << std::endl;
if (bStartFit == true)
{
// gp << doing stuf here;
std::cout << "Test end" << std::endl;
}
std::cout << "Fit is done" << std::endl;
the output will be:
Starting to fit
Fit is done
Test end
//gnuplot stuff
My question is: how to force the code execute gnuplot stuff exactly when needed, and after proceed with the C++ code. For example:
write intro message;
plot the sin(x) function (as fast example);
wait until the gnuplot is closed;
write exiting message or do what ever AFTER the gnuplot is done.
thank you,
P
EDIT:
std::string filename = "fit.log";
if (bStartFit == true)
{
// Using Gnuplot for the data fit (command are parsed as the strings):
// 1. define the fit function.
gp << "f(x) = imfpZP * x**(-b) + c * x**(d) + g * x**(h) \n";
// 2. fit parameters first assumption.
gp << "b = 1.1; c = 0.5; d = 1.0; g = 2.0; h = 0.1 \n";
// 3. fit range.
gp << "fit [50:10000] f(x) 'agn.iimfp' via b,c,d,g,h \n";
// 4. set the logarithmic scale.
gp << "set logscale \n";
// 5. plot the fitted data.
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' \n";
std::cout << "Fit was successful" << std::endl;
}
// Opening the generated fit.log file to store the fit parameters:
std::ifstream inFIT(filename.c_str());
if (inFIT.is_open())
{
std::cout << "FIT log is opened" << std::endl;
std::string line;
int lineCounter = 0;
while (std::getline(inFIT, line))
{
lineCounter++;
}
std::cout << "Total lines: " << lineCounter << std::endl;
// Getting the five lines with fit parameters from the fit.log:
std::fstream& GoToLine(std::fstream& file, unsigned int lineNumber);
std::fstream file(filename.c_str());
GoToLine(file, lineCounter - 15);
std::string b_Line;
std::getline(file, b_Line);
std::cout << b_Line << std::endl;
std::istringstream sb(b_Line);
std::string tempStr;
char tempChar;
sb >> tempStr >> tempChar >> b
// similar code to get another 4 lines
;
It is operating system specific. I am guessing you are on Linux (or at least on some POSIX OS). Then you really should read Advanced Linux Programming. And using strace(1) could be helpful to understand what is happening.
You could use popen(3), but you probably should explicitly use system calls (they are listed in syscalls(2)) like pipe(2), fork(2), dup2(2), execve(2), waitpid(2), etc. And very probably have some event loop (e.g. around poll(2)).
BTW, you should be aware that input output is buffered, and you probably want to be sure that your gnuplot stream is regularly flushed (so use std::endl or std::flush appropriately on it). Writing a \n is not enough! You probably should code at least
gp << "plot 'agn.iimfp' w l lw 2 tit 'orig', f(x) w l lw 2 tit 'fit' "
<< std::endl;
(I have replaced some \n inside a string with an explicit use of std::endl)
I don't know much about gnuplot stream (I'm guessing it is a bit like some specialized popen but using C++ streams), but I guess that you should the gnuplot print or printerr command to communicate to your calling program the fact that a given curve has been plotted. (But then you need a genuine event loop, and you are defining a bidirectional protocol between gnuplot and your program.).
Perhaps Qt or POCO might be relevant, because they provide some notion of event loop and processes. Perhaps you might have several threads (one managing gnuplot and the other for the rest), but then you have synchronization issues.
(I don't understand enough what your program is supposed to do, and how you have coded it, so it is a blind guess; I feel your question is very unclear)
Read more about Inter-Process Communications.

Parsing strings in variable and store them to a new variable [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 9 years ago.
Improve this question
I need to parse the following, which is stored in a variable, and extract only Names. These names should be placed in a new variable (all together separated by dot (.)). Any ideas?
Name : Mike Anderson\n
Age : 43\n
Name : Andie Jameson\n
Age : 35\n
The expected output should be a variable with content: Mike Anderson.Andie Jameson
Thank you.
There will be many useful methods for your situation.
This code is just one of them. I used std::istringstream, string::find().
int main()
{
//Originally, each data is from your source.
//but, this is just sample.
std::istringstream input;
input.str("Name : Mike Anderson\nAge : 43\nName : Andie Jameson\nAge : 35\n");
//to find pattern
std::string name_pattern = "Name : ";
std::size_t found = std::string::npos;
for (std::string line; std::getline(input, line); ) {
found = line.find(name_pattern);
if (found!=std::string::npos)
{
//write on file for 'directory'
std::string only_name(line, found + name_pattern.length() );
std::cout << "\nName : " << only_name;
continue;
}
}
getchar();
}
This code will print below like,

c++ Parsing prices of a text file [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I need to parse the following file so it takes the item as a string then skip the # sign and then take the price as a float.
text file:
hammer#9.95
saw#20.15
shovel#35.40
how would I go about doing this?
In case when you have std::string in presented format you could use something like this:
std::string test {"test#5.23"};
std::cout << std::stof(std::string{test.begin() + test.rfind('#') + 1, test.end()});
Note that std::stof is C++11 function
Read the file line by line into a string. Find # and parse second part as float.
std::ifstream file("input.txt");
for (std::string line; std::getline(file, line); )
{
auto sharp = line.find('#'); // std::size_t sharp = ...
if (sharp != std::string::npos)
{
std::string name(line, 0, sharp);
line.erase(0, sharp+1);
float price = std::stof(line);
std::cout << name << " " << price << "\n";
}
}
Note: I didn't some error checking, do them yourself as an exercise. and also you should know about std::string, std::ifstream, std::getline and std::stof.