/* [<][>][^][v][top][bottom][index][help] */
DEFINITIONS
This source file includes following definitions.
- CCsv
- CCsv
- GetValue
- GetRowSize
- GetColumnSize
- RemoveAll
- AddRow
- Save
- CountDQuotation
- StripQuotation
- AddQuotation
/*
* Copyright (C) 2002-2003 chik, s.hiranaka
* For license terms, see the file COPYING in this directory.
*/
// Csv.cpp:
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "pochy.h"
#include "Csv.h"
#include "StrTok.h"
#include "lib.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// 構築/消滅
//////////////////////////////////////////////////////////////////////
CCsv::CCsv(LPCTSTR path)
{
if(path == NULL)
return;
CString buf;
CString message;
CStdioFile read_file;
if(!read_file.Open(path, CFile::modeRead | CFile::typeText)){
message.Format("%sが開けません", path);
AfxMessageBox(message);
return;
}
CStringArray tmp_array;
buf.Empty();
while(read_file.ReadString(buf)){
tmp_array.Add(buf);
buf.Empty();
}
m_data.RemoveAll();
m_data.SetSize(tmp_array.GetSize());
int start;
int start2;
int end;
for(int n=0; n<tmp_array.GetSize(); n++){
buf = tmp_array.GetAt(n);
start=0;
while((end = buf.Find(",", start)) != -1){
// if buf include (") or (,)
if(buf[start] == '"'){
while(1){
int i = CountDQuotation(buf, start, end);
if(i%2 == 1 || i == 1){
break;
}else{
start2 = end+1;
end = buf.Find(",", start2);
if(end == -1){
end = buf.GetLength()-1;
break;
}
continue;
}
}
}
if(buf[start] == '"'){
CString tmp = buf.Mid(start+1, end-start-1);
this->StripQuotation(tmp);
m_data[n].Add(tmp);
}else{
m_data[n].Add(buf.Mid(start, end-start));
}
start = end+1;
}
buf = buf.Mid(start);
buf.TrimRight();
m_data[n].Add(buf);
}
}
CCsv::~CCsv()
{
}
CString CCsv::GetValue(int row, int column)
{
CString buf;
buf.Empty();
if(row >= GetRowSize())
return buf;
else if(column >= GetColumnSize(row))
return buf;
return m_data[row].GetAt(column);
}
int CCsv::GetRowSize()
{
return m_data.GetSize();
}
int CCsv::GetColumnSize(int row)
{
return m_data[row].GetSize();
}
void CCsv::RemoveAll()
{
m_data.RemoveAll();
}
void CCsv::AddRow(CStringArray *new_row)
{
int size = m_data.GetSize();
m_data.SetSize(size+1);
for(int i=0; i<new_row->GetSize(); i++)
m_data[size].Add(new_row->GetAt(i));
}
void CCsv::Save(LPCTSTR path)
{
CString buf;
CString data;
CString tmp;
data.Empty();
buf.Empty();
for(int i=0; i<m_data.GetSize(); i++){
for(int j=0; j<m_data[i].GetSize(); j++){
tmp = m_data[i].GetAt(j);
if(tmp.Find("\"") != -1 || tmp.Find(",") != -1)
this->AddQuotation(tmp);
if(j==0){
buf += tmp;
}else{
buf += ","+tmp;
}
}
data += buf+"\r\n";
buf.Empty();
}
FILE* file = fopen(path, "wb");
fwrite(data, sizeof(char), data.GetLength(), file);
fclose(file);
}
// count number of double-quotation(") just before single-quotation(').
// end must be position of single-quotation(') in buf.
// if return of this function is odd, here mean this single quotation(') is separation mark of csv.
int CCsv::CountDQuotation(CString buf, int start, int end)
{
int n=1;
while(buf[end-n] == '"' && end-n > start){
n++;
}
return n-1;
}
void CCsv::StripQuotation(CString &buf)
{
int p=0;
while((p = buf.Find('"', p)) != -1){
buf.Delete(p);
p=p+1;
}
}
void CCsv::AddQuotation(CString &buf)
{
BOOL flag = FALSE;
CString tmp;
for(int i=0; i<buf.GetLength(); i++){
if(buf[i] == '"'){
flag |= TRUE;
tmp += "\"\"";
}else if(buf[i] == ','){
flag |= TRUE;
tmp += buf[i];
}else{
tmp += buf[i];
}
}
if(flag)
buf = "\""+tmp+"\"";
}