How can I comment out lines from a certain pattern and N lines onwards?
int var1;
int var2;
int var3;
int var4;
int var5;
I want to comment out 3 lines including var2 (and not according to their content!):
int var1;
// int var2;
// int var3;
// int var4;
int var5;
This requires GNU sed
sed '/^int var2;$/,+2 s.^.//.'
GNU awk (maybe other awks too) has pattern ranges:
gawk '/var2/, c==2 {$0 = "//" $0; c++} { print }' file.c
Or written readably:
/var2/, c == 2 {
$0 = "//" $0
c++
}
{
print
}
Edit:
awk --posix '/var2/, c++ == 2 {$0 = "//" $0} { print }'
works, so I think ranges are part of the AWK spec. You can also put the increment in the range pattern to save some keystrokes.
It applies the first action to lines including the one that matches var2, and after until c == 2.
It applies the second pattern to every line.
Also this script:
sed -i '2,4 s:^://:' test.txt
test.txt:
int var1;
int var2;
int var3;
int var4;
int var5;
output:
int var1;
//int var2;
//int var3;
//int var4;
int var5;
awk '/var2/{c=3}c-->0{ $0="//"$0}1' file
The following awk script can do what you ask:
echo 'int var1;
int var2;
int var3;
int var4;
int var5;
' | awk '
/^int var2;$/ {
count = 3;
}
{
if (count > 0) {
$0 = "//"$0;
count = count - 1;
};
print;
}'
This outputs:
int var1;
//int var2;
//int var3;
//int var4;
int var5;
The way it works is relatively simple. The counter variable c decides how many lines are left to comment. It starts as 0 but when you find a specific pattern, it gets set to 3.
Then, it starts counting down, affecting that many lines (including the one that set it to 3).
If you're not that worried about readability, you can use the shorter:
awk '/^int var2;$/{c=3}{if(c>0){$0="//"$0;c=c-1};print}'
Be aware that the count will be reset whenever the pattern is found. This seems to be the logical way of handling:
int var1; ----> int var1;
int var2; //int var2;
int var3; //int var3;
int var2; //int var2;
int var3; //int var3;
int var4; //int var4;
int var5; int var5;
If that's not what you wanted, replace count = 3; with if (count == 0) {count = 3;}; or use:
awk '/^int var2;$/{if(c==0){c=3}}{if(c>0){$0="//"$0;c=c-1};print}'
for the compact version.
Related
Is it possible to concatenate integers without converting to String first?
int _test1 = 123;
int _test2 = 456;
print(int.parse(("$_test1"+"$_test2"))); // 123456
you can do it like this
void main() {
int _test1 = 123;
int _test2 = 456;
int pow = 10;
while(_test2 >= pow)
pow *= 10;
print(_test1 *pow + _test2);
}
source : How to concatenate two integers in C
Hi i have been wondering if there is a way in which to convert binary numbers into decimal fractions.
I know how to change base as an example through this code
String binary = "11110010";
//I'd like to change this line so it produces a decimal value
String denary = int.parse(binary, radix: 2).toRadixString(10);
If anyone still wondering how to convert decimal to binary and the inverse:
print(55.toRadixString(2)); // Outputs 110111
print(int.parse("110111", radix: 2)); Outputs 55
int binaryToDecimal(int n)
{
int num = n;
int dec_value = 0;
// Initializing base value to 1, i.e 2^0
int base = 1;
int temp = num;
while (temp) {
int last_digit = temp % 10;
temp = temp / 10;
dec_value += last_digit * base;
base = base * 2;
}
return dec_value;
}
int main()
{
int num = 10101001;
cout << binaryToDecimal(num) << endl;
}
This is my c++ solution but you can implement any language
I've checked other similar posts but I think I just need a second set of eyes. This file is for the lex Unix utility.
I created a makefile and this is the error I receive:
gcc -g -c lex.yy.c
cxref.l:57: error: expected ‘;’, ‘,’ or ‘)’ before numeric constant
make: *** [lex.yy.o] Error 1
Line 57 is just inside the void inserID() function near the top.
Here is the code:
%{
#include <stdio.h>
#include <string.h>
char identifier[1000][82];
char linesFound[100][100];
void insertId(char*, int);
int i = 0;
int lineNum = 1;
%}
%x comment
%s str
%%
"/*" BEGIN(comment);
<comment>[^*\n]* /* eat anything that's not a '*' */
<comment>"*"+[^*/\n]* /* eat up '*'s not followed by '/'s */
<comment>\n ++lineNum;
<comment>"*"+"/" BEGIN(INITIAL);
"\n" ++lineNum;
auto ;
break ;
case ;
char ;
continue ;
default ;
do ;
double ;
else ;
extern ;
float ;
for ;
goto ;
if ;
int ;
long ;
register ;
return ;
short ;
sizeof ;
static ;
struct ;
switch ;
typedef ;
union ;
unsigned ;
void ;
while ;
[*]?[a-zA-Z][a-zA-Z0-9_]* insertId(yytext, lineNum);
[^a-zA-Z0-9_]+ ;
[0-9]+ ;
%%
void insertId(char* str, int nLine)
{
char num[2];
sprintf ( num, "%d", nLine);
int iter;
for(iter = 0; iter <= i; iter++)
{
if ( strcmp(identifier[iter], str) == 0 )
{
strcat( linesFound[iter], ", " );
strcat( linesFound[iter], num );
return;
}
}
strcpy( identifier[i], str );
strcat( identifier[i], ": " );
strcpy( linesFound[i], num );
i++;
}
Your problem is:
%s str
There is a reason that it's normal to write condition names in CAPS: it makes them look like macros, which is exactly what they are.
So
void insertId(char* str, int nLine)
get macro expanded to something like:
void insertId(char* 2, int nLine)
and the compiler complains that 2 is not really expected at that point in the declaration.
Say I have an integer, 9802, is there a way I can split that value in the four individual digits : 9, 8, 0 & 2 ?
Keep doing modulo-10 and divide-by-10:
int n; // from somewhere
while (n) { digit = n % 10; n /= 10; }
This spits out the digits from least-significant to most-significant. You can clearly generalise this to any number base.
You probably want to use mod and divide to get these digits.
Something like:
Grab first digit:
Parse digit: 9802 mod 10 = 2
Remove digit: (int)(9802 / 10) = 980
Grab second digit:
Parse digit: 980 mod 10 = 0
Remove digit: (int)(980 / 10) = 98
Something like that.
if you need to display the digits in the same order you will need to do the module twice visa verse this is the code doing that:
#import <Foundation/Foundation.h>
int main (int argc, char * argv[])
{
#autoreleasepool {
int number1, number2=0 , right_digit , count=0;
NSLog (#"Enter your number.");
scanf ("%i", &number);
do {
right_digit = number1 % 10;
number1 /= 10;
For(int i=0 ;i<count; i++)
{
right_digit = right_digit*10;
}
Number2+= right_digit;
Count++;
}
while ( number != 0 );
do {
right_digit = number2 % 10;
number2 /= 10;
Nslog(#”digit = %i”, number2);
}
while ( number != 0 );
}
}
return 0;
}
i hope that it is useful :)
I have a question about using fgetc to count characters in a specified file.
How do you use it when you have to count character types separately? Like for example I only want to count the number of lowercase characters only, or number of spaces, or punctuations, etc? Can someone show a brief example? Thank you
I tried to do this program that would hopefully count the total number of characters, how do you squeeze in though the number of the separate character types? I'm not exactly sure if this program is correct
#include <stdio.h>
int main (void)
{
//Local declarations
int a;
int count = 0;
FILE* fp;
//Statements
if (!(fp = fopen("piFile.c", "r")))
{
printf("Error opening file.\n");
return (1);
}//if open error
while ((a = fgetc (fp)) != EOF)
{
if (a != '\n')
count++;
printf("Number of characters: %d \n", count);
else
printf("There are no characters to count.\n");
}
fclose(fp);
return 0;
}
Read up on these functions:
int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
and you'll see right away how to do it.
In your while, you can use if statements for each character you want to check.
if(isalnum(a){
counta++;
}
else if(isalpha(a)){
countb++;
}
else if(isascii(a)){
countc++;
}