You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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_line function 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, or Close) 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.13

End of the column

内容的提问来源于stack exchange,提问作者fire fireeyyy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:41:06