c - 如何从 CSV 文件(C 语言)读取和写入寄存器?

标签 c file csv fwrite fread

我有一个 .CSV 文件,我需要读取它并写入一个二进制文件。

我尝试改编我在一些类似问题中看到的一些代码,但没有奏效。

我的文件是这样的:

nroInscricao,nota,data,cidade,nomeEscola
439,607.5,01/01/2004,Maceio,PEDRO II
387,,,Sao Paulo,JOAO KOPKE
332,400.8,03/01/2004,Brasilia,REINALDO RIBEIRO DA SILVA DOU
296,436.4,04/01/2004,,JOSE CANDIDO DE SOUZA

然后我尝试使用以下代码读取文件:

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("C:\\Users\\10734140\\Downloads\\SCC0503012019trabalho1.csv", "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);
    }
}

但是在执行过程中没有任何结果。

最佳答案

只需编写从 strtok 派生的 strtokEvenEmpty 然后替换

     for (tok = strtok(line, ","); tok && *tok; tok = strtok(NULL, ",\n")){

通过

for (tok = strtokEvenEmpty(line, ","); tok != NULL; tok = strtokEvenEmpty(NULL, ",\n")){

因为您的测试 *tok 会在字段为空时阻止您,甚至在预期字段之前

例如:

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

char * strtokEvenEmpty(char * s, const char * seps)
{
  static char * p = NULL;

  if (s != NULL)
    p = s;
  else if (p == NULL)
    return NULL;
  else
    s = p;

  while (*p) {
    if (strchr(seps, *p)) {
      *p++ = 0;
      return s;
    }
    p += 1;
  }
  return (*s) ? s : NULL;
}

const char * getfield(char* line, int num){
  const char * tok;

  for (tok = strtokEvenEmpty(line, ","); tok; tok = strtokEvenEmpty(NULL, ",\n")){
    if (!--num)
      return tok;
  }
  return NULL;
}

int main()
{
  FILE * stream = fopen("SCC0503012019trabalho1.csv", "r");

  if (stream != NULL) {
    char line[1024];
    while (fgets(line, 1024, stream)) {
      printf("Field 3 would be '%s'\n", getfield(line, 3));
    }
    fclose(stream);
  }
}

编译和执行:

pi@raspberrypi:/tmp $ gcc -pedantic -Wextra -Wall -g s.c
pi@raspberrypi:/tmp $ cat SCC0503012019trabalho1.csv 
nroInscricao,nota,data,cidade,nomeEscola
439,607.5,01/01/2004,Maceio,PEDRO II
387,,,Sao Paulo,JOAO KOPKE
332,400.8,03/01/2004,Brasilia,REINALDO RIBEIRO DA SILVA DOU
296,436.4,04/01/2004,,JOSE CANDIDO DE SOUZA
pi@raspberrypi:/tmp $ ./a.out
Field 3 would be 'data'
Field 3 would be '01/01/2004'
Field 3 would be ''
Field 3 would be '03/01/2004'
Field 3 would be '04/01/2004'

如果我得到第四个字段而不是第三个字段 (printf("Field 4 would be %s\n", getfield(line, 4));) :

Field 4 would be 'cidade'
Field 4 would be 'Maceio'
Field 4 would be 'Sao Paulo'
Field 4 would be 'Brasilia'
Field 4 would be ''

在当前情况下,main 中的 strdup 没有用,因为 linestrtok/strtokEvenEmpty 不是问题,line 也不是问题,所以 getfield 的结果会被下一个循环修改。

关于c - 如何从 CSV 文件(C 语言)读取和写入寄存器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55476394/

相关文章:

c++ - 将文件保存到用户在 C++ 中输入定义的位置和名称

c++ - 在每第 n 次出现时反转字符串

c - 结构成员的大小

c++ - const 在 C/C++ 中提供什么样的优化?

file - 如何使用 Bash 将大量字符串快速输入到文件中

java - 找不到文件java

postgresql - 如何在 postgres 前端 COPY 中指定一个选项卡

VBA For Excel (CSV),循环文件以获取行,然后将行附加到一个列表中

javascript - 从 Express 后端下载 .csv 到 Angularjs

c - 奇怪的 printf() 行为