使用fgets()和跳过行从另一个CSV写入CSV

问题描述 投票:0回答:1

完全公开:学校分配

我一直在研究一些代码,以从CSV提取数据并将其移动到另一个CSV,但是我一直遇到这个错误,我似乎无法克服。

对于我正在处理的部分,用户在命令行参数中提供'DELETE OPT1',其中OPT1是CSV中条目的ID。 deleteStuff()函数应遍历database.csv并删除匹配ID的第一个条目/行。它应该通过创建一个database.tmp,然后将database.csv复制到tmp(不包括第一个匹配条目)来实现。然后删除csv,然后将tmp重命名为database.csv,好像什么都没发生。

但是,源代码(database.csv)似乎做错了,删除了除ID之外的所有内容。在下面,我发布了源代码和启动的database.csv,以及运行DELETE 10之后代码输出的内容。任何帮助将不胜感激,尤其是在理解如何获取fgets()的下一行时。

请注意,noSpaces()函数只会删除任何空格,因为根据我们的教授可能会将它们包含在输入中。

database.c:

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

char show[] = "SHOW";
char delete[] = "DELETE";
char add[] = "ADD";

void noSpaces(char* s) {
        const char* d = s;
        do {
                while (*d == ' ') {
                        ++d;
                }
        } while (*s++ = *d++);
}

void showStuff() {
        FILE* csv = fopen("database.csv", "rt");
        if (csv == NULL) {
                printf("\n File opening failed");
                exit(1);
        }
        char buffer[800];
        char *Gptr, *ID, *name, *cAge, *cGPA;
        int counter = 1;
        while (fgets(buffer, sizeof(buffer), csv)) {
                ID = strtok(buffer, ",");
                noSpaces(ID);
                name = (strtok(NULL, ","));
                noSpaces(name);
                cAge = (strtok(NULL, ","));
                noSpaces(cAge);
                int age = atoi(cAge);
                cGPA = (strtok(NULL, ","));
                noSpaces(cGPA);
                double GPA = strtod(cGPA, &Gptr);
                printf("Record %d: ID=%-5s NAME:%-5s AGE:%-5d GPA:%.1f\n", counter, ID, name, age, GPA);
                counter++;
        }
        fclose(csv);
}

void deleteStuff(char givenID[]) {
        FILE* csvread = fopen("database.csv", "rt");
        if (csvread == NULL) {
                printf("\n File opening failed");
                exit(1);
        }
        FILE* csvwrite = fopen("database.tmp", "wt");
        char buffer[800];
        char* ID;
        int oneAndDone = 0;
        while (fgets(buffer,sizeof(buffer),csvread)) {
                ID = strtok(buffer, ",");
                noSpaces(ID);
                if ((strcmp(ID, givenID) == 0) && (oneAndDone == 0)) {
                        oneAndDone++;
                        continue;
                }
                fprintf(csvwrite, "%s", buffer);
        }
        system("rm database.csv");
        system("mv database.tmp database.csv");
        fclose(csvread);
        fclose(csvwrite);
        if (oneAndDone == 0) {
                printf("Sorry, the user was not found. Nothing was deleted.\n\n");
                exit(1);
        }
}

void addStuff(char gID[], char gName[], char gAge[], char gGPA[]) {
        char* Gptr;
        int age = atoi(gAge);
        double GPA = strtod(gGPA, &Gptr);
        FILE* csvappend = fopen("database.csv", "at");
        if (csvappend == NULL) {
                printf("\n File opening failed");
                exit(1);
        }
        fprintf(csvappend, "%s,%s,%d,%.1f", gID, gName, age, GPA);
        fclose(csvappend);
}

void main(int argc, char* argv[]) {
        if (argc == 1) {
                printf("Your did not provide any arguments. Please enter: ./database CMD OPT1 OPT2 OPT3 OPT4 \n\n");
                exit(1);
        }
        if (strcmp(argv[1], show) == 0) showStuff();
        else if (strcmp(argv[1], delete) == 0) {
                if (argc <= 2) {
                        printf("Name of record to delete is missing\n\n");
                        exit(1);
                }
                deleteStuff(argv[2]);
        }
        else if (strcmp(argv[1], add) == 0) {
                if (argc <= 5) {
                        printf("Missing ID, Name, AGE, and GPA Arguments\n\n");
                        exit(1);
                }
                addStuff(argv[2], argv[3], argv[4], argv[5]);
        }
        else printf("The command you requested in invalid. Please select from one of these: SHOW, DELETE, ADD\n\n");

}

原始数据库.csv:

10,bob,18, 3.5
15,mary,20,4.0
5,tom, 17, 3.8

在database.csv之后:

155

完全公开:学校分配我一直在研究一些代码,以从CSV中提取数据并将其移动到另一个CSV,但是我一直遇到这个错误,我似乎无法克服。对于我,...'

c csv fopen fgets
1个回答
0
投票

使用strtok时,您必须了解它会修改您要标记的字符串。如果在调用strtok之后需要使用字符串,则应首先复制该字符串。如果不确定确切的工作方式,请务必检查man page是否使用了任何功能。 man 3 strtok

© www.soinside.com 2019 - 2024. All rights reserved.