文件处理加上c中的标记化

时间:2015-04-10 13:09:37

标签: c file token tokenize

我要做的是从标准输入中输入以下格式

输入:

22|Subject 1|45
23|Subject 2|52
22|Subject 2|51
26|Subject 1|72
23|Subject 2|61
26|Subject 1|81

这不过是 学生证|主题|标记 现在我想标记这些细节并将它们存储在结构变量中,以便我可以对它们进行计算。此代码无效。最后一行中的printf给出5 0作为输出,这是不正确的。请帮忙。

struct student
{
  int sid;
  char sub[35];
  int marks;
};


void main()
{
  struct student std[16];
  int i,ch,j;
  char temp[50];
  FILE *fp;
  clrscr();
  //fp=fopen("xyz.txt", "r");
  //fscanf(fp,"%s", temp);
  //printf("\n%s", temp);
  i=0;
  std[i].sid=0;
  while((ch = getchar()) != EOF && i < 6)
  {
    std[i].sid = 10 * std[i].sid + (int)(ch - '0');
    while((ch = getchar()) != '|')
    {
      std[i].sid = 10 * std[i].sid + (int)(ch - '0');
    }
    while((ch = getchar()) != '|')
    {
      std[i].sub[j++] = ch;
    }
    std[i].sub[j] = '\0';
    std[i].marks = 0;
    while ((ch = getchar()) != '\n')
    {
      std[i].sid = 10 * std[i].marks + (int)(ch - '0');
    }
    i++;

    if (i < 6)
      std[i].sid = 0;
  }
  printf("%d %s %d",std[0].sid, &(std[1].sub[0]), std[2].marks);
  //fclose(fp);
  getch();
}

2 个答案:

答案 0 :(得分:0)

您应该使用库函数而不是手动执行,就像这样

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

struct student
{
  int sid;
  char sub[35];
  int marks;
};


int main(void)
{
  struct student std[16];
  size_t i;
  size_t count;
  char   line[100];

  i          = 0;
  std[i].sid = 0;
  count      = sizeof(std) / sizeof(std[0]);
  while (((fgets(line, sizeof(line), stdin)) != NULL) && (i < count))
  {
    char *token;
    char *endptr;

    token = strtok(line, "|");
    if (token == NULL)
      continue;        
    std[i].sid = strtol(token, &endptr, 10);
    if (*endptr != '\0')
      continue;

    token = strtok(NULL, "|");
    if (token == NULL)
      continue;
    /* WARNING: no bound checking is being performed, DANGER ... */
    strcpy(std[i].sub, token);

    token = strtok(NULL, "|");
    if (token == NULL)
      continue;
    std[i].marks = strtol(token, &endptr, 10);
    if (*endptr != '\0')
      continue;

    ++i;
  }
}

答案 1 :(得分:0)

您的代码运行正常,有几个修复程序。

  • 在填充主题
  • 后将j重置为0
  • 您在计算商标
  • 时使用std[i].sid代替std[i].marks

打印出最后的所有数据:

for (i = 0; i < 6; ++i)
    printf("%d %s %d\n", std[i].sid, &(std[i].sub[0]), std[i].marks);

完整的代码(我添加了clrscr()的垫片,因为我没有conio.h):

// parser.c - Parses student data into struct
// To compile:
//  gcc parser.c -o parser
// To run:
//  ./parser < data.txt

#include <stdio.h> // So compiler doesn't complain

// Shim for clrscr() if <conio.h> not available
void clrscr()
{
    printf("\e[2J\e[1;1H");
}

struct student
{
  int sid;
  char sub[35];
  int marks;
};


void main()
{
  struct student std[16];
  int i,ch,j;
  char temp[50];
  FILE *fp;
  clrscr();
  //fp=fopen("xyz.txt", "r");
  //fscanf(fp,"%s", temp);
  //printf("\n%s", temp);
  i=0;
  std[i].sid=0;
  while((ch = getchar()) != EOF && i < 6)
  {
    std[i].sid = 10 * std[i].sid + (int)(ch - '0');
    while((ch = getchar()) != '|')
    {
      std[i].sid = 10 * std[i].sid + (int)(ch - '0');
    }
    while((ch = getchar()) != '|')
    {
      std[i].sub[j++] = ch;
    }
    std[i].sub[j] = '\0';
    std[i].marks = 0;
    j = 0; // Reset j to 0

    while ((ch = getchar()) != '\n')
    {
      std[i].marks = 10 * std[i].marks + (int)(ch - '0');
    }
    i++;

    if (i < 6)
      std[i].sid = 0;
  }
  for (i = 0; i < 6; ++i)
    printf("%d %s %d\n", std[i].sid, &(std[i].sub[0]), std[i].marks);
  //fclose(fp);
  //getch(); // Commented out as not needed/don't have <conio.h>
}

使用您的数据的输出:

22 Subject 1 45
23 Subject 2 52
22 Subject 2 51
26 Subject 1 72
23 Subject 2 61
26 Subject 1 81

它使用gcc在Linux下编译正常,并在代码清单的顶部添加。