/    Sign up×
Community /Pin to ProfileBookmark

problem with reading a csv file.

Hi,

I am using fgetcsv to read my csv files but i have a problem.

In the csv i have a description field, now that description field uses comma’s

The commas that need to be ignored have a infront of them and delimiter is a comma on its own.

Any idea how i can get it to ignore comma’s with a $ignoredelimiter variable in it

[code=php]
$ignoredelimiter = “”;

while (($line < $previewLimit) && ($data = fgetcsv($myFile, 1024, $delimiter)))

[/code]

Many Thanks
Adam

to post a comment
PHP

18 Comments(s)

Copy linkTweet thisAlerts:
@NogDogAug 16.2005 — In a CSV file, any field which contains a comma must be quoted. Any field which has quotes must be quoted with the actual content quotes being doubled up. So, for the following fields...
<i>
</i>1. test
2. this is, a test
3. this is a "test", so to speak

...the CSV file should be...
<i>
</i>test,"this is, a test","this is a ""test"", so to speak"

(Note that it is OK though not necessary to quote the first field, too.)
Copy linkTweet thisAlerts:
@k0r54authorAug 17.2005 — the big problem is that unfortunatly i do not have control on the csv they are from a client? Stupid i know, but unfortunatly the way it is ?

Thanks for your help
Copy linkTweet thisAlerts:
@NogDogAug 17.2005 — the big problem is that unfortunatly i do not have control on the csv they are from a client? Stupid i know, but unfortunatly the way it is ?

Thanks for your help[/QUOTE]

Ugh. That makes life difficult if they're not going to supply you with a proper CSV format. ?
Copy linkTweet thisAlerts:
@k0r54authorAug 17.2005 — tell me about it, people just expect me to be able to just make things work still ?

Any Ideas
Copy linkTweet thisAlerts:
@NogDogAug 17.2005 — OK, that was a fun challenge. ? What I've come up with is creating an temporary CSV file "on the fly", and converting the user's pseudo-CSV file into a proper one, then using the fgetcsv function to read from it. (This would be easier with PHP5 (I'm on 4) since it has a fputcsv() function, but this should be more portable anyway.) If/when ready to try this with your actual input file, just delete/comment out the section where I create the test data, and change the name of the input file on the line that reads [b]$csv = file($testFile) or die("Unable to read in CSV file");[/b] (and eventually get rid of the various [b]# DEBUG ... # /DEBUG[/b] sections).
[code=php]
<?php
# create test data:
$testFile = "test.csv";
$test =fopen($testFile, 'w') or die("unable to create test file");
for($i=1; $i<=3; $i++)
{
fputs($test, 'Line '.$i.',This is a "test".,It is, only, a test.'."n");
}
fclose($test);
# END create test data
### DEBUG
echo "<pre>TEST DATA:n";
readfile($testFile);
echo "</pre>";
### /DEBUG
# create temporary CSV file
$tmpCSV = "tmp".uniqid('X').".csv";
$tmp = fopen($tmpCSV, 'w') or die("unable to open temp file");
$csv = file($testFile) or die("Unable to read in CSV file");
foreach($csv as $key => $line)
{
$line = str_replace(',', '[comma]', trim($line));
$fields = explode(',', str_replace('"', '""', $line));
$out = '';
foreach($fields as $value)
{
$out .= '"'.str_replace('[comma]',',',$value).'",';
}
$out = rtrim($out, ',') . "n";
fputs($tmp, $out);
}
fclose($tmp);
# END create temporary CSV file
### DEBUG
echo "<pre>TMP FILE:n";
readfile($tmpCSV);
echo "</pre>";
### /DEBUG
# use the tmp file as our CSV file now:
$myFile = fopen($tmpCSV, 'r') or die("unable to open tmp csv file for reading");
# hard code vars for testing:
$line = 1;
$previewLimit = 2;
while (($line < $previewLimit) && $data = fgetcsv($myFile, 1024))
{
# do stuff with array $data here
# DEBUG
echo "<pre>";
print_r($data);
echo "</pre>n";
# /DEBUG
}
fclose($myFile);
# delete tmp file (and test data file):
unlink($tmpCSV);
unlink($testFile);
?>
[/code]
Copy linkTweet thisAlerts:
@k0r54authorAug 17.2005 — very impressed ?,

I appreciate the time you put into it, i will adapt it and hopefully resolve my problem.

Thanks again

adam
Copy linkTweet thisAlerts:
@k0r54authorAug 17.2005 — ok just have another simple question about it, i have a permisions problem on deleting the tmp file get this msg

Warning: unlink() [function.unlink]: Permission denied in **location** on line 53

it is the line to unlink the tmpcsv..

Any ideas around it, otherwise i am very impressed.

What is the speed of it like if the csv is about a mb, will it still do it quite fasT?

Thanks

Adam
Copy linkTweet thisAlerts:
@NogDogAug 17.2005 — LOL - I was just getting ready to post this...

I was thinking that the whole temp file thing is unnecessary (and just another possible point of failure), but I was so zeroed in on the whole CSV compatibility thing I got stuck on that. Here's a version with no temp file and no CSV functions - and it should therefore even execute a bit faster, I would think.
[code=php]
<?php
# create test data:
$testFile = "test.csv";
$test =fopen($testFile, 'w') or die("unable to create test file");
for($i=1; $i<=3; $i++)
{
fputs($test, 'Line '.$i.',This is a "test".,It is, only, a test.'."n");
}
fclose($test);
# END create test data
### DEBUG
echo "<pre>TEST DATA:n";
readfile($testFile);
echo "</pre>";
### /DEBUG
$csv = file($testFile) or die("Unable to read in CSV file");
foreach($csv as $line)
{
$fields = explode(',', str_replace(',', '[comma]', trim($line)));
foreach($fields as $key => $value)
{
$fields[$key] = str_replace('[comma]',',',$value);
}
$dataArray[] = $fields;
}
# END create temporary CSV file
### DEBUG
echo "<pre>$data array:n";
print_r($dataArray);
echo "</pre>";
### /DEBUG
# use the tmp file as our CSV file now:
$line = 1;
$previewLimit = 2;
while (($line < $previewLimit) && $data = array_shift($dataArray))
{
# do stuff with array $data here
# DEBUG
echo "<pre>";
print_r($data);
echo "</pre>n";
# /DEBUG
}
# delete test data file:
unlink($testFile);
?>
[/code]
Copy linkTweet thisAlerts:
@k0r54authorAug 17.2005 — Thank you lol,

I was going over the code and didn't think there was a need to the tmpfile, although it does sound apealing actually have the correct csv for it :d

I will post up any updats i do

Thanks

Adam
Copy linkTweet thisAlerts:
@k0r54authorAug 20.2005 — Hi nogdog,

I have put your create csv into a function and it works so so nicley :d (thank you for that) ?

Ok anyway i come across a small problem lol.

It fails import on these parts of the tmpCSV file, i dont quite understand on how to change it, but ill pop the function i got below.

Original - German Flag "Go Germany"

tmpCSV - "German Flag ""Go Germany"""

Original - Cow Skin "I'm moody"

tmpCSV - "Cow Skin ""I'm moody"""

[code=php]
function CreateTmpCSV($CSV) {
$tmpCSV = "tmp".uniqid('X').".csv";
$tmp = fopen($tmpCSV, 'w') or die("unable to open temp file");
$csv = file($CSV) or die("Unable to read in CSV file");
foreach($csv as $key => $line) {
$line = str_replace(',', '[comma]', trim($line));
$fields = explode(',', str_replace('"', '""', $line));
$out = '';

foreach($fields as $value){
$out .= '"'.str_replace('[comma]',',',$value).'",';
}

$out = rtrim($out, ',') . "n";
fputs($tmp, $out);
}

fclose($tmp);

return $tmpCSV;
}
[/code]


I tried messing about with it, but with no luck. i will keep trying but im sure you can probably do it right away lol.

** Added **

After playing with it, i found another problem. If the file does have the correct csv way it puts the double speach marks like above which obviously cause a problem.

I think im gettin close to it in the idea of once it put all singles speach to double perhaps turning it back. but it is a shot in the dark :s

k0r54
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — well this has been a gd bit of fun ?

I have sussed both the problems and ill explain how, firstly here is the code : -

[code=php]
function CreateTmpCSV($CSV) {
$tmpCSV = "tmp".uniqid('X').".csv";
$tmp = fopen($tmpCSV, 'w') or die("unable to open temp file");
$csv = file($CSV) or die("Unable to read in CSV file");
foreach($csv as $key => $line) {
$line = str_replace(',', '[comma]', trim($line));
$fields = explode(',', $line);
$out = '';

foreach($fields as $value){
if ((substr($value, -1) == '"') && (substr($value, 0 ,1) == '"')) {
$out .= ''.str_replace('[comma]',',',$value).',';
} else {
$out .= '"'.str_replace('[comma]',',',$value).'",';
}
}

$out = rtrim($out, ',') . "n";
fputs($tmp, $out);
}

fclose($tmp);

return $tmpCSV;
}
[/code]


Ok i first replaced this line : -

$fields = explode(',', str_replace('"', '""', $line));

with just: -

$fields = explode(',', $line);

? i wasn't to sure what that bit done apart from turn single speach marks into double so that got rid of the go germany thing.

The thing then was to recognise if it already has the proper csv format.

After about an hour just put in an if statment to check if the first and last charactors of $value in the foreach statement was a speachmark.

The only point of failure i see is if there is a field that has speach marks around it, when the other actually dont. i.e.

1,adam,k0r54,"my address",so "on", so on

as it will pick up my address as a proper csv when it actually isn't although the so "on" it will realise its not because it doesn't have a speach mark at the beginin and end, just the end.

Ok, well if anyone can think of a way to get round that little problem then please let me know, although thankfully none of the csv i am doing this for have that ..... yet :eek:

Ok, well let me know what you think or if you think you can improve on what i have done ?

cheers

k0r54
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — WHAT IS THE CHANCES :mad:

ok i have this: -

Your able to position your racket in three different positions, "left", "center" and "right" and move up and down

the , "left", stops it :mad:

ok, well im out of ideas for the moment lol, i will try but i doubt i can get this one.

cheers

k0r54
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — ok i have figured that bit out ?

but i have come accross another problem: -

I have attached a sml txt file, that is a part of the RLY messed up csv i need to sort out. (open it in notepad to see what im on bout)

It is a funny little square with a infront of it that i am pretty sure is a symbol for return (or next line) the problem is i cant do a str_replace on it becuase i cant find the sysmbol.

Any ideas on how i could str_replace it as i need to get rid of the aswell.

I will then post up the final code for your views or adaptions.

cheers

k0r54

[upl-file uuid=a37ff453-7407-4250-bb60-d32a9d18b07b size=417B]javagamessrt.txt[/upl-file]
Copy linkTweet thisAlerts:
@NogDogAug 21.2005 — Looks to me like it's ending each line with a "" followed by a newline character. If you want to leave the newline in place to mark the end of a line, then...
[code=php]
$string = str_replace("\n", "n", $string);
[/code]

Otherwise, if you want to replace the whole thing with a space...
[code=php]
$string = str_replace("\n", " ", $string);
[/code]
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — nogdog,

Unfortunatly that did not do it :s

Well this is the last problem, (i think) but i think this is a function deffo worth keeping.

Well here is the fully commented and fully working function apart from this line: -

// change the newlinecharactor to just a new line

$line = str_replace('n', ' ', $line);

so if any knows how to do that then please let me know, the line that fails is in the attachment in the previous post.

[code=php]
function CreateTmpCSV($CSV) {

// create tmp filename
$tmpCSV = "tmp".uniqid('X').".csv";

// open tmp CSV
$tmp = fopen($tmpCSV, 'w') or die("unable to open temp file");

// put the CSV contents into a variable
$csv = file($CSV) or die("Unable to read in CSV file");

// seperate every line of the CSV file
foreach($csv as $key => $line) {

// change the " to [speach] (mainly so we can run the query below)
$line = str_replace('"', '[speach]', trim($line));

// change the newlinecharactor to just a new line
$line = str_replace('\n', ' ', $line);

// variable to check if the csv file has the proper speach mark formation
$properCSV = (trim((substr($line, -8) == '[speach]')) && trim((substr($line, 0 ,8) == '[speach]')));

// if the csv file is with the proper speach marks
if ($properCSV) {

// If so then just explode where the , is surrounded by [speach] because otheriwse it will split if the field has a comma in the txt
$fields = explode('[speach],[speach]', $line);
} else { // as the document is inproper then : -

// replace the , for [comma], this is because the inproper csv tries to ignore , by puting a infront of it (we put it as [comma] so it dont get exploded)
$line = str_replace(',', '[comma]', trim($line));

// replace the [speach] for " so that we can locate and determine what ones to ignore (we can do this because the csv does not have the proper " formation)
$line = str_replace('[speach]', '"', trim($line));

$fields = explode(',', $line);
}

echo $line . '<br><br>';
$out = '';

// seperate every field of the CSV file
foreach($fields as $value) {

if ($properCSV) {

$out .= '"'.str_replace('[comma]',',',$value).'",';

// change the [speach] back to "
$out = str_replace('[speach]','"',$out);

// because it is the proper csv format, it already has " at the beginin and end of the $line and because we have added another one we have doubles at begining and end of $line.
$out = str_replace('""','"',$out);
} else {

$out .= '"'.str_replace('[comma]',',',$value).'",';

// change the [speach] back to "
$out = str_replace('[speach]','"',$out);
}
}

// remove the last comma (i think)??
$out = rtrim($out, ',') . "n";

// create the tmp CSV
fputs($tmp, $out);

// for test purposes only, remove once it is fully working
echo $out;
}

// close the link tmp CSV
fclose($tmp);

// return the filename
return $tmpCSV;
}
[/code]


other than that ? if there are any comments or improvments i can make then please let me know ?.

k0r54
Copy linkTweet thisAlerts:
@NogDogAug 21.2005 — You need to use double-quotes for the n to be interpreted as a newline character (and thus the need to escape the preceding backslash). 'n' would look for the literal characters of 3 backslashes followed by an 'n', while "n" would look for a single backslash followed by a newline character.
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — that does not work either :s

$line = str_replace("n", "", $line);
Copy linkTweet thisAlerts:
@k0r54authorAug 21.2005 — still havn't found it :s
×

Success!

Help @k0r54 spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.18,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @AriseFacilitySolutions09,
tipped: article
amount: 1000 SATS,

tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,
)...