Extracting between two strings with sed until the first occurrence - sed

Can someone explain why I am getting different outcome while using the same command? I have 2 c++ files:
1st one(ax.h)
int iseven(int a);
int sum(float a, int b);
2nd one(ax.cpp)
//Definicija
int iseven(int a) {
if (a%2==0){
return 1;
else
return 0;}
float sum(float a, int b) {
return a + (float)b;
}
Why is it when I use the command:
sed -n '/iseven/,/}/p' ax.cpp
My output only does what I want and it print the text between iseven and the first occurrence of} ->
int iseven(int a) {
if (a%2==0){
return 1;
else
return 0;}
But when I use the same command(sed -n '/iseven/,/)/p' ax.h) on my 1st file(ax.h), it prints everything out:
int iseven(int a);
int sum(float a, int b);
And what I was expecting was int iseven(int a);

When you use
/start/,/end/ as the address in a sed command, it starts searching for end on the next line after the match of start. So you can't use a pattern range when the end pattern is on the same line as the start pattern.
You could just use /iseven/p to match just those lines in ax.h, unless you need to allow for declarations to be spread over multiple lines. If you need to handle both single-line and multi-line declarations, there might be a way using the hold space, but I'm not an advanced enough sed user to show how to do it.

Related

How to Build a String in DRL file

String i;
String j;
String k;
i.concat(j).concat(k);
Now I want to write this in DRL file.
rule "X"
when
xx : X(i.concat(j).concat(k))
I am new with Drools, please help me to build the string inside the when condition in DRL file.
I can't think of any good reason to want to do this. The "when" clause is for checking conditions (broadly equivalent to an "if" statement.)
Now, assuming you have some input object X that looks like this:
class X {
String i;
String j;
String k;
}
... you can create a String that's the concatenated form of the i, j and k values in a few ways.
One way would be like this:
rule "Str from x - v1"
when
X( $i: i, $j: j, $k: k )
$str: String() from $i.concat($j).concat($k)
then
// do something with $str
end
If you're just trying to compare to the concatenated value, you could just, you know, concatenate the fields at the time of comparison instead of assigning them to a variable:
rule "Just compare it"
when
X( $i: i, $j: j, $k: k )
SomethingElse( myStr == $i + $j + $k )
then
// ...
end
Since $i, $j, and $k values are immutable (since they're Strings), you can concatenate them at any time and always get the same result, so it's not even a case of "the values might change from under me". So while there's very little reason to ever do this, here's how you'd go about it.

swscanf return wrong result

i use embarcadero Xe7. I found that swscanf returns wrong result.
example
int _tmain(int argc, _TCHAR* argv[])
{
char *t1= " ";
wchar_t *t2= L" ";
int i1, i2;
i1= -1;
i1= sscanf (t1, "%d", &i2);
if(i1!=EOF)
printf("sscanf output i1=%d i2=%d\n", i1, i2);
else
printf("sscanf EOF\n");
i1= swscanf(t2, L"%d", &i2);
if(i1!=EOF)
printf("swscanf output i1=%d i2=%d\n", i1, i2);
else
printf("swscanf EOF\n");
return 0;
}
the result:
sscanf EOF
swscanf output i1=1 i2=0
The first result is ok. But the second is wrong.
This is a bug. This behaviour of swscanf() contradicts the C11 standard:
7.29.2.4/3 The swscanf function returns the value of the macro EOF if an input failure occurs before the first conversion (if any) has
completed. Otherwise, the swscanf function returns the number of input
items assigned, which can be fewer than provided for, or even zero, in
the event of an early matching failure.
Clearly, here it fails before the first conversion has started.
It also contradicts the XE7 sscanf/swscanf documentation:
If sscanf attempts to read at end-of-string, it returns EOF.
And again, clearly, here it attempts to read end of string.
There is no bug report for now on EDN. You should file one.
*Workaround: process the cases i1==EOF and i1==0 together, as in both cases you can't exploit the content of any variable.

Merging function declarations

I have following requirement in my project,
qualifier1 foo(int a, int b, int c); -- In header file header_1.h
qualifier2 foo(int a, int b, int c); -- In header file header_2.h
Where, qualifier1 is not equal to qualifier2.
Can I document the function declaration as shown below using Doxygen,
qualifier1 qualifier2 foo(int a, int b, int c);
Thanks.
INPUT_FILTER option with sed utility solved my problem as shown,
INPUT_FILTER = "sed -e 's/_qualifier1_ foo/_qualifier1_ _qualifier2_ foo/"
** Note the \ (escape) character use to avoid unknown character errors.

Perl - Pattern contains new line

I am trying to grab all functions from a C file in a perl script.
Pattern example :
function return type
function name (function parameters)
{
So far I have: m/^(.*)\((.*)\)/
But this grabs functions inside as well, such as if statements, so I was hoping to match for the { as well since that would eliminate all internal functions but m/^(.*)\((.*)\)/\n\{/
doesn't work.
How do I match for the \n{ i.e the { in the next line, so that I can catch
add(int a, int b)
{
... but avoid, say
if(a = b)
Have a look at C::Scan over at CPAN
There are no asterisks you want to match in the C source. Therefore, remove the backslashes before asterisks in the pattern.
The following might be closer to what you want:
m/^(.*?\(.*?\))\s*\n{/m

Scanf missed line

I wrote a test program which should take in a 3x3 matrix of characters and output the entered matrix. However, I have to enter 4 lines in order for the program to produce the corresponding matrix. I have looked up problems on the scanf function, but none of the solutions I tried seemed to work...Could you help me out with this?
My code:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
char a[3][3];
int i,j;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
}
scanf("\n");
}
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
printf("%c",a[i][j]);
}
printf("\n");
}
system("PAUSE");
return(0); }
scanf("%c",...) get the whitespaces and the \n. You can solve it in many ways:
If you read like a b c
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
cin.get(); //Get the spaces after each character and the \n at the end of each line
}
}
or you can simple use cin (read char/string inputs with scanf is always a problem)
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
cin >> a[i][j];
}
}
if you are reading like abc, you only have to substitute your scanf("\n") for a cin.get()
#João Menighin's answer surely works. If you want to avoid c++, this would work:
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf(" %c",&a[i][j]);
}
}
Although it would ignore ALL whitespace: both abc and a b c would be interpreted to be equivalent.
try adding a white space in your scanf right after the "
scanf(" %c",&a[i][j]);
I had the same problem in a two-dimension matrix and it worked for me.
I have no idea why though!!! I just spent 1 hour in front of my laptop trying different things...
Have tried your and IT WORKED. Although, I did make a few changes per comments:
#include <stdio.h> // added, but that shouldn't matter
main()
{
char a[3][3];
int i,j;
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
scanf("%c",&a[i][j]);
}
//scanf("\n"); // not necessary, see below
}
for(i=0;i<3;++i)
{
for(j=0;j<3;++j)
{
printf(" %c",a[i][j]);
}
printf("\n");
}
return(0);
}
Compiled and ran this code on Eclipse/Microsoft C Compiler and entered series of characters followed by enter.
abcdefghi
a b c
d e f
g h i
The point of confusion might be that scanf pulls the data from a console buffer. Typically, (although you can work around this) that buffer is returned to your program when you press enter. Also, the format specifier of %c also accepts blanks. Thus, I tried a second run with the following input and output.
a b c d e
a b
c
d e
You can tell the spaces were read and stored as well as the letters.
Hope this helps.