问题
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