如何计算文件中的列

时间:2016-03-12 03:41:42

标签: c pointers multidimensional-array

我正在尝试计算txt.file中的列数 示例文件( txt_file.txt ):

aaron 1 2 3
bethi 1 2 3
dylan 1 2 3
kevin 1 2 3

这是我的代码片段:( main.c)

int main(int argc, char *argv[])
{
//File based variables
char line[1024] = {0x0};
char name[100] = {0x0};
int i, j;

//Array based variables
int students = 0,
    assignments = 0,
    count = 0;

//File pointer, refer to file as fp now.
FILE *fp;
printf("the input file name is %s\n",  argv[1]);
if ( fp == NULL )
{
  puts ( "Cannot open source file");
}

// open file in read mode & get size
fp = fopen(argv[1], "r");
**get_data_size(fp,&students,&assignments);** //Function returning junk

//MY array for grades
//-------------------------------------------
int **grades = (int **)malloc(assignments * sizeof(int *));
for (i = 0; i < assignments; i++)
{
  grades[i] = (int *)malloc(students * sizeof(int));
  if (grades[i] == NULL)
  {
     fprintf(stderr, "Not enough memory to allocate\n");
     exit(1);
  }
}

get_data_size函数的代码片段:(使用:查找并确定文件大小。行与列)

void get_data_size(FILE *fp, int *students, int *assignments)
{
//File based variables
char line[1024] = {0x0};
char name[100] = {0x0};

while(fgets(line, 1023, fp)) //rows
{
  students++;
}

fseek(fp, 0, SEEK_SET);
char delims[] = ",";
char *result = strtok( line, delims );
while( result != NULL )  //columns
{
  assignments ++;
  printf( "result is \"%s\"\n", result );
  result = strtok( NULL, delims );
}
//These are what return strange junk.
printf("The number of counts, or columns in the array is: %d\n",&assignments);
printf("The number of lines, or rows in the array is: %d\n",&students);
}

2 个答案:

答案 0 :(得分:1)

尝试strtok()strtok_r(),它可以将"Abc Efg Ghi"剥离为"Abc", "Efg", "Ghi",您可以计算总列数并将"Abc", "Efg", "Ghi"存储在2- D阵列。

char *strtok(char *str, const char *delim);
char *strtok_r(char *str, const char *delim, char **saveptr);

strtok()函数返回指向下一个&#34;令牌的指针&#34;在str1中,str2包含确定令牌的分隔符。如果未找到令牌,则strtok()会返回NULL。为了将字符串转换为标记,对strtok()的第一次调用应该使str1指向要标记化的字符串。之后的所有调用都应该str1为NULL

另外,您可以阅读docs

例如:

char str[] = "Abc Efg Ghi";
char delims[] = " ";
char *result = NULL; 
int count = 0;
result = strtok( str, delims );
while( result != NULL ) {
    count ++;
    printf( "result is \"%s\"\n", result );
    result = strtok( NULL, delims );
}
printf("The total column is %d\n", count);

以上代码将显示以下输出:

result is "Abc "
result is "Efg"
result is "Ghi"
The total column is 4

以下代码从名为test.csv的文件中读取文本,并将数据存储到二维数组中。

test.csv

alice, 22, 1992/03/05
bob, 33, 1981/11/21
cart, 40, 1974/07/13

readfile.c

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char *trim(char *str)
{
    char *p = str; 
    while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
        p ++;
    str = p; 
    p = str + strlen(str) - 1; 
    while (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
        -- p;
    *(p + 1) = '\0'; 
    return str; 
}
int main()
{
    int i, j;
    char ** data = (char **)malloc(100 * sizeof(char *));
    for (i = 0; i < 100; i ++)
    {
        data[i] = (char *)malloc(20 * sizeof(char));
    }
    char *** mydata = (char ***)malloc(3 * sizeof(char **));
    for (i = 0; i < 3; i ++)
    {
        mydata[i] = (char **)malloc(3 * sizeof(char *));
        for (j = 0; j < 3; j ++)
        {
            mydata[i][j] = (char *)malloc(20 * sizeof(char));
        }
    }

    FILE *fp = fopen("test.csv", "r");
    if(fp == NULL) {
        return -1;
    }

    char line[1024];
    int row = 0;
    while(fgets(line, sizeof(line), fp)) 
    {
        //printf("%s", line);

        char *save_ptr;
        char *name = strtok_r(line, ",", &save_ptr);
        if (name == NULL) {
            return -1;
        }
        //printf("%s\n", save_ptr);
        char *age = strtok_r(NULL, ",", &save_ptr);
        //printf("%s\n", save_ptr);
        char *birthday = strtok_r(NULL, ",", &save_ptr);
        //printf("%s\n", save_ptr);
        strcpy(mydata[row][0], trim(name));
        strcpy(mydata[row][1], trim(age));
        strcpy(mydata[row][2], trim(birthday));
        //printf("%s\t%s\t%s\n", trim(name), trim(age), trim(birthday));
        row ++;
    }
    for (row = 0; row < 3; row ++)
    {
        printf("%s\t%s\t%s\n", mydata[row][0], mydata[row][1], mydata[row][2]);
    }
    return 0;
}

该功能拆分,,您也可以拆分" "。您可以根据需要更改代码。

希望这两个功能可以帮助您存储数据并获取列号。

答案 1 :(得分:1)

计算字符串中数据列的一种非常简单的方法是将指针向下移动并检查每个字符。如果遇到非空白字符,请将计数增加1,然后扫描以查找下一个空格。然后只需向前扫描,同时字符继续为空格,直到找到下一个非空格字符并(重复)。符合该法案的快速功能可能是:

/** count columns of data in a character string.
 */
int countcol (const char *s)
{
    if (!s || !*s) return 0;    /* validate input */

    char *p = s;    /* pointer to buf */
    int col = 0;    /* initialize col */

    while (*p) { /* for each char in buf */
        /* if p points to non-whitespace, col + 1 */
        if (*p != ' ' && *p != '\t') col++, p++;
        /* skip non-whitespace to find whitespace */
        while (*p && *p != ' ' && *p != '\t') p++;
        /* skip multiple whitespace together */
        while (*p && (*p == ' ' || *p == '\t')) p++;
    }
    return col;
}

一个小样本程序,可以读取stdin上的信息并计算每行中的列数:

#include <stdio.h>

enum { MAXC = 64 };

void rmcrlf (char *str);
int countcol (const char *s);

int main (void) {

    char buf[MAXC] = "";
    int col = 0;

    while (fgets (buf, MAXC, stdin)) {  /* read from stdin    */

        rmcrlf (buf);   /* remove trailing '\n' read by fgets */
        if (!*buf) continue;            /* skip empty line    */
        col = countcol (buf);
        printf ("'%s' (%d-col)\n", buf, col);
    }

    return 0;
}

/** stip trailing newlines and carraige returns by overwriting with
 *  null-terminating char. str is modified in place.
 */
void rmcrlf (char *str)
{
    if (!str || !*str) return;
    char *p = str;
    for (; *p; p++)
        if (*p == '\n' || *p == '\r') { *p = 0; break; }
}

/** count columns of data in a character string.
 */
int countcol (const char *s)
{
    if (!s || !*s) return 0;    /* validate input */

    char *p = s;    /* pointer to buf */
    int col = 0;    /* initialize col */

    while (*p) { /* for each char in buf */
        /* if p points to non-whitespace, col + 1 */
        if (*p != ' ' && *p != '\t') col++, p++;
        /* skip non-whitespace to find whitespace */
        while (*p && *p != ' ' && *p != '\t') p++;
        /* skip multiple whitespace together */
        while (*p && (*p == ' ' || *p == '\t')) p++;
    }
    return col;
}

注意:调整常量MAXC以满足您的输入长度;另请注意rmcrlf函数只是删除回车换行'\n')从fgets读取的字符串末尾,用0覆盖任一字符( nul-terminatedating < / em> character))

输入文件

$ cat dat/text_file.txt
aaron 1 2 3
bethi 1 2 3
dylan 1 2 3
kevin 1 2 3

使用/输出

$ ./bin/file_count_col <dat/text_file.txt
'aaron 1 2 3' (4-col)
'bethi 1 2 3' (4-col)
'dylan 1 2 3' (4-col)
'kevin 1 2 3' (4-col)

如果您有任何问题,请与我们联系。