解决问题的另一种标准方法是简单地使用设置为行尾的指针,然后备份——修剪空格(和 nul 终止)直到找到一个字母或数字——然后只是备份直到你找到然后是下一个空格。由于您的指针现在指向之前的最后一个空白weight
,只需保存一个指向current + 1
开头的指针weight
(再次重复height
)
您现在已经保存了一个指向的指针,height
并且您的指针现在指向之前的最后一个空格height
。只需继续备份空格(随时以nul 结尾),直到您到达下一个字母或数字(这将是名称的结尾),或者您点击了字符串的开头(出了点问题,您没有找到`姓名、身高、体重)。
由于到目前为止您一直在以nul 终止,因此您知道现在读取的缓冲区仅包含name
,因此您可以简单地打印输出并阅读下一行。绝对没有什么是您无法通过将指针(或指针对)沿字符串(或在本例中为字符串)向下移动来解析的
总而言之,您可以执行类似于以下的操作:
#include <stdio.h>
#include <ctype.h>
enum { MAXHW = 2, MAXC = 512 }; /* if you need constants, define them */
int main (int argc, char **argv) {
char buf[MAXC] = ""; /* line buffer */
FILE *fp = argc > 1 ? fopen (argv[1], "r") : stdin;
if (!fp) { /* validate file open for reading */
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
while (fgets (buf, MAXC, fp)) { /* read each line */
char *p = buf, /* pointer to buf */
*hw[MAXHW] = {NULL}; /* array of MAXHW pointers */
int ndx = 0; /* array index */
while (*p) p++; /* find end of buf */
p--; /* backup to last char */
while (p > buf) { /* while pointer within buf */
/* loop checking if char is a trailing space, tab, newline, ... */
while (p > buf && isspace (*p))
*p-- = 0; /* overwrite with nul-terminating char */
/* loop checking each char is a letter or digit */
while (p > buf && isalnum (*p))
p--; /* just backup to previous char */
hw[ndx++] = p + 1; /* space before word found, save ptr to word */
if (p != buf) /* if not at beginning */
*p = 0; /* nul-terminate */
else
break; /* at beginning - bail */
if (ndx == MAXHW) /* if both h & w filled */
break; /* bail */
p--; /* backup to previous and keep going */
}
if (p > buf && ndx == MAXHW) { /* not at beginning & H & W found */
p--; /* backup to previous */
/* trim trailing whitespace to end of name */
while (p > buf && isspace (*p))
*p-- = 0;
}
/* output results */
printf ("name: %s, height: %s, weight: %s\n", buf, hw[1], hw[0]);
}
if (fp != stdin) fclose (fp); /* close file if not stdin */
return 0;
}
示例使用/输出
$ ./bin/readhw <dat/hw.dat
name: Yuri, height: 164, weight: 80
name: Lai San Young, height: 155, weight: 60
name: John Wayne, height: 180, weight: 93
有很多很多不同的方法可以做到这一点。您可能没有使用ctype.h
和检查,例如if (p > buf && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n')
使用显式检查空格代替isspace()
等。您可以使用strpbrk
在字符串中向前扫描您的第一个数字并从那里向前和向后工作。不管你怎么做,关键是把你的字符串写在一张纸上,然后用铅笔前后移动你的指针位置,同时找出你需要的测试和索引。
如果您还有其他问题,请查看并告诉我。