基于第一列对二维数组排序的C语言实现求助
Alright, let's fix this sorting issue for your temp2.dat file. The key here is to keep each row's 4 columns linked together while sorting by the first column—using a struct is perfect for this, and we can leverage the standard C library's qsort function to do the heavy lifting. Here's a complete, working solution:
Step 1: Define a Struct to Bind Row Data
First, we create a struct to store all 4 columns of a single row. This ensures that when we sort, each column stays paired with its original row's first column value:
#include <stdio.h> #include <stdlib.h> #include <string.h> // Struct to hold one row of 4-column data typedef struct { double col1; // First column: our sort key double col2; double col3; double col4; } DataRow;
Step 2: Create a Comparison Function for qsort
The qsort function needs a custom comparison function that tells it how to order our DataRow elements. We'll sort by col1 in ascending order:
// Comparison function for qsort: sorts DataRow by col1 (ascending) int compareRows(const void *a, const void *b) { const DataRow *rowA = (const DataRow *)a; const DataRow *rowB = (const DataRow *)b; // For floating-point values, avoid direct subtraction (precision issues) if (rowA->col1 < rowB->col1) return -1; if (rowA->col1 > rowB->col1) return 1; return 0; }
Step 3: Full Function to Read, Sort, and Write Data
This function handles opening the input file, reading all rows, sorting them, and writing the sorted data to an output file:
int sortDataFile(const char *inputPath, const char *outputPath) { // Open input file FILE *inputFile = fopen(inputPath, "r"); if (!inputFile) { perror("Failed to open input file"); return 1; } // First pass: count total rows to allocate enough memory int rowCount = 0; double d1, d2, d3, d4; while (fscanf(inputFile, "%lf %lf %lf %lf", &d1, &d2, &d3, &d4) == 4) { rowCount++; } rewind(inputFile); // Reset file pointer to start // Allocate memory for all rows DataRow *data = malloc(rowCount * sizeof(DataRow)); if (!data) { perror("Failed to allocate memory"); fclose(inputFile); return 1; } // Read all rows into the struct array for (int i = 0; i < rowCount; i++) { fscanf(inputFile, "%lf %lf %lf %lf", &data[i].col1, &data[i].col2, &data[i].col3, &data[i].col4); } fclose(inputFile); // Sort the array using qsort qsort(data, rowCount, sizeof(DataRow), compareRows); // Open output file and write sorted data FILE *outputFile = fopen(outputPath, "w"); if (!outputFile) { perror("Failed to open output file"); free(data); return 1; } // Write each row (adjust decimal precision as needed) for (int i = 0; i < rowCount; i++) { fprintf(outputFile, "%.6lf %.6lf %.6lf %.6lf\n", data[i].col1, data[i].col2, data[i].col3, data[i].col4); } fclose(outputFile); free(data); // Clean up allocated memory printf("Sorting done! Results saved to %s\n", outputPath); return 0; } // Example main function to run the sort int main() { return sortDataFile("temp2.dat", "sorted_temp2.dat"); }
Key Notes to Avoid Common Mistakes
- Struct Binding: Never sort columns individually—using a struct ensures each row's data stays intact during sorting.
- Floating-Point Comparison: Direct subtraction (like
rowA->col1 - rowB->col1) can lead to precision errors with doubles. Using explicit</>checks is safer. - Memory Management: Always
freethe allocatedDataRowarray to prevent memory leaks. - File Handling: We first count rows to know how much memory to allocate—this avoids guessing or using dynamic resizing (which adds complexity).
Compile this code with a standard C compiler (e.g., gcc sort_data.c -o sort_data), then run the executable—it will read temp2.dat, sort it by the first column, and write the sorted data to sorted_temp2.dat.
内容的提问来源于stack exchange,提问作者user177196

