如何从 CSV 文件(C 语言)读取和写入寄存器?
How to read and write registers from a CSV file (in C)?
我有一个 .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 没有用,因为 line 是由 strtok/strtokEvenEmpty 修改不是问题,事实 line 也不是问题,所以 getfield[=41= 的结果]被下一个循环修改。
我有一个 .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 没有用,因为 line 是由 strtok/strtokEvenEmpty 修改不是问题,事实 line 也不是问题,所以 getfield[=41= 的结果]被下一个循环修改。