csv line parsing, printing extra line at end - c

I have been supplied a CSV line parser to use in a program, and it seems to have a bug where if there is a blank line at the end of the text file it prints out an empty line, like so
My input is this
test, does, this, work
1, second, line, same
My output looks like this. Not only does it cut off the last word, but it prints out the empty line.
test = 1
does = second
this = line
work = same
test =
What it's supposed to do is match every word with the coinciding one in the top line, which it does, but I don't know where the last "test = " is coming from. Here's the code I was supplied, any ideas about what's wrong with it would be a huge help. Thanks.
/*
* Just an array of characters representing a single filed.
*/
typedef char f_string[MAX_CHARS+1] ; /* string for each field */
/*
* A parsed CSV line, with the number of fields and upto MAX_FIELDS themselves.
*/
typedef struct {
int nfields ; /* 0 => end of file */
f_string field[MAX_FIELDS] ; /* array of strings for fields */
} csv_line ;
/*
* Returns true iff the character 'ch' ends a field. That is, ch is end of file,
* a comma, or a newline.
*/
bool is_end_of_field(char ch) {
return (ch == ',') || (ch == '\n') || (ch == EOF) ;
}
/*
* Return the minimum of two integers.
*/
int min(int x, int y) {
return x < y ? x : y ;
}
/*
* Read the next field from standard input. Returns the value of getchar() that
* stopped (terminated) the field.
*/
int get_field(f_string field) {
/**BEGIN_SOLN**/
int i ;
int next_char ;
next_char = getchar() ;
for ( i = 0 ; ! is_end_of_field(next_char) ; ++i ) {
field[i] = next_char ;
next_char = getchar() ;
}
field[i] = '\0' ;
return next_char ;
/**END_SOLN**/
}
/*
* Read in a CSV line. No error checking is done on the number of fields or
* the size of any one field.
* On return, the fields have been filled in (and properly NUL-terminated), and
* nfields is the count of the number of valid fields.
* nfields == 0 means end of file was encountered.
*/
csv_line get_line() {
/**BEGIN_SOLN**/
csv_line line ;
int fi = 0 ; /* index of current field in line */
int stop_ch ; /* character that terminated the last field */
stop_ch = get_field(line.field[fi++]) ;
while ( stop_ch == ',' ) {
stop_ch = get_field(line.field[fi++]) ;
}
line.nfields = (stop_ch == EOF) ? 0 : fi ;
return line ;
/**END_SOLN**/
}
/*
* Print a CSV line, associating the header fields with the
* data line fields.
* The minimum of the number of fields in the header and the data
* determines how many fields are printed.
*/
void print_csv(csv_line header, csv_line data) {
/**BEGIN_SOLN**/
int i ;
int nfields = min(header.nfields, data.nfields) ;
for ( i = 0 ; i < nfields ; ++i ) {
printf("%s = %s\n", header.field[i], data.field[i]) ;
}
/**END_SOLN**/
}
/*
* Driver - read a CSV line for the header then read and print data lines
* until end of file.
*/
int main() {
csv_line header ;
csv_line current ;
header = get_line() ;
current = get_line() ;
while ( current.nfields > 0 ) {
print_csv(header, current) ;
current = get_line() ;
}
return 0 ;
}

bool is_end_of_field(int ch) {
return (ch == ',') || (ch == '\n') || (ch == EOF) ;
}
bool get_field(f_string field){
int i ;
int next_char ;
for ( i = 0 ; ! is_end_of_field(next_char=getchar()) ; ++i ) {
field[i] = next_char ;
}
field[i] = '\0';
return (next_char == ',')? true : false;
}
csv_line get_line() {
csv_line line ;
int fi = 0;
while(get_field(line.field[fi++]))
;
line.nfields = line.field[fi-1][0] ? fi : 0;
return line ;
}

Related

Emit INDENT/OUTDENT tokens from Flex

I have found a great example of handling Python-style INDENT/OUTDENT in Flex here: http://matt.might.net/articles/standalone-lexers-with-lex/
The code is:
%{
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#define MAX_DEPTH 72
int nesting = 0 ;
unsigned int indent_stack[MAX_DEPTH] ;
unsigned int level = 0 ;
unsigned int first = 1 ;
void process_indent(char* line) ;
%}
PUNCT [-+*/=<>:]*
ID [A-Za-z_][A-Za-z0-9_]*
INT [0-9]+
%option noyywrap
%%
^[ ]*\n {/* Ignore blank lines. */}
^[ ]*[^ \n]+ {int last = yyleng - 1;
process_indent(yytext) ;
while ((last >= 0) &&
(yytext[last] != ' ')) {
unput(yytext[last]);
last-- ;}}
"(" {printf(" "); ECHO; nesting++ ; }
")" {printf(" "); ECHO; nesting-- ; }
{ID}|{INT}|{PUNCT} {printf(" ") ; ECHO;}
[ \r] {}
\n {}
<<EOF>> { process_indent("") ; return 0 ; }
%%
unsigned int white_count(char* line) {
unsigned int count = 0 ;
while (*line == ' ')
count++, line++ ;
return count ;
}
void process_indent(char* line) {
if (nesting)
/* Ignore indents while nested. */
return ;
unsigned int indent = white_count(line) ;
if (indent == indent_stack[level]) {
if (!first) printf(" ;") ; // EMIT END_STATEMENT
first = 0 ;
return ;
}
if (indent > indent_stack[level]) {
printf(" {") ; // EMIT BLOCK_START
assert(level+1 < MAX_DEPTH) ;
indent_stack[++level] = indent ;
return ;
}
while (indent < indent_stack[level]) {
--level ;
printf(" }") ; // EMIT BLOCK_END
}
assert(level >= 0) ;
}
int main(int argc, char* argv[]) {
indent_stack[0] = 0 ;
yylex() ;
printf("\n") ;
}
Basically, it converts code like this:
def f(x):
y = x * x
e = (m * c
* c)
if x > 0:
return e
else:
return y
To this:
def f ( x ) : { y = x * x ; e = ( m * c * c ) ;
if x > 0 : { return e } else : { return y } }
Which is exactly what I need. With one difference: I want the lexer to return the appropriate tokens instead of printing out the curly braces.
The problem is with the OUTDENTs. This happens in a while block in the process_indent function (meaning: there may be more than one block to "close"). And that means I would have to return more than one tokens at the same time - which is NOT possible with Lex/Flex.
Any ideas how I could change that to make it work? Are there any working examples with what I need?
Any ideas how I could change that to make it work? Are there any
working examples with what I need?
You could base your code on the Python lexer example included with RE/flex, see ptokens.l. This lexer fully supports Python's syntax rules such as indentation blocks, and implicit and explicit line joining which isn't possible with process_indent(). Multiple "OUTDENT" (RE/flex "dedent") are generated when multiple blocks close.
The example requires RE/flex as a more advanced version of Flex. But RE/flex is very much like Flex and accepts Flex specifications, so moving on to RE/flex should be easy.

Parsing a CSV File Problems

I tried this to parse data given in a csv file into ID, AGE, and GPA fields in a "data" file, but I don't think I'm doing this right (when I tried printing the data, its printing weird numbers). What am I doing wrong?
char data[1000];
FILE *x = fopen("database.csv","rt");
char NAME[300];
int ID[300],AGE[300],GPA[300];
int i,j;
i = 0;
while(!feof(x)) {
fgets(data,999,x);
for (j = 0; j < 300 && data[i] != ','; j++, i++) {
ID[j] = data[i];
i++;
}
for (j = 0; j < 300 && data[i] != ','; j++, i++) {
NAME[j] = data[i];
i++;
}
for (j = 0; j < 300 && ( data[i] != '\0' || data[i] != '\r' || data[i] != data[i] != '\n'); j++, i++) {
GPA[j] = data[i];
}
}
First of all: for what you're doing, you probably want to look carefully at the function strtok and the atoi macro. But given the code you posted, that's perhaps still a bit too advanced, so I'm taking a longer way here.
Supposing that the line is something like
172,924,1182
then you need to parse those numbers. The number 172 is actually represented by two or four bytes in memory, in a very different format, and the byte "0" is nothing like the number 0. What you'll read is the ASCII code, which is 48 in decimal, or 0x30 in hex.
If you take the ASCII value of a single digit and subtract 48, you will get a number, because fortunately the numbers are stored in digit order, so "0" is 48, "1" is 49 and so on.
But you still have the problem of converting the three digits 1 7 2 into 172.
So once you have 'data':
(I have added commented code to deal with a unquoted, unescaped text field inside the CSV, since in your question you mention an AGE field, but then you seem to want to use a NAME field. The case when the text field is quoted or escaped is another can of worms entirely)
size_t i = 0;
int number = 0;
int c;
int field = 0; // Fields start at 0 (ID).
// size_t x = 0;
// A for loop that never ends until we issue a "break"
for(;;) {
c = data[i++];
// What character did we just read?
if ((',' == c) || (0x0c == c) || (0x0a == c) || (0x00 == c)) {
// We have completed read of a number field. Which field was it?
switch(field) {
case 0: ID[j] = number; break;
case 1: AGE[j] = number; break;
// case 1: NAME[j][x] = 0; break; // we have already read in NAME, but we need the ASCIIZ string terminator.
case 2: GPA[j] = number; break;
}
// Are we at the end of line?
if ((0x0a == c) || (0x0c == c)) {
// Yes, break the cycle and read the next line
break;
}
// Read the next field. Reinitialize number.
field++;
number = 0;
// x = 0; // if we had another text field
continue;
}
// Each time we get a digit, the old value of number is shifted one order of magnitude, and c gets added. This is called Horner's algorithm:
// Number Read You get
// 0 "1" 0*10+1 = 1
// 1 "7" 1*10+7 = 17
// 17 "2" 17*10+2 = 172
// 172 "," Finished. Store 172 in the appropriate place.
if (c >= '0' && c <= '9') {
number = number * 10 + (c - '0');
}
/*
switch (field) {
case 1:
NAME[j][x++] = c;
break;
}
*/
}

How to identify a double \n\n with fgets/read/fread

I have a dot file, which i need to parse it into a graph structure using C.
My dot file contains 2 blocs seperated with a double \n:
the one is verticle
the other one is edges
I have tried with fgets since it reads until \n is met. It is helpfull to count the number of verticles but not whats comes after it. I don't have any idea of how i can do it
Right now I have a function like this (not complete)
int graphe_charger_dot(graphe *g, char *nom_fichier) {
FILE * f;
int n;
if ((f = fopen(nom_fichier, "r")) == 0) {
puts(nom_fichier);
puts("Erreur d'ouverture du fichier");
return -1;
}
char buffer[500];
fgets(buffer, sizeof(buffer),f);
;
if (strcmp(buffer, "graph {\n") != 0) {
puts("Erreur de compatibilité de fichier");
puts(nom_fichier);
return -1;
}
puts("Fichier ouvert et compatible");
puts("Lecture du buffer 1");
// reads the first verticles. the atoi is just here to test if i can convert an char to integer even with a non integer right after it.
fgets(buffer, sizeof(buffer),f);
n = atoi(buffer);
g->n += 1;
return 0;
}
My dot file
graph {
0;
1;
2;
3;
4;
5;
6;
7;
8;
0 -- 1;
0 -- 4;
0 -- 5;
0 -- 6;
0 -- 8;
1 -- 2;
1 -- 3;
1 -- 4;
1 -- 5;
2 -- 3;
2 -- 4;
2 -- 5;
2 -- 8;
3 -- 7;
5 -- 7;
5 -- 8;
6 -- 8;
7 -- 8;
}
and the structure of the graph
struct s_graphe {
int n; /* number of verticles */
int m; /* number of edges */
int adj[GRAPHE_ORDRE_MAX][GRAPHE_ORDRE_MAX];
/* Adjacency matrix of the graph */
};
How to identify a double \n\n ...
The prior line ended with a '\n'. With fgets(), test if buffer[0] == '\n' to see if a line begins and ends with a '\n' to detect the consecutive '\n'.
...
puts("Lecture du buffer 1");
//fgets(buffer, sizeof(buffer),f);
//n = atoi(buffer);
//g->n += 1;
while (fgets(buffer, sizeof buffer, f) && buffer[0] != '\n') {
// parse `buffer` for a vertex
}
while (fgets(buffer, sizeof buffer, f)) {
// parse `buffer` for an edge
}
My dot file contains 2 blocs separated with a double \n:
The below looks like 3 '\n' in a row. The first of the 3 ends the "8;\n" line.
7;\n
8;\n
\n
\n
0 -- 1;\n
0 -- 4;\n
In that case a little more work is needed. Perhaps
while (fgets(buffer, sizeof buffer, f) && buffer[0] != '\n') {
// parse `buffer` for a vertex
}
// Here code consumes 0 or more lines that are only `"\n"`
// Could use a counter to limit
int ch;
while ((c = fgetc(f)) == '\n');
ungetc(ch, f);
while (fgets(buffer, sizeof buffer, f)) {
// parse `buffer` for an edge
}

One of my value in array gives "0"

In my file includes two columns and I'm try to gather data from file. I need to compare two value in one column. For example, if array[5] is higher than array[4], do something. Here my code:
int control(double col2[], double col3[], int subscript){
double a, b, fcontrol ;
int k /* group */ ;
/* some necessary values for JD controlling */
a = col2[subscript] ;
b = col2[subscript-1] ;
/* for JD controlling */
fcontrol = a - b ;
printf("kontrol = %.12f a = %.12f b = %.12f\n", fcontrol, a, b) ;
/* if value of between two data is equal or higher than 10 hour return 1 */
if(fcontrol >= 0.416666666667){
return 1 ;
}
else{
return 0 ;
}
b is always 0. How can I fix it?
My terminal is :
kontrol = 258.426728989849 a = 258.426728989849 b = 0.000000000000
kontrol = 258.447161800788 a = 258.447161800788 b = 0.000000000000
kontrol = 258.467594711488 a = 258.467594711488 b = 0.000000000000
kontrol = 260.245248070103 a = 260.245248070103 b = 0.000000000000
kontrol = 260.265680861012 a = 260.265680861012 b = 0.000000000000
kontrol = 260.286113551461 a = 260.286113551461 b = 0.000000000000
kontrol = 260.306546441912 a = 260.306546441912 b = 0.000000000000
Here my all code :
/* TASK */
#include<stdio.h>
int kontrol(double col2[], double col3[], int subscript) ;
int main(){
int kolon1,
n = 0, /* for array */
j, z, /* for "for" loopr */
flag = 0 ;
int grup = 0 ;
double kolon2, kolon3,
col2[100000], col3[100000] ;
char ignore[100];
FILE *okuPtr ;
FILE *yazPtr ;
char oku_tbl[100] ;
sprintf(oku_tbl, "deneme.tbl") ;
/* error if file isnt opened*/
if ((okuPtr = fopen(oku_tbl, "r")) == NULL)
printf("%s Acilamadi", oku_tbl) ;
/* file is opened */
else{
char yaz_tbl[100] ;
sprintf(yaz_tbl, "deneme_data.tbl") ;
/* errof if file isnt opened */
if((yazPtr = fopen(yaz_tbl, "w")) == NULL)
printf("%s acilamadi\n", yaz_tbl) ;
/* file is opened */
else{
/* first read */
fscanf(okuPtr, "%d%lf%lf", &kolon1, &kolon2, &kolon3) ;
/* until end of file */
while (!feof(okuPtr)){
/* ignore first 3 line */
fgets(ignore, 100, okuPtr) ;
col2[n] = kolon2 ;
col3[n] = kolon3 ;
flag = control(col2, col3, n) ;
n++ ;
/* if flag == 1 */
if (flag == 1){
for (z = 0 ; z <= --n ; z++){
fprintf(yazPtr, "%d\t%.12f\t%.12f\n", grup, col2[z], col3[z]) ;
}
n = 0 ;
grup++ ;
}
/* yeni veri oku */
fscanf(okuPtr, "%d%lf%lf", &kolon1, &kolon2, &kolon3) ;
}
/* diziyi yazdir
for (j = 0 ; j <= n-1 ; j++){
printf("%d\t%-.12f\t%-.12f\n", k, col2[j], col3[j]) ;
} */
}
}
return 0 ;
}
int control(double col2[], double col3[], int subscript){
double a, b,
fcontrol ;
int k /* group */ ;
/* some necessary values for JD controlling */
a = col2[subscript] ;
b = col2[subscript-1] ;
/* for JD controlling */
fcontrol = a - b ;
printf("kontrol = %.12f a = %.12f b = %.12f\n", fcontrol, a, b) ;
/* if value of between two data is equal or higher than 10 hour return 1 */
if(fcontrol >= 0.416666666667){
return 1 ;
}
else{
return 0 ;
}
}
Problem is that when you call control for first time when n=0
flag = control(col2,col3, n);
But notice here b=col2[subscript-1] will actually be b=col2[-1] which is creating problem as array indexing start with 0 thus your program has this behaviour .
while (!feof(okuPtr))
It is always wrong. See here-Why is “while ( !feof (file) )” always wrong?
Instead use this -
while(fgets(ignore, 100, okuPtr))
{
/*Your code*/
}

simple way to delimit whitespace (once) in C when already using another delimiter

I have the following code
while (*ptr != ',') {
int items_read = sscanf(ptr, "%91[^,]%n", field, &n);
printf("field = \"%s\"\n", field);
field[0]='\0';
if (items_read == 1)
ptr += n; /* advance the pointer by the number of characters read */
if ( *ptr != ',' ) {
break; /* didn't find an expected delimiter, done? */
}
++ptr; /* skip the delimiter */
}
It reads through my string and creates a new array for each string it finds between the commas, however I have white space in the middle of the string. I have many strings that will be read in, and some of those have white space in more than one area (after that middle place) and I do not want that white space accounted for, just the first instances.
I know I can put || ' ' on the while line, the int line, and/or the second if line but I haven't gotten to do what I need done.
I've heard that using strtok isn't good, or at least there are better ways to do that. I do not know how to add additional 'flags' (like the commas in my code) for the code to by-pass.
ex:
3,875,837 file1.ext
3,437,281 document two.txt
I already have the beginnings doing what I want.
field1 = 3
field2 = 875
field3 = 837
However I want the rest of the string on those 2 inputs to go into separate char arrays and print out as follows:
field4 = file1
field5 = ext
and
field4 = document
field5 = two
field6 = txt
Or, I'm thinking now, is there anyway I can extract the last iteration of that char array field in order to use another loop through the exact same code except replace the ,s with ' ' spaces?
Depends a lot on what you want to use the data for. How to use it elsewhere in the code etc.
Guess I'd often use plain iteration on parsing like this. If you want to use sscanf this might help; as an example:
#include <stdio.h>
int prnt_fields(char **ptr)
{
char field[128];
int n;
int i = 0;
printf("Item {\n");
while (**ptr) {
if(sscanf(*ptr, "%127[^\t\n., ]%n", field, &n) != 1)
break;
printf(" %d => '%s'\n", i++, field);
(*ptr) += n;
/* To handle multiple spaces tabs etc.: */
if(sscanf(*ptr, "%127[ \t.,]%n", field, &n))
(*ptr) += n;
/* Or:
n = 0;
sscanf(*ptr, "%*[ \t.,]%n", &n);
(*ptr) += n;
*/
if (**ptr == '\n') {
printf("} OK!\n");
(*ptr)++;
return **ptr != '\0';
}
}
/* Should never end here unless input is invalid;
* aka not separated with , \n or over long fields (>127) */
printf("} something failed!\n");
return 0;
}
int main(void)
{
char *tst = "3,875,837 file1.ext\n"
"6,875,847 file2.ext\n"
"3,437,281 document two.txt\n"
"9,991,123\tdrei.txt\n"
"4,494,123 vier fünf . txt\n"
;
char field[128];
int n;
char *ptr = tst;
int i = 0;
while (*ptr) {
if(sscanf(ptr, "%127[^, \n.]%n", field, &n) != 1)
break;
printf("field%d = '%s'\n", i++, field);
ptr += n+1;
/* If one want to validate separator
ptr += n;
if (*ptr != ',' && *ptr != ' ' && *ptr != '\n')
break;
++ptr;
*/
}
ptr = tst;
printf("\n---------------\n");
while (prnt_fields(&ptr) > 0)
;
return 0;
}
Should give something like:
field0 = '3'
field1 = '875'
field2 = '837'
...
field18 = '123 drei' <= breaks here
field19 = 'txt'
field20 = '4'
field21 = '494'
field22 = '123'
Item {
0 => '3'
1 => '875'
2 => '837'
3 => 'file1'
4 => 'ext'
} OK!
Item {
0 => '6'
1 => '875'
2 => '847'
3 => 'file2'
4 => 'ext'
} OK!
Item {
0 => '3'
1 => '437'
2 => '281'
3 => 'document'
4 => 'two'
5 => 'txt'
} OK!
Item {
0 => '9'
1 => '991'
2 => '123'
3 => 'drei'
4 => 'txt'
} OK!
Item {
0 => '4'
1 => '494'
2 => '123'
3 => 'vier'
4 => 'fünf'
5 => 'txt'
} OK!
Edit:
OK. This can be done much cleaner and nice, but you'll might get an idea:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
struct file_data {
struct date {
int y;
int m;
int d;
} date;
struct time {
int h;
int m;
} time;
int size_prt[8]; /* max 2^63 : 9223372036854775808 bytes */
double size;
char name[512];
char ext[16];
char ext_tr[16];
char name_prt[32][128]; /* should be malloc or ptrs or done in func or.. */
};
/* Default */
static const struct file_data file_def = {
{0,0,0},{0,0},{-1},0,{'\0'},{'\0'},{'\0'},{{'\0'}}
};
void prnt_filedata(FILE *fh, struct file_data fd)
{
int i = 0;
fprintf(fh,
"File { \n"
" Date: %4d-%02d-%02d\n"
" Time: %02d:%02d\n"
" Size: %.f\n"
" Size: %.2f K\n"
" Size: %.2f M\n"
" Size: %.2f G\n"
" Name: '%s'\n"
" Ext : '%s'\n"
" ExtT: '%s'\n"
" Szpt: ",
fd.date.y, fd.date.m, fd.date.d,
fd.time.h, fd.time.m,
fd.size,
(fd.size / (1 << 10)),
(fd.size / (1 << 20)),
(fd.size / (1 << 30)),
fd.name,
fd.ext,
fd.ext_tr
);
while (fd.size_prt[i] != -1)
fprintf(fh, "%d ", fd.size_prt[i++]);
fprintf(fh, "\n Fprt: ");
i = 0;
while (*fd.name_prt[i])
fprintf(fh, "'%s' ", fd.name_prt[i++]);
fprintf(fh, "\n}\n");
}
int extr_file_data(char **ptr, struct file_data *fd)
{
int i;
int n;
char size[26];
char name[512];
char *p;
*fd = file_def;
while (**ptr) {
if (sscanf(*ptr,
"%4d-%2d-%2d %d:%d %25[0123456789,] %511[^\n]%n",
&fd->date.y, &fd->date.m, &fd->date.d,
&fd->time.h, &fd->time.m,
size, name, &n) != 7) {
fprintf(stderr,
" * ERR; Unable to extract from %s\n",
*ptr);
return 0;
}
(*ptr) += n;
p = size;
i = 0;
/* Size parts + total */
while (*p && i < 7) {
fd->size_prt[i] = (int)strtol(p, &p, 0);
fd->size *= 1000;
fd->size += fd->size_prt[i++];
if (*p) ++p;
}
fd->size_prt[i] = -1; /* flag next to last */
/* get .ext */
if ((p = strrchr(name, '.')) != NULL) {
strncpy(fd->name, name, p - name);
strncpy(fd->ext, p + 1, 16);
/* trimmed ext */
if (sscanf(fd->ext, "%15s", fd->ext_tr) != 1)
*fd->ext_tr = '\0';
} else {
strncpy(fd->name, name, 511);
}
/* get trimmed parts of name */
p = fd->name;
i = 0;
while (sscanf(p, "%127s%n", fd->name_prt[i++], &n) == 1 && i < 32)
p+=n;
;
*fd->name_prt[n] = '\0';
if (**ptr == '\n')
(*ptr)++;
return **ptr != '\0';
}
return 0;
}
int main(void)
{
char *tst =
"2012-04-18 13:28 32 ein.ext\n"
"2012-04-18 13:28 2,446,875,847 zwei.xt \n"
"2012-04-18 13:28 0 drei .xt\n"
"2012-04-18 13:28 7,694,587,183,883,665 vier fünf.txt\n"
"2012-04-18 13:28 9,991,123\t\tsechs\n"
"2012-04-18 13:28 4,494,123 sieben acht . txt\n"
;
char *ptr = tst;
struct file_data fd;
while (extr_file_data(&ptr, &fd) > 0)
prnt_filedata(stdout, fd);
prnt_filedata(stdout, fd);
return 0;
}
Should give:
...
File {
Date: 2012-04-18
Time: 13:28
Size: 2446875847
Size: 2389527.19 K
Size: 2333.52 M
Size: 2.28 G
Name: 'zwei'
Ext : 'xt '
ExtT: 'xt'
Szpt: 2 446 875 847
Fprt: 'zwei'
}
...
File {
Date: 2012-04-18
Time: 13:28
Size: 4494123
Size: 4388.79 K
Size: 4.29 M
Size: 0.00 G
Name: 'sieben acht '
Ext : ' txt'
ExtT: 'txt'
Szpt: 4 494 123
Fprt: 'sieben' 'acht'
}
...
Edit (again); sorry, only a weird shift i forgot to change after testing.
You might take a look at the strcspn() method.
As a nice side effect it could be implemented multi-byte character safe.
How I'd do this would depend on the data. I'd probably read in one string, parse it into two at the first space possibly with strchr, then go through the first string splitting on commas.

Resources