I want to replace the whitespaces with string "IIT".I tried using loop in my string and when I encountered whitespace I tried to replace it with the given string. But the whitespace is similar to a single character in string so it is not replacing with a word so please help me out how can I replace my withspace with given word.Thank you .
The trick to replacing a single character in a string with multiple characters without using a second string is to process the string from end to beginning.
First, go through the string once, counting how many characters there are to be replaced. Then compute how many extra characters your replacement will add. Make sure the string has enough space allocated to handle the new characters. Then starting with the last character in the string, move each character to the new end of the string, replacing specific characters with your replacement characters.
Example, replace x with zz
xcfdxdfxg---
(dashes are space allocated for the string, but not currently used, and of course there should be a \0 at the end of the string, which also properly gets moved)
xcfdxdfxg---
xcfdxdfx---g
xcfdxdf--zzg
xcfdxd--fzzg
xcfdx--dfzzg
xcfd-zzdfzzg
xcf-dzzdfzzg
xc-fdzzdfzzg
x-cfdzzdfzzg
zzcfdzzdfzzg
C String manipulation Standard Library APIs are not that strong to simply replace a Strings. So, You can use lexical analyzer utilities like Flex which give a REGEX power to find and manipulate your texts.
Here is a program which compresses multiple blanks and tabs down to a single blank, and throws away whitespace found at the end of a line:
%%
[ \t]+ putchar( ' ' );
[ \t]+$ /* ignore this token */
Flex will generate a C program for you, which do all the work.
Tutorial: http://alumni.cs.ucr.edu/~lgao/teaching/flex.html
You cannot since you said that you want to replace the whitespaces with "IIT". Here "IIT" has 3 bytes and the whitespace is a single byte. So how can you store it. You can do this by allocating more memory before placing the string "IIT" . See realloc for more information on this.
Related
Originally I had File.foreachf(name, "\n\n") in my code. This worked fine with my own test files, but now using real data I'm running into those files potentially also using \r\n instead of \n\n.
I would like to split a file into chunks of data using the blank line as the delimiter.
Alternatively I also tried to use File.readlines(fname), however this will only split the file by the line and I can't then further sub-split it, even if the blank lines are now empty elements because I used .chomp.
Is there a way to split the file according to new lines as the delimiter that accounts for both \r\n and \n\n?
Thanks
You could write the following.
str =<<~_
Little Miss Muffet
sat on her
tuffet
eating her curds
and whey
_
str.split(/(?:^\r?\n)+/)
#=> ["Little Miss Muffet\nsat on her\n",
# "tuffet\n",
# "eating her curds\nand whey\n"]
The regular expression reads, "match one or more (+) contiguous
empty lines having line terminators of \r\n or \n.
You can write your regex to account for either \r or \n characters:
string.split(/[\r\n]\n/)
The brackets [] indicate any character within them can match, so that would mean the regex matches either \r or \n for the first character.
I am trying to read below CSV file content line by line in Perl.
CSV File Content:
A7777777.A777777777.XXX3604,XXX,3604,YES,9
B9694396.B216905785.YYY0018,YYY,0018,YES,13
C9694396.C216905785.ZZZ0028,ZZZ,0028,YES,16
I am able to split line content using below code and able to verify the content too:
#column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
I am also trying to find the second part on the first column of CSV file (i.e., A777777777 or B216905785 or C216905785) – the first column delimited with . using the below code and I am unable to get it.
Instead, just a new line printed.
my ($v1, $v2, $v3) = split(".", $column_fields1[0]);
print $v2,"\n";
Can someone suggest me how to split the array element and get the above value?
On my functionality, I need the first column value altogether at someplace and just only the second part at someplace.
Below is my code:
use strict;
use warnings;
my $dailybillable_tab_section1_file = "./sql/demanding_01_T.csv";
open(FILE, $dailybillable_tab_section1_file) or die "Could not read from $dailybillable_tab_section1_file, program halting.";
my #column_fields1;
my #column_fields2;
while (<FILE>)
{
chomp;
#column_fields1 = split(',', $_);
print $column_fields1[0],"\n";
my ($v1, $v2, $v3) = split(".",$column_fields1[0]);
print $v2,"\n";
if($v2 ne 'A777777777')
{
…
…
…
}
else
{
…
…
…
}
}
close FILE;
split takes a regex as its first argument. You can pass it a string (as in your code), but the contents of the string will simply be interpreted as a regex at runtime.
That's not a problem for , (which has no special meaning in a regex), but it breaks with . (which matches any (non-newline) character in a regex).
Your attempt to fix the problem with split "\." fails because "\." is identical to ".": The backslash has its normal string escape meaning, but since . isn't special in strings, escaping it has no effect. You can see this by just printing the resulting string:
print "\.\n"; # outputs '.', same as print ".\n";
That . is then interpreted as a regex, causing the problems you have observed.
The normal fix is to just pass a regex to split:
split /\./, $string
Now the backslash is interpreted as part of the regex, forcing . to match itself literally.
If you really wanted to pass a string to split (I'm not sure why you'd want to do that), you could also do it like this:
split "\\.", $string
The first backslash escapes the second backslash, giving a two character string (\.), which when interpreted as a regex means the same thing as /\./.
If you look at the documentation for split(), you'll see it gives the following ways to call the function:
split /PATTERN/,EXPR,LIMIT
split /PATTERN/,EXPR
split /PATTERN/
split
In three of those examples, the first argument to the function is /PATTERN/. That is, split() expects to be given a regular expression which defines how the input string is split apart.
It's very important to realise that this argument is a regex, not a string. Unfortunately, Perl's parser doesn't insist on that. It allows you to use a first argument which looks like a string (as you have done). But no matter how it looks, it's not a string. It's a regex.
So you have confused yourself by using code like this:
split(".",$COLUMN_FIELDS1[0])
If you had made the first argument look like a regex, then you would be more likely to realise that the first argument is a regex and that, therefore, a dot needs to be escaped to prevent it being interpreted as a metacharacter.
split(/\./, $COLUMN_FIELDS1[0])
Update: It's generally accepted among Perl programmers, that variable with upper case names are constants and don't change their values. By using upper case names for standard variables, you are likely to confuse the next person who edits your code (who could well be you in six months time).
I want to make sure user input has:
Two letters at the start
And the support for any number of optional space characters following these two letters.
Additionally, if at least one space character is provided, optionally allow letters, digits or . characters after it.
Here's the expression I currently have:
[a-zA-Z][a-zA-Z] (?\\s+ (?a-zA-Z0-9.))
And here's my thinking:
[a-zA-Z][a-zA-Z] makes sure the input begins with at least two letters
(?\\s+ begins an optional statement. This optional statement must start with at least one space (I'm on windows which is why I have two slashes).
(?a-zA-Z0-9.)) finishes the optional statement. So, if at least one space is provided, at least one optional character, number or . can also be added.
For instance, ab, ab , ab .s, and ab .asd2 should all be valid inputs.
How do I solve this problem?
The problem with your attempt is that both (?\ and (?a are syntax errors. If you want to create an optional group, you need to write (...)?, not (?...).
(The other issue is that a-zA-Z0-9 in your regex matches literally because it's not part of a character class.)
Besides, \s (to match whitespace) does not exist in POSIX regex.
My suggestion:
^[a-zA-Z]{2}( +[a-zA-Z0-9.]*)?$
That is:
^ # beginning of string
[a-zA-Z]{2} # exactly two letters
(
\ + # one or more spaces
[a-zA-Z0-9.]* # zero or more of: letters, digits, or dot
)? # ... this group is optional
$ # end of string
As an example I have a text file that includes this text: "name?"
I want to save this String only as name?
I tried ("%["]"), but this doesn't work.
Which function should I use?
The scanf and fscanf functions work exactly the same. Your format is however wrong.
Try instead e.g. "\"%[^\"]\"" as your format.
The first and last " is to mark the start and end of the string. Inside the string one can't use plain double-quote as that will end the string. So these have to be escaped using the backslash.
If we break down the format string into its three main components:
\" - This matches the literal double-quote
%[^\"] - This matches a string not containing the double-quote (the negation is what the ^ does)
Lastly \" again, to match the end quote of your input
I want to control the printf() functions output format with dynamic parameter, just as the code showed below:
#include<stdio.h>
int main(int argc,char ** argv)
{
printf(argv[1],"hello,world");
return 0;
}
Then I compile and run it:
$ gcc -o test test.c
$ ./test "\t%s\n"
The result is strange:
\thello,world\n$
Why "\n" and "\t" has no effect?
Because the escapes you use (\t and \n) are interpreted inside string literals by the C compiler, not by printf(). This:
const char *newline1 = "\n", newline2[] = { '\n', 0 };
would generate the exact same content in newline1 and newline2, regardless of whether or not these are ever passed to printf(); the strings are there anyway.
Your code behaves just like this would:
printf("\\t%s\\n", "hello,world");
Here, I've double-escaped the special characters to generate a string with the same actual content as your command-line argument, i.e. "\t%s\n" (six characters rather than four).
The proper way to dynamically control printf() is to build the format string in code. If you want C-like escapes at runtime, you need to interpret them yourself in some way.
The sequence \n in a string or character literal in C/C++ is a single byte with the numeric value 10 (on an ASCII system). When output on a terminal (try putchar(10)!) it just sets the output position for the next character on the terminal to the beginning of the next line (on *nix; on MacOS, I think, you need an additional \r, or 13 for carriage return to have the output position at the beginning of the line).
Similarily, a \t is the notation for a single byte with the value 9, which makes most terminals advance their cursor to the next tabulator position.
What you need is to insert a single byte of these values in the command line. How that can be done depends on your shell; in bash you can keep the shell from interpreting special characters by pressing Ctrl-V beforehand. That outputs e.g. a tab, displayed by showing some empty space (instead of making the shell show possible string continuations or whatever tab does in bash). bash strings in single or double quotes can include newlines without further efforts -- simply press enter.
Here is a sample run in a cygwin terminal with bash. I pressed the indicated keys at the indicated positions; I finished the command as usual with [return] after the closing single quote on the second line.
pressed Ctrl-v,[TAB] here | pressed [return] there
v v
$ ./printf-arg.exe ' %s
> '
hello,world
The > in the second line was output by the shell after I pressed enter within the string delimited by single quotes. (Which inserts a newline in the string). It is an indication that the string being edited is continued on that line.
As an aside, it is probably unsafe to use command line arguments this way in potentially hostile environments. Carefully crafted strings could access memory which is not meant to be accessed and e.g. redirect return addresses, thus corrupting the program.
It's because the compiler handles the escape sequences like "\n" etc., and it does it in string or character literals only.
if you pass interpreted "\t%s\n" to command it will work. However it is tricky to construct such string in shell. The easiest way I know is:
./test $'\t%s\n'
See ANSI quoting in man bash for the $'magick'