C++ Read from .CSV File

Read .csv file in C

Hopefully this would get you started

See it live on http://ideone.com/l23He (using stdin)

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

const char* getfield(char* line, int num)
{
const char* tok;
for (tok = strtok(line, ";");
tok && *tok;
tok = strtok(NULL, ";\n"))
{
if (!--num)
return tok;
}
return NULL;
}

int main()
{
FILE* stream = fopen("input", "r");

char line[1024];
while (fgets(line, 1024, stream))
{
char* tmp = strdup(line);
printf("Field 3 would be %s\n", getfield(tmp, 3));
// NOTE strtok clobbers tmp
free(tmp);
}
}

Output:

Field 3 would be nazwisko
Field 3 would be Kowalski
Field 3 would be Nowak

Reading from csv file in C causing input to not print

Since your file contains only two columns, you can write it this way using sscanf():

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

int main()
{
FILE *fp = fopen("file", "r");
if (!fp) {
fprintf(stderr, "Can't open file\n");
return 1;
}

char line[1024];
int x, y;
while (fgets(line, sizeof line, fp)) {
line[strcspn(line, "\n")] = '\0'; // Replace '\n' read by fgets() by '\0'

if (sscanf(line, "%d, %d", &x, &y) != 2) {
fprintf(stderr, "Bad line\n");
}

printf("x:%d\ty:%d\n", x, y);
}

fclose(fp);
}

How to read ANY csv file, not just a specific one, in a c++ program

I can think of 3 ways to do this:

  1. Use command line arguments. You can get the command line arguments by defining main as int main (int argc, char *argv[]) {} wherein argc is the count of arguments and argv is the values. So when you run the program you can just do program.exe filename.csv
  2. Scan for the input filename. cin >> filename;
  3. Get the current directory and get all the csv files. Here's a link on how to get the files in a directory.

read csv file to its end in c

The answer to your question if just test the return value of fgets

for (;;)   // idiomatic C style for an infinite loop 
{
int countTok = 1;

if (NULL == fgets(oneproduct, 256, fp)) break; //get one row and exit loop on EOF
...

But as you were told in comments, there are many other problems in your code:

  • you initialize your indexes to 1 while C array indexes start at 0. So I assume that x=1; should be x=0;. For the same reason, countTok = 1; is not wrong, but countTok = 0; would be more idiomatic C
  • you use fprintf(stderr, ... to notice an error when opening the file. While not wrong, it gives no indication on the cause of the error. perror would do...
  • you erase last character of oneproduct without controling it is a newline. The assumption will be wrong

    • if one line contains at least 256 characters
    • if last line does not end with a newline

    The idiomatic way is to use strcspn:

    oneproduct[strcspn(oneproduct, "\n")] = '\0';  // erase an optional end of line
  • you duplicate oneproduct to oneline. Here again, nothing is wrong, but it is useless because you never use the original line
  • the long list of else if could be replaced with a switch, but this one is mainly a matter of style
  • you free token at the end of loop. As it is NULL it is a no-op, but it is was not allocated it should not be freed.

How to get data from CSV file to struct by C language?

In CSV format at the end of each line, you usually don't have a comma, If that is the case in your CSV file too, then change the format you are providing to fscanf,

from this,

"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,]"

to this,

"%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]"

if you try to read till next comma , for the city field too, then you will end up reading the string city\n6929245 to st[n].city which is wrong and will result in an incorrect reading pattern and might end up in segfault.

And to avoid printing the first line, you can skip the index 0 in your st array, because the first line that you read will be stored in the 0th index of the st array and from index 1 will be your data.

How do I read a .csv file and save it into a 2d array?

You can replace you current loop with this one:

for(i = 0; i < 4; i++){
for(j = 0; j < 2; j++){
char junk;

if (j != 0) fgetc(in_data);

fscanf(in_data, "%c%d%c", &junk, &trIn[i][j], &junk);
printf("%d ", trIn[i][j]);
}
fgetc(in_data);
printf("\n");
}

This works because fscanf(in_data, "%d", &trIn[i][j]) reads an int (%d) from the file in_data into the memory location of trIn[i][j]. fgetc didn't work because it only reads a single character which was then printed as if it were an integer.

EDIT: Now, for each value in the .csv file, you read to a junk variable the " and \n characters.

Line by line:

if (j != 0) fgetc(in_data); reads the , from the csv file into a junk variable (which isn't the first character on a line).

fscanf(in_data, "%c%d%c", &junk, &trIn[i][j], &junk); reads:

  • 1st: the opening " character into a junk variable
  • 2nd: the number (int: %d) into to memory location of trIn[i][j].
  • 3rd: the closing " character into a junk variable


Related Topics



Leave a reply



Submit