C语言读取大型CSV按列名输出多列内容的问题求助
Solution: Read CSV Columns by Name in C
Got it, let's fix this so you can read any column by name! Your current code only grabs the first float value from each line and completely ignores the rest of the CSV fields. Here's a rewritten version that lets you specify a column name and outputs the entire column, plus it handles edge cases like missing fields or invalid column names.
Modified Code
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> // Helper function: Split a CSV line into individual fields (trims whitespace) int split_csv_line(char *line, char ***fields, int *num_fields) { *num_fields = 0; char *token = strtok(line, ","); while (token != NULL) { // Trim leading/trailing whitespace from the field char *start = token; while (isspace((unsigned char)*start)) start++; char *end = start + strlen(start) - 1; while (end > start && isspace((unsigned char)*end)) end--; *(end + 1) = '\0'; // Resize fields array to hold the new token *fields = realloc(*fields, (*num_fields + 1) * sizeof(char*)); if (*fields == NULL) { perror("Memory allocation failed"); return -1; } // Allocate memory for the field and copy the trimmed string (*fields)[*num_fields] = malloc(strlen(start) + 1); if ((*fields)[*num_fields] == NULL) { perror("Memory allocation failed"); return -1; } strcpy((*fields)[*num_fields], start); (*num_fields)++; token = strtok(NULL, ","); } return 0; } // Helper function: Find the index of a column name in the header int find_column_index(char **headers, int num_headers, const char *column_name) { for (int i = 0; i < num_headers; i++) { if (strcmp(headers[i], column_name) == 0) { return i; } } return -1; // Column not found } int main() { char buffer[1001]; FILE *fp = fopen("filename.csv", "r"); // Check if file opened successfully if (!fp) { perror("Couldn't open the CSV file"); return EXIT_FAILURE; } // Read and parse the header line if (fgets(buffer, sizeof(buffer), fp) == NULL) { perror("Failed to read header line"); fclose(fp); return EXIT_FAILURE; } buffer[strcspn(buffer, "\n")] = '\0'; // Remove newline character char **headers = NULL; int num_headers; if (split_csv_line(buffer, &headers, &num_headers) != 0) { fclose(fp); return EXIT_FAILURE; } // Get target column name from user char target_column[50]; printf("Enter the column name to read (e.g., Date, Close): "); fgets(target_column, sizeof(target_column), stdin); target_column[strcspn(target_column, "\n")] = '\0'; // Remove newline // Find the index of the target column int col_index = find_column_index(headers, num_headers, target_column); if (col_index == -1) { printf("Error: Column '%s' doesn't exist in the CSV\n", target_column); // Clean up allocated memory for headers for (int i = 0; i < num_headers; i++) { free(headers[i]); } free(headers); fclose(fp); return EXIT_FAILURE; } // Output the column content printf("\nOutput for column '%s':\n", target_column); int line_num = 1; while (fgets(buffer, sizeof(buffer), fp) != NULL) { buffer[strcspn(buffer, "\n")] = '\0'; char **fields = NULL; int num_fields; if (split_csv_line(buffer, &fields, &num_fields) != 0) { // Clean up fields if allocation failed for (int i = 0; i < num_fields; i++) { free(fields[i]); } free(fields); continue; } // Check if the line has enough fields to access the target column if (num_fields >= col_index + 1) { printf("%d: %s\n", line_num, fields[col_index]); } else { printf("%d: [Invalid line - missing fields]\n", line_num); } // Clean up fields memory for this line for (int i = 0; i < num_fields; i++) { free(fields[i]); } free(fields); line_num++; } // Clean up headers memory for (int i = 0; i < num_headers; i++) { free(headers[i]); } free(headers); fclose(fp); printf("\nEnd of the column\n"); return EXIT_SUCCESS; }
Key Improvements & Explanations
- Header Parsing: The code first reads the CSV header to map column names to their positions (indices). This lets you reference columns by name instead of hardcoding positions.
- Field Splitting: The
split_csv_linefunction breaks each line into individual fields, trims extra whitespace (in case fields have leading/trailing spaces), and handles dynamic memory allocation for fields. - Error Handling: Added checks for file opening failures, memory allocation issues, missing columns, and invalid lines with missing fields.
- Flexibility: You can input any valid column name (like
Date,Volume USD, orClose) and the code will output that entire column.
Example Usage
If you run the program and enter Volume USD, the output will look like:
Enter the column name to read (e.g., Date, Close): Volume USD
Output for column 'Volume USD':
1: 26014.29
2: 27111049.25
3: 24521694.72
4: 37356362.78
5: 15035324.13End of the column
内容的提问来源于stack exchange,提问作者fire fireeyyy
相关产品推荐
相关产品推荐

