Joining 2 strings

S

Sim

Hi! Thanks for looking at my problem. I have a problem with joining 2
strings together.

Here is the problem:

I read a file into perl line by line. Each line becomes a string
element in an array. I need to recognize the first, second and third
elements of the array and join them on a single line in the output;
then join the fourth,fifth and sixth elements on the second line. My
inital plan was to use the join() function, but I had problems. The
join function does not join 2 strings on the same line. Can someone
help?(Pardon me if this is supposed to be an easy problem. I am new to
Perl)


My current stage:

my $n;
$n= 1;
open (FILE, 'sample.out');
while (defined ($_ = <FILE>)){
if ($n < 4){
$array[$n] = $_;
print join(' ',$array[$n], $array[$n+1]);#does not
work
print join(' ',@array); #does not work too
$n = $n +1 ;
}
else {
print $_;
print "time for next line";
$n =1;
}
}
close FILE;
 
G

gnari

Sim said:
My current stage:

my $n;
$n= 1;
open (FILE, 'sample.out');
while (defined ($_ = <FILE>)){

at this stage $_ contains the end of line character(s)
remove it with chomp;
chomp;
add the "\n" to every print after this

if ($n < 4){
$array[$n] = $_;
print join(' ',$array[$n], $array[$n+1]);#does not
work

this does not work because array[$n+1] is not defined at this stage


print join(' ',@array); #does not work too
define 'does not work'. do you mean the newlines?

try again

gnari
 
J

Jürgen Exner

Sim said:
Hi! Thanks for looking at my problem. I have a problem with joining 2
strings together.

Here is the problem:

I read a file into perl line by line. Each line becomes a string
element in an array.

I am not sure if putting the strings into an array is part of your
requirements or part of an attempt to solve your underlying problem
I need to recognize the first, second and third
elements of the array and join them on a single line in the output;
then join the fourth,fifth and sixth elements on the second line. My
inital plan was to use the join() function, but I had problems. The
join function does not join 2 strings on the same line. Can someone
help?(Pardon me if this is supposed to be an easy problem. I am new to
Perl)

Because in this part you don't talk about the array any more but instead you
are talking about strings and lines.
You need to be careful about what you are talking about. "Lines", "strings",
and "array elements" are quite different entities.
For example join() doesn't know and doesn't care about of lines. It takes
whatever the array contains and just concatenates it.
If those text pieces happen to be lines, then you will get a single string
containing multiple lines.

I'm assuming that you simply want to print every three lines as one single
line.
open (FILE, 'sample.out');
unless while (defined ($_ = <FILE>)){
if ($n < 4){
$array[$n] = $_;
print join(' ',$array[$n], $array[$n+1]);#does not
work
print join(' ',@array); #does not work too
[rest of script snipped]

You are not removing the newline character anywhere. Therefore even after
you join the lines into a single string, they are still three lines, just
packed into a single string.

You should be able to do something similar to this (untested, just to give
you an idea):

open (FILE, 'sample.out');
unless (eof FILE){ #warning: not stable; will fail if number of lines in
file is not dividable by 3
print chomp(<FILE>) . chomp(<FILE>) . <FILE>;
}
close FILE;

Or

open (FILE, 'sample.out');
while (<FILE>){
chomp; print;
print "\n" unless ($. % 3)
}
close FILE;


jue
 
T

Tad McClellan

Sim said:
open (FILE, 'sample.out');


You should always, yes *always*, check the return value from open():

open (FILE, 'sample.out') or die "could not open 'sample.out' $!";
 
M

Mladen Gogala

Hi! Thanks for looking at my problem. I have a problem with joining 2
strings together.

Here is the problem:

I read a file into perl line by line. Each line becomes a string
element in an array. I need to recognize the first, second and third
elements of the array and join them on a single line in the output;
then join the fourth,fifth and sixth elements on the second line. My
inital plan was to use the join() function, but I had problems. The
join function does not join 2 strings on the same line. Can someone
help?(Pardon me if this is supposed to be an easy problem. I am new to
Perl)

open (FILE,"<",'sample.out') || die "Cannot open sample.out:$!\n";
my @file=<FILE>;
chomp(@file);
print join(' ',@file[0..2]),"\n";
print join(' ',@file[3..5]),"\n";
close(FILE);

This, I believe, does exactly what you wanted to do.
 
J

John W. Krahn

Sim said:
Hi! Thanks for looking at my problem. I have a problem with joining 2
strings together.

Here is the problem:

I read a file into perl line by line. Each line becomes a string
element in an array. I need to recognize the first, second and third
elements of the array and join them on a single line in the output;
then join the fourth,fifth and sixth elements on the second line. My
inital plan was to use the join() function, but I had problems. The
join function does not join 2 strings on the same line. Can someone
help?(Pardon me if this is supposed to be an easy problem. I am new to
Perl)

You don't really need an array, you can just use string concatenation.

open FILE, '<', 'sample.out' or die "Cannot open sample.out: $!";
my $line;
while ( <FILE> ) {
chomp;
if ( $. % 3 ) {
$line .= "$_ ";
}
else {
print "$line$_\n";
$line = '';
}
}


Of course, if you really want to use an array:

open FILE, '<', 'sample.out' or die "Cannot open sample.out: $!";
my @lines;
while ( <FILE> ) {
chomp;
if ( $. % 3 ) {
push @lines, $_;
}
else {
print join( ' ', splice( @lines ), $_ ), "\n";
}
}



John
 
S

Sim

Thanks for the reply. I tried the given solutions and they all work in
a way similar to this:

Raw data from input file:
abcdefghi
jklmno
pqr

Output:

pqrmnoghi

The third line overwrite the second which in turn overwrites the
first. What I am trying to accomplish instead is to put the 3 lines
on a single line without any overwriting to give this (on a single
line):

abcdefghijklmnopqr

Can this be done?

Reason why I choose arrays is that later on I have to recognize
individual numbers from the input data and filter them based on the
criterion of a minimum value. This is the overall picture.

For example, suppose my input file contains:

"First data is 1
Second data is 2
Third data is 3"

My script should be able to read the lines, filter and take away for
example, data that read a data with < 2, and display them on the same
line:

"Second data is 2 Third data is 3" #Note that the entire first line is
filtered

I read that in arrays, I can control each of the elements, so if
"First data is 1" is an array, I can recognize "1" as an element, and
set a criterion that is has to be >2 or else it will not be displayed.

This is my first idea. Please enlighten me if there are better ways to
do it.
 
S

Sim

For clarification,

The aim of the program is to
1. Format the data such that 3 lines (containing the information about
a single record) are displayed as a single line with no overwriting.
2. Analyze the data such that a specific value in each record meets a
requirement (say above a specific value.)

Problems:
1. I cannot join/ append the 3 lines on a single line. Solutions
posted above overwrite the 3 lines, on top of one another. This is
described in my previous post (post #7).

2. As for the data analysis, I am considering using arrays to
represent each record. In this way, I can identify, via pattern
matching, the particular array elements that match a certain
requirement.

Please advise on:
Problem #1 in particular, and
Any tips for problem #2 if you have any (better solutions??)

Platform info:

ActivePerl 5.8.4 build 810

Text editor: Secure Shell Client for Workstations Version 3.2.9(build
283)
Window XP
 
J

Jürgen Exner

Sim said:
Thanks for the reply. I tried the given solutions and they all work in
a way similar to this:

Raw data from input file:
abcdefghi
jklmno
pqr

Output:

pqrmnoghi

The third line overwrite the second which in turn overwrites the
first. What I am trying to accomplish instead is to put the 3 lines
on a single line without any overwriting to give this (on a single
line):

abcdefghijklmnopqr

A wild guess: the original file was created on a Windows system and you are
processing this file on a Unix system? On Windows a logical newline consists
of a carriage return character and linefeed character while on Unix the
logical newline is only the linefeed character.
Therefore when you chomp() the line on Unix then only the LF will be
removed, leaving the CR behind.
And that in turn causes the cursor to move back to the beginning of the line
after printing each partial string, giving the appearance as if the lines
were over each other.
Can this be done?

Sure, just remove the CR, too, not only the LF.

If this is not the problem, them please post a minimal, but complete program
that demonstrates your problem.
I doubt that anyone can help you without a concrete code sample.

jue
 
T

Tad McClellan

Sim said:
The aim of the program is to
1. Format the data such that 3 lines (containing the information about
a single record) are displayed as a single line with no overwriting.
1. I cannot join/ append the 3 lines on a single line.


I can:

------------------------------------------
#!/usr/bin/perl
use warnings;
use strict;

my $line1 = "first line\n";
my $line2 = "second line\n";
my $line3 = "third line\n";

chomp $line1;
chomp $line2;
my $single_line = "$line1$line2$line3";

print $single_line;
------------------------------------------

Please advise on:
Problem #1 in particular, and


Show us a short and complete program that we can run, including
the data, and we will help you fix it.
 
A

Anno Siegel

bowsayge said:
Sim said to us:

[...]
Problems:
1. I cannot join/ append the 3 lines on a single line.
[...]

This works for bowsayge:

while (scalar @lines) {

No need for "scalar" there. The conditional of "while" is already in
scalar context (boolean, specifically).

print join " ", splice @lines, 0, 3;
print "\n";
}

You could print the lines and the line feed in a single statement. Then
"while" can become a statement modifier, and the whole thing a one-liner:

print join( " ", splice @lines, 0, 3), "\n" while @lines;

Anno
 
S

Sim

I managed to solve the problem! It is very similar to the solution Jue
posted. Here's how it goes. I wish to thank everyone who has thought
through this problem. My MSN is (e-mail address removed). I am a college
Physics student, and if you have any physics question, I might be of a
little help. =)


#!/usr/bin/perl
use strict;

open (FILE, 'sample.out') or die "could not open 'sample.out'!!! ";
open (OUTPUTFILE, '>>output.out') or die "could not open
'output.out'!!! ";
while (<FILE>) {
s/^\s*((.*\S)?)\s*$/$1/; #removes spaces before and after the
string
print (OUTPUTFILE $_, ' ');
if ($. % 3 == 0) {print (OUTPUTFILE "\n")}
}
close FILE;
close OUTPUTFILE;
 
E

Eric Bohlman

(e-mail address removed) (Sim) wrote in
I managed to solve the problem! It is very similar to the solution Jue
posted. Here's how it goes. I wish to thank everyone who has thought
through this problem. My MSN is (e-mail address removed). I am a college
Physics student, and if you have any physics question, I might be of a
little help. =)


#!/usr/bin/perl
use strict;

You want 'use warnings;' here as well.
open (FILE, 'sample.out') or die "could not open 'sample.out'!!! ";
open (OUTPUTFILE, '>>output.out') or die "could not open
'output.out'!!! ";

Error messages for files should say *why* the file couldn't be opened;
stick a $! in both messages.
while (<FILE>) {
s/^\s*((.*\S)?)\s*$/$1/; #removes spaces before and after the
string

The FAQ recommends doing this in two substitutions (neither of which
requires capturing) rather than one; it's usually faster.
 
J

Joe Smith

Sim said:
s/^\s*((.*\S)?)\s*$/$1/; #removes spaces before and after the string

That takes longer to execute than doing it in two steps.
s/^\s+//;
s/\s+$//;

See
perldoc -q "blank space"
for more info.

-Joe
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,078
Latest member
MakersCBDBlood

Latest Threads

Top