[英]How can I alphabetize the first column of a .csv file in C?
我有一個 .csv 文件。 假設數據是這樣的:
Location 1,Location 2,Price,Rooms,Bathrooms,CarParks,Type,Area,Furnish
Upper-East-Side,New-York,310000,3,2,0,Built-up,1000,Partly
West-Village,New-York,278000,2,2,0,Built-up,1000,Partly
Theater-District,New-York,688000,3,2,0,Built-up,1000,Partly
預計 output(按字母順序排列):
Theater-District
Upper-East-Side
West-Village
我怎樣才能只顯示文件的第一列(位置 1)並按字母順序排序,同時還跳過 header?
這是目前我的代碼,但它仍處於“讀取和顯示”形式。
#include <stdio.h>
int main()
{
FILE *fh;
fh = fopen("file.csv", "r");
if (fh != NULL)
{
int line_number = 0;
char c;
while ( (c = fgetc(fh)) != EOF )
{
if(line_number > 0 || c == '\n'){
putchar(c);
}
if(c == '\n'){
line_number++;
}
}
fclose(fh);
} else printf("Error opening file.\n");
return 0;
}
csv 不是一個定義明確的格式,所以我建議您使用現有的 csv 庫,而不是自己解析數據。 例如,如果第一個字段有任何嵌入的逗號,這將不起作用。 它依靠 scanf() 來分配行,並根據需要調整lines
數組的大小。 這意味着沒有任意限制。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int strcmp2(const void *a, const void *b) {
return strcmp((const char *) a, (const char *) b);
}
int main() {
FILE *f = fopen("unsorted.csv", "r");
if(!f) return 1;
char **lines = NULL;
size_t n = 0;
for(;; n++) {
char *location1;
int rv = fscanf(f, "%m[^,]%*[^\n]\n", &location1);
if(rv != 1) break;
char **tmp = realloc(lines, (n + 1) * sizeof *tmp);
if(!tmp) return 1;
lines = tmp;
tmp[n] = location1;
}
fclose(f);
free(lines[0]); // header
qsort(&lines[1], n - 1, sizeof *lines, strcmp2);
for(size_t i = 1; i < n; i++) {
printf("%s\n", lines[i]);
free(lines[i]);
}
free(lines);
}
它產生預期的 output:
Theater-District
Upper-East-Side
West-Village
因此,假設對行長度和 CSV 文件記錄數有一些硬性限制,我們可以只使用 arrays。
要讀取記錄,只需使用fgets()
。 使用通常的方法將每一行文本添加到數組中。
我們使用簡單的字符串搜索和截斷來隔離第一個字段。 (假設沒有像雙引號字段這樣花哨的東西。我假設你正在做作業。)
要對除CSV header 記錄以外的所有內容進行排序,請使用qsort()
和一些額外的數學運算。
#include <iso646.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define unused(x) (void)(x)
#define MAX_LINE_LENGTH 100
#define MAX_RECORD_COUNT 100
int main( int argc, char ** argv )
{
unused( argc );
char records[MAX_RECORD_COUNT][MAX_LINE_LENGTH];
size_t record_count = 0;
const char * filename = argv[1];
if (!filename) return 1;
// Read our records from file
FILE * f = fopen( filename, "r" );
if (!f) return 1;
while ((record_count < MAX_RECORD_COUNT)
and fgets( records[record_count], MAX_LINE_LENGTH, f ))
record_count += 1;
fclose( f );
// Truncate the strings to just the first field
for (size_t n = 0; n < record_count; n++)
{
char * p = strchr( records[n], ',' );
if (p) *p = '\0';
}
// Sort everything but the header
if (record_count > 2) // must exist at least two records + header
qsort( records+1, record_count-1, MAX_LINE_LENGTH,
(int (*)( const void *, const void * ))strcmp );
// Print everything but the header
for (size_t n = 1; n < record_count; n++)
printf( "%s\n", records[n] );
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.