簡體   English   中英

如何按字母順序排列 C 中 a.csv 文件的第一列?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM