Reading from CSV with fgets() and strtok()

自古美人都是妖i 提交于 2020-01-24 13:35:29

问题


FULL DISCLOSURE: SCHOOL ASSIGNMENT

I've been working on some code to pull data from a CSV and display it, however I keep encountering this error I can't seem to overcome.

The code would be pretty simple, but the problem is that our CSV can have spaces before or after the comma, which means you can't just strtok() because it will include the space. Therefore, you need to remove the spaces before printing. I attempted to achieve this by strtok() the CSV, then running said token through a function to eliminate any spaces. However, this seems to be where the issue is happening. I keep getting a "read access violation" on line 12 that I don't understand. Any help would be appreciated. I've posted the database.c code and database.csv that it's accessing.

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=%-3s NAME:%-3s AGE:%-3d GPA:%-3f\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;
        }
        else {
            fputs(buffer, csvwrite);
        }
    }
    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");
        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,%f", 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");
        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");
            exit(1);
        }
        deleteStuff(argv[2]);
    }
    else if (strcmp(argv[1], add) == 0) {
        if (argc <= 3) {
            printf("Missing ID, Name, AGE, and GPA Arguments");
            exit(1);
        }
        addStuff(argv[2], argv[3], argv[5], argv[5]);
    }
    else printf("The command you requested in invalid. Please select from one of these: SHOW, DELETE, ADD");
}

database.csv:

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

来源:https://stackoverflow.com/questions/58868089/reading-from-csv-with-fgets-and-strtok

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!