Asked  7 Months ago    Answers:  5   Viewed   35 times

I have a csv file which looks like this

$lines[0] = "text, with commas", "another text", 123, "text",5;
$lines[1] = "some without commas", "another text", 123, "text";
$lines[2] = "some text with commas or no",, 123, "text";

And I would like to have a table:

$t[0] = array("text, with commas", "another text", "123", "text","5");
$t[1] = array("some without commas", "another text", "123", "text");
$t[2] = array("some text, with comma,s or no", NULL , "123", "text");

If I use split($lines[0],",") I'll get "text" ,"with commas" ... Is there any elegant way to do it?

 Answers

22

You can use fgetcsv to parse a CSV file without having to worry about parsing it yourself.

Example from PHP Manual:

$row = 1;
if (($handle = fopen("test.csv", "r")) !== FALSE) {
    while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
        $num = count($data);
        echo "<p> $num fields in line $row: <br /></p>n";
        $row++;
        for ($c=0; $c < $num; $c++) {
            echo $data[$c] . "<br />n";
        }
    }
    fclose($handle);
}
Tuesday, June 1, 2021
 
Student
answered 7 Months ago
19

Get Data from CSV File use fgetcsv function.

$row = 1;
if (($openfile = fopen("customer.csv", "r")) !== FALSE) {
   while ($getdata = fgetcsv($openfile, 1000, ",")) {
       $total = count($getdata);
       echo "<b>Row no:-</b>$rown";   
       echo "<b>Total fields in this row:-</b>$totaln";
       $row++;
       for ($c=0; $c < $total; $c++) {
          $csvdata = implode(";", $getdata);
          $fncsvdata = explode(";", $csvdata);
       }
       var_dump($fncsvdata);
   }
}

Here You can see your CSV file data than you want to use INSERT query for insert data.
For insert frist colum use $fncsvdata[0].
Here in fgetcsv 1000 = "Must be greater than the longest line (in characters) to be found in the CSV file".

Saturday, May 29, 2021
 
pocketfullofcheese
answered 7 Months ago
39

I suggest you not inventing a wheel. There is existing solution. Source here

import os


def split(filehandler, delimiter=',', row_limit=1000,
          output_name_template='output_%s.csv', output_path='.', keep_headers=True):
    import csv
    reader = csv.reader(filehandler, delimiter=delimiter)
    current_piece = 1
    current_out_path = os.path.join(
        output_path,
        output_name_template % current_piece
    )
    current_out_writer = csv.writer(open(current_out_path, 'w'), delimiter=delimiter)
    current_limit = row_limit
    if keep_headers:
        headers = reader.next()
        current_out_writer.writerow(headers)
    for i, row in enumerate(reader):
        if i + 1 > current_limit:
            current_piece += 1
            current_limit = row_limit * current_piece
            current_out_path = os.path.join(
                output_path,
                output_name_template % current_piece
            )
            current_out_writer = csv.writer(open(current_out_path, 'w'), delimiter=delimiter)
            if keep_headers:
                current_out_writer.writerow(headers)
        current_out_writer.writerow(row)

Use it like:

split(open('/your/pat/input.csv', 'r'));
Wednesday, June 30, 2021
 
julesj
answered 5 Months ago
13

As I said in a comment, csv files would need to be split on row (or line) boundaries. Your code doesn't do this and potentially breaks them up somewhere in the middle of one — which I suspect is the cause of your _csv.Error.

The following avoids doing that by processing the input file as a series of lines. I've tested it and it seems to work standalone in the sense that it divided the sample file up into approximately equally size chunks because it's unlikely that an whole number of rows will fit exactly into a chunk.

Update

This it is a substantially faster version of the code than I originally posted. The improvement is because it now uses the temp file's own tell() method to determine the constantly changing length of the file as it's being written instead of calling os.path.getsize(), which eliminated the need to flush() the file and call os.fsync() on it after each row is written.

import csv
import multiprocessing
import os
import tempfile

def split(infilename, num_chunks=multiprocessing.cpu_count()):
    READ_BUFFER = 2**13
    in_file_size = os.path.getsize(infilename)
    print 'in_file_size:', in_file_size
    chunk_size = in_file_size // num_chunks
    print 'target chunk_size:', chunk_size
    files = []
    with open(infilename, 'rb', READ_BUFFER) as infile:
        for _ in xrange(num_chunks):
            temp_file = tempfile.TemporaryFile()
            while temp_file.tell() < chunk_size:
                try:
                    temp_file.write(infile.next())
                except StopIteration:  # end of infile
                    break
            temp_file.seek(0)  # rewind
            files.append(temp_file)
    return files

files = split("sample_simple.csv", num_chunks=4)
print 'number of files created: {}'.format(len(files))

for i, ifile in enumerate(files, start=1):
    print 'size of temp file {}: {}'.format(i, os.path.getsize(ifile.name))
    print 'contents of file {}:'.format(i)
    reader = csv.reader(ifile)
    for row in reader:
        print row
    print ''
Friday, July 30, 2021
 
bayman
answered 4 Months ago
78

Try this

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define MAX_ROW 256

int main()
{
    FILE  *file;
    float  data[MAX_ROW][6];
    int    index;
    float *row;

    file = fopen("file.dat", "r");
    if (file == NULL)
    {
        perror("fopen()");
        return 1;
    }

    index = 0;
    row   = data[0];
    while (fscanf(file, "%f%f%f%f%f%f", &row[0], &row[1], &row[2], &row[3], &row[4], &row[5]) == 6)
    {
        printf("[%f;%f;%f;%f;%f;%f]n", row[0], row[1], row[2], row[3], row[4], row[5]);
        row = data[index++];
    }
    fclose(file);

    return 0;
}

note that you could need to make data dynamically allocated to be able to resize it.

Wednesday, October 27, 2021
 
ChriskOlson
answered 1 Month ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share