如何在文本文件中使用strtok

时间:2018-07-12 04:46:04

标签: c arrays pointers token strtok

我有一个文本文件,如下所示:

Jane Smith 1111

Alex John 2222

Joe Bon 1234

我正在尝试解析此数据并将其放入结构数组中。当我从文件中获取一行并使用strtok时,将打印正确的数据,但不会将其复制到结构中。如何复制数据?这是我的代码:

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

#define MAX_NUM 100

struct object {
  char fname[20];
  char lname[20];
  char phoneNum[20];
};

typedef struct object Person;

int main (int argc, char ** argv) {
  FILE *fp;
  int i = 0;
  Person person[MAX_NUM];

  fp = fopen(argv[1], "r");
  char *token;

  char line[256];

  int y = 1;

  while (fgets(line, sizeof(line), fp)) {
    token = strtok(line, " ");
    arr[0] = token;

     while(token != NULL) {
      token = strtok(NULL, " ");
      arr[y] = token;
      y++;
    }
    strcpy(person[i].fname, arr[0]);
    strcpy(person[i].lname, arr[1]);
    strcpy(person[i].phoneNum, arr[2]);
    i++;
  }

  printf("%s\n", person[i].fname); //why does nothing print
  printf("%s\n", person[i].lname);
  printf("%s\n", person[i].phoneNum);

}

3 个答案:

答案 0 :(得分:2)

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

#define MAX_NUM 100

struct object {
  char fname[20];
  char lname[20];
  char phoneNum[20];
};

typedef struct object Person;

int main (int argc, char *argv[])
{
    FILE *fp;
    int i;
    Person person[MAX_NUM];
    char line[256];

    // Check command line arguments
    if (argc != 2)
    {
        printf("Usage: %s <file>\n", argv[0]);
        return -1;
    }

    // Check FILE *
    if ((fp = fopen(argv[1], "r")) == NULL)
    {
        printf("FAILED TO OPEN %s\n", argv[1]);
        return -1;
    }

    while (fgets(line, sizeof(line), fp))
    {
        if (sscanf(line, "%s %s %s", person[i].fname, person[i].lname, person[i].phoneNum) < 3)
        {
            printf("ILLEGAL TEXT: <<%s>>\n", line);
        }
        else
        {
            printf("RECORD %s %s %s\n", person[i].fname, person[i].lname, person[i].phoneNum);
            i++;
        }
    }

    // Close file
    fclose(fp);

    printf("%d RECORD(S) HAVE(HAS) BEEN PARSED SUCCESSFULLY\n", i);

    return 0;
}

demo.data:

Jane Smith 1111 
Alex John 2222 
Joe Bon 1234 
Invalid line
 Space  Tab 6666
Joy Allen 2333
Jane Smith 1111 
Alex John 2222 
Joe Bon 1234 
Invalid line
 Space Tab 6666
Joy Allen 2333
Jane Smith 1111 
Alex John 2222 
Joe Bon 1234 
Invalid line
 Space Tab 6666
Joy Allen 2333

运行:

$ ./demo demo.data
RECORD Jane Smith 1111
RECORD Alex John 2222
RECORD Joe Bon 1234
ILLEGAL TEXT: <<Invalid line
>>
RECORD Space Tab 6666
RECORD Joy Allen 2333
RECORD Jane Smith 1111
RECORD Alex John 2222
RECORD Joe Bon 1234
ILLEGAL TEXT: <<Invalid line
>>
RECORD Space Tab 6666
RECORD Joy Allen 2333
RECORD Jane Smith 1111
RECORD Alex John 2222
RECORD Joe Bon 1234
ILLEGAL TEXT: <<Invalid line
>>
RECORD Space Tab 6666
RECORD Joy Allen 2333
15 RECORD(S) HAVE(HAS) BEEN PARSED SUCCESSFULLY

答案 1 :(得分:0)

好吧,您应该怀疑在打印时uint32_t的值是什么...

这是您留下的地方,只有一个传递了i数组中存储的最后一个值,因此毫无价值就不足为奇了。

修复很简单:只需循环person

i

答案 2 :(得分:0)

如果要解析此数据并将其放入结构数组中,则可以使用以下功能:

char  ** split(char string[], int * num, char * sep) 
{
    char * pch;
    char ** out = 0;
    int i = 0;
    pch = strtok(string, sep);

    while (pch != 0) {
        out = realloc(out, (i + 1) * sizeof(char *));
        out[i] = malloc(strlen(pch) + 1);
        strcpy(out[i], pch);
        ++i;
        pch = strtok(NULL, sep);
    }
    *num = i;
    return out;
}

该函数将字符串分成2d数组,您可以将其放入struct