C程序编译报错求助:解决[-Waddress]与[-Wpointer-arith]警告
CSV解析C程序编译错误修复方案
编译错误说明
遇到的编译错误分为两类:
comparison with string literal results in unspecified behavior [-Waddress]:直接用==比较字符串指针与字面量,C语言中==比较的是指针地址而非字符串内容,属于错误用法。pointer of type 'void *' used in arithmetic [-Wpointer-arith]:void*指针无法直接做算术运算,编译器无法确定其指向数据的类型大小,无法计算偏移量。
具体修改点
1. 修复字符串比较错误
将所有structure == "xxx_t"的判断替换为strcmp(structure, "xxx_t") == 0,strcmp是C标准库专门用于字符串内容比较的函数,返回0代表两个字符串相等。
2. 修复void*指针算术运算错误
不要直接对void*类型的table指针做加法,改用count变量计算当前元素索引,通过数组下标方式访问结构体,避免指针运算错误。
修改后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // Define the structure for table1 typedef struct { char customer_code[31]; char firstname[101]; char lastname[101]; } table1_t; // Define the structure for table2 typedef struct { char customer_code[31]; char invoice_code[31]; float amount; char date[11]; // Assuming DATE is in 'YYYY-MM-DD' format } table2_t; // Define the structure for table3 typedef struct { char invoice_code[31]; char item_code[31]; float amount; int quantity; } table3_t; // Define the structure for table4 typedef struct { char customer_code[31]; } table4_t; int rows; // Function to read CSV file and populate the table name passed int parse_csv(const char *filename, void *table, const char *structure) { FILE *fp = fopen(filename, "r"); if (!fp) { perror("Error opening file"); return -1; } // Skip the first record char line[4096]; fgets(line, sizeof(line), fp); int count = 0; while (fgets(line, sizeof(line), fp)) { if (strcmp(structure, "table1_t") == 0) { table1_t *t1 = (table1_t *)table + count; sscanf(line, "%[^,],%[^,],%s", t1->customer_code, t1->firstname, t1->lastname); } else if (strcmp(structure, "table2_t") == 0) { table2_t *t2 = (table2_t *)table + count; sscanf(line, "%[^,],%[^,],%f,%s", t2->customer_code, t2->invoice_code, &t2->amount, t2->date); } else if (strcmp(structure, "table3_t") == 0) { table3_t *t3 = (table3_t *)table + count; sscanf(line, "%[^,],%[^,],%f,%d", t3->invoice_code, t3->item_code, &t3->amount, &t3->quantity); } else if (strcmp(structure, "table4_t") == 0) { table4_t *t4 = (table4_t *)table + count; sscanf(line, "%[^,]", t4->customer_code); } else { fprintf(stderr, "Invalid table structure\n"); fclose(fp); return -1; } count++; } fclose(fp); return count; } int main() { // Process table1 table1_t table1[500000]; rows = parse_csv("table1.csv", table1, "table1_t"); printf("Number of rows in table1: %d\n", rows); //Process table2 table2_t table2[1000000]; rows = parse_csv("table2.csv", table2, "table2_t"); printf("Number of rows in table2: %d\n", rows); //Process table3 table3_t table3[5000000]; rows = parse_csv("table3.csv", table3, "table3_t"); printf("Number of rows in table3: %d\n", rows); //Process table4 table4_t table4[1000]; rows = parse_csv("table4.csv", table4, "table4_t"); printf("Number of rows in table4: %d\n", rows); return 0; }
额外说明
(table1_t *)table + count的写法,是将void*转换为结构体指针后,指针加法会自动按结构体大小计算偏移量,比直接操作void*更安全。- 当前
sscanf的%[^,]格式符只能处理无引号包裹的简单CSV字段,如果需要处理包含逗号的带引号字段,建议使用专门的CSV解析库。
内容的提问来源于stack exchange,提问作者Tom
相关产品推荐
相关产品推荐

