完全公开:学校分配
我一直在研究一些代码,以从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,但是我一直遇到这个错误,我似乎无法克服。对于我,...'
使用strtok
时,您必须了解它会修改您要标记的字符串。如果在调用strtok
之后需要使用字符串,则应首先复制该字符串。如果不确定确切的工作方式,请务必检查man page
是否使用了任何功能。 man 3 strtok