如何在二进制文件上写入 CSV 字段?
How to write CSV fields on a binary file?
我有以下代码:
typedef struct RegDados{
char removido; // deve ser inicializado com '-'
int encadeamento; // deve ser inicializado com -1
int nroInscricao; // nao aceita valores repetidos nem nulos
double nota;
char data[10]; // checar tipo
char *cidade;
int sizecid;
char tagCampo4;
char *nomeEscola;
int sizesch;
char tagCampo5;
}RegDados;
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("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
RegDados regdados[5000];
RegCab regcab;
int i = 0;
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
char line[1024];
while (fgets(line, 1024, stream)) {
regdados[i].nroInscricao = atoi(getfield(line, 1));
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
regdados[i].nota = atof(getfield(line, 2));
fwrite(®dados[i].nota, sizeof(double), 1, ArqBin);
strcpy(regdados[i].data, getfield(line, 3));
fwrite(regdados[i].data, sizeof(char), 100, ArqBin);
regdados[i].cidade = getfield(line, 4);
fwrite(regdados[i].cidade, sizeof(char), 100, ArqBin);
regdados[i].nomeEscola = getfield(line, 5);
fwrite(regdados[i].nomeEscola, sizeof(char), 100, ArqBin);
i++;
}
fclose(stream);
fclose(ArqBin);
}
else{
printf("Error");
}
}
它已经解析了我文件的字段,但我不能将它们写入二进制文件,因为当我尝试写入时,我得到了很多空字段,而当我不这样做时就不会发生这种情况不写了。
我的 CSV 文件如下所示:
nroInscricao,nota,data,cidade,nomeEscola
13893,353.9,26/11/2016,,FRANCISCO RIBEIRO CARRIL
13595,472.2,,Salgueiro,ALFREDO GUEDES
13894,614.4,28/11/2016,Recife,JOAO DE MOURA GUIMARAES
13880,403.2,29/11/2016,Fortaleza,ANTONIO DIAS PASCHOAL PR
13881,373.7,,Sao Jose da Tapera,DONIZETTI TAVARES DE LIM
13882,394.8,01/12/2016,Sao Bernardo do Cam,JUSTINO GOMES DE CASTRO
如何在二进制文件中写入每个字段?
when I try to write, I get a lot of null fields, which doesn't happen when I don't write.
这是正常的,number的内部表示可以包含几个0,比如做:
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
if regdados[i].nroInscricao
值 7 和你的 int 在 32 位上,将写入 3 次 0 和 1 次 7(顺序取决于你是否在 little/big字节序)。
当然和你写的固定大小的字符串是一样的,所以padding characters可以是任意值,包括0(没有初始化)
您使用 getfield 提取字段的方法很昂贵,因为您提取了第一个标记,然后要获取第二个标记,您必须绕过第一个标记,然后才能获取第三个标记你必须绕过 2 个第一个标记等
更好的方法是 getfield(line, 1)
然后 getfield(NULL, 1)
得到第二个标记,然后 getfield(NULL, 1)
得到第三个等等,所以实际上第二个参数总是1 你可以删除它的管理
您尝试打开trabalho1.csv.csv
,可能您想打开trabalho1.csv
在
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
打印错误还不够,千万不要继续,可以
if(ArqBin == NULL)
printf("Error");
else if (stream != NULL) {
或更好地替换
FILE * stream = fopen("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
...
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
...
}
else{
printf("Error");
}
类似
FILE * stream = fopen("trabalho1.csv.csv", "r+");
if (stream == NULL) {
fprintf(stderr, "cannot open input file rabalho1.csv.csv");
return -1;
}
FILE * ArqBin = fopen("test.bin","wb");
if (ArqBin == NULL) {
fprintf(stderr, "cannot open output file test.bin");
fclose(stream); /* really useful if you do not stop execution */
return -1;
}
...
我有以下代码:
typedef struct RegDados{
char removido; // deve ser inicializado com '-'
int encadeamento; // deve ser inicializado com -1
int nroInscricao; // nao aceita valores repetidos nem nulos
double nota;
char data[10]; // checar tipo
char *cidade;
int sizecid;
char tagCampo4;
char *nomeEscola;
int sizesch;
char tagCampo5;
}RegDados;
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("trabalho1.csv.csv", "r+");
FILE * ArqBin = fopen("test.bin","wb");
RegDados regdados[5000];
RegCab regcab;
int i = 0;
if(ArqBin == NULL) printf("Error");
if (stream != NULL) {
char line[1024];
while (fgets(line, 1024, stream)) {
regdados[i].nroInscricao = atoi(getfield(line, 1));
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
regdados[i].nota = atof(getfield(line, 2));
fwrite(®dados[i].nota, sizeof(double), 1, ArqBin);
strcpy(regdados[i].data, getfield(line, 3));
fwrite(regdados[i].data, sizeof(char), 100, ArqBin);
regdados[i].cidade = getfield(line, 4);
fwrite(regdados[i].cidade, sizeof(char), 100, ArqBin);
regdados[i].nomeEscola = getfield(line, 5);
fwrite(regdados[i].nomeEscola, sizeof(char), 100, ArqBin);
i++;
}
fclose(stream);
fclose(ArqBin);
}
else{
printf("Error");
}
}
它已经解析了我文件的字段,但我不能将它们写入二进制文件,因为当我尝试写入时,我得到了很多空字段,而当我不这样做时就不会发生这种情况不写了。
我的 CSV 文件如下所示:
nroInscricao,nota,data,cidade,nomeEscola
13893,353.9,26/11/2016,,FRANCISCO RIBEIRO CARRIL
13595,472.2,,Salgueiro,ALFREDO GUEDES
13894,614.4,28/11/2016,Recife,JOAO DE MOURA GUIMARAES
13880,403.2,29/11/2016,Fortaleza,ANTONIO DIAS PASCHOAL PR
13881,373.7,,Sao Jose da Tapera,DONIZETTI TAVARES DE LIM
13882,394.8,01/12/2016,Sao Bernardo do Cam,JUSTINO GOMES DE CASTRO
如何在二进制文件中写入每个字段?
when I try to write, I get a lot of null fields, which doesn't happen when I don't write.
这是正常的,number的内部表示可以包含几个0,比如做:
fwrite(®dados[i].nroInscricao, sizeof(int), 1, ArqBin);
if regdados[i].nroInscricao
值 7 和你的 int 在 32 位上,将写入 3 次 0 和 1 次 7(顺序取决于你是否在 little/big字节序)。
当然和你写的固定大小的字符串是一样的,所以padding characters可以是任意值,包括0(没有初始化)
您使用 getfield 提取字段的方法很昂贵,因为您提取了第一个标记,然后要获取第二个标记,您必须绕过第一个标记,然后才能获取第三个标记你必须绕过 2 个第一个标记等
更好的方法是 getfield(line, 1)
然后 getfield(NULL, 1)
得到第二个标记,然后 getfield(NULL, 1)
得到第三个等等,所以实际上第二个参数总是1 你可以删除它的管理
您尝试打开trabalho1.csv.csv
,可能您想打开trabalho1.csv
在
if(ArqBin == NULL) printf("Error"); if (stream != NULL) {
打印错误还不够,千万不要继续,可以
if(ArqBin == NULL)
printf("Error");
else if (stream != NULL) {
或更好地替换
FILE * stream = fopen("trabalho1.csv.csv", "r+"); FILE * ArqBin = fopen("test.bin","wb"); ... if(ArqBin == NULL) printf("Error"); if (stream != NULL) { ... } else{ printf("Error"); }
类似
FILE * stream = fopen("trabalho1.csv.csv", "r+");
if (stream == NULL) {
fprintf(stderr, "cannot open input file rabalho1.csv.csv");
return -1;
}
FILE * ArqBin = fopen("test.bin","wb");
if (ArqBin == NULL) {
fprintf(stderr, "cannot open output file test.bin");
fclose(stream); /* really useful if you do not stop execution */
return -1;
}
...