我有一个项目要做一个程序,读取一个.csv文件,需要两个输入,第一个输入是列,第二个输入是关键词。它需要做的是找到所选列中的关键词,并打印出该列中包含该关键词的每一行。我已经在这个问题上卡住了一段时间,只是无法弄清楚。
问题从第75行开始,在那里我得到一个错误“request for member 'Location1' in 'aol',它是非类类型'data [4000]”
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct data{
char Location1[100];
char Location2[100];
char price[10];
char rooms[10];
char bathrooms[10];
char carparks[10];
char type[100];
char furnish[100];
};
struct data aol[4000];
int printedlines;
// Untuk membaca isi file csv
void fileread() {
FILE *fp = fopen("AOLDATA.csv","r");
if(fp == NULL){
printf("Error! File not found.");
exit(0);
}
while(fscanf(fp, "%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^,],%[^\n]", aol[printedlines].Location1, aol[printedlines].Location2,
aol[printedlines].price, aol[printedlines].rooms, aol[printedlines].bathrooms, aol[printedlines].carparks,
aol[printedlines].type, aol[printedlines].furnish) != EOF) {
printedlines++;
fgetc(fp);
}
fclose(fp);
}
void searchData(char *keyword) {
int found = 0;
for(int i = 0; i < printedlines; i++) {
if(strstr(aol[i].Location1, keyword) || strstr(aol[i].Location2, keyword) ||
strstr(aol[i].price, keyword) || strstr(aol[i].rooms, keyword) ||
strstr(aol[i].bathrooms, keyword) || strstr(aol[i].carparks, keyword) ||
strstr(aol[i].type, keyword) || strstr(aol[i].furnish, keyword)) {
printf("%-20s%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n", aol[i].Location1, aol[i].Location2, aol[i].price, aol[i].rooms,
aol[i].bathrooms, aol[i].carparks, aol[i].type, aol[i].furnish);
found++;
}
}
if(!found) {
printf("Data not found!");
}
}
int main(){
int option;
char line[100];
fileread();
printf("What do you want to do?\n1.Display data\n2.Search Data\n3.Sort Data\n4.Export Data\n5.Exit\n");
printf("Your choice: ");
scanf("%d", &option);
if(option == 1){
int howmanylines;
int printedlines = 0;
printf("Number of rows: ");
scanf("%d", &howmanylines);
for(int i = 0; i < howmanylines; i++) {
printf("%-20s%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n", aol[i].Location1, aol[i].Location2, aol[i].price, aol[i].rooms,
aol[i].bathrooms, aol[i].carparks, aol[i].type, aol[i].furnish);
}
}else if(option == 2){
char choice[100];
char column[100];
printf("Choose column: ");
scanf("%s", column); getchar();
printf("What do you want to find? ");
scanf("%s", choice); getchar();
if(choice == aol.Location1){
for(int i=0; i < 3940-1; i+8)
printf("%-20s%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n", aol[i].Location1, aol[i].Location2, aol[i].price, aol[i].rooms
, aol[i].bathrooms, aol[i].carparks, aol[i].type, aol[i].furnish);
}
}
return 0;
}
字符串
输入文件示例:
A B C D E F G H
NY US 10 20 30 40 Bad Expensive
LN UK 20 30 40 50 Good Expensive
JK IN 20 10 50 20 Good Cheap
型
1条答案
按热度按时间mspsb9vt1#
choice == aol.Location1
:比较两个指针(这里总是false),而不是使用strcmp()
来比较字符串。1.对于search,不清楚你是想在结构成员名上搜索,还是第一行是一个header,你想输入一个header列名。我使用了前者,因为它少了一步,但如果你澄清你想要后者,我会更新我的答案。
1.(不固定)如果第一行是一个标题,那么你想为它使用一个不同的类型,比如说,
char **header
,因为它没有数据的约束。如果列的类型是int
,那么列标题仍然是char *
。1.(不固定)考虑使用一个更简单的数据模型。例如一个线数组(
char **data
)。然后一切都会变得更容易处理:字符串
1.在使用
scanf()
阅读字符串时,始终使用最大字段宽度,以避免缓冲区溢出。我引入了字符串长度的符号常量,并使用str()
宏生成合适的格式字符串。1.始终检查
fprintf()
或scanf()
等I/O操作的返回值,否则可能会对未初始化的变量进行操作。1.使用符号常量,如字段的数量或每个选项的名称,而不是硬编码,特别是如果你需要多次使用它。
1.不要使用全局变量,这会让你的代码更难测试。
1.重新格式化菜单以提高可读性。
型
我修改了你的输入文件以匹配你的解析器:
型
示例运行: