如果您有固定的列宽,您可以使用指针算术来访问字符串
str
的子串。 如果您有一个起始索引
begin
,
printf("%s", str + begin) ;
将打印从begin
开始直到结尾的子字符串。如果您想要打印特定length
的字符串,可以使用printf
的精度限定符.*
,该限定符需要一个最大长度作为附加参数:
printf("%.*s", length, str + begin) ;
如果你想将字符串复制到临时缓冲区,可以使用strncpy
,如果缓冲区大于子字符串长度,它将生成一个空终止的字符串。你也可以根据上述模式使用snprintf
:
char buf[length + 1];
snprintf(buf, sizeof(buf), "%.*s", length, str + begin) ;
这将提取前导和尾随空格,这可能不是您想要的。您可以编写一个函数来删除不需要的空格;在SO上应该有很多示例。
您还可以在复制子字符串时去除空格。下面的示例代码使用
<ctype.h>
中的
isspace
函数/宏来实现此操作:
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
int extract(char *buf, const char *str, int len)
{
const char *end = str + len;
int tail = -1;
int i = 0;
while (str < end && *str && isspace(*str)) str++;
while (str < end && *str) {
if (!isspace(*str)) tail = i + 1;
buf[i++] = *str++;
}
if (tail < 0) tail= i;
buf[tail] = '\0';
return tail;
}
int main()
{
char str[][80] = {
"0PAUL 22 ACACIA AVENUE 02/07/1986RN666",
"1BOB 1 POLK ST 01/04/1988RN802",
"2ALICE 99 WEST HIGHLAND CAUSEWAY 28/06/1982RN774"
};
int i;
for (i = 0; i < 3; i++) {
char *p = str[i];
char id[2];
char name[20];
char number[6];
char street[35];
char bday[11];
char ref[11];
extract(id, p + 0, 1);
extract(name, p + 1, 19);
extract(number, p + 20, 5);
extract(street, p + 25, 34);
extract(bday, p + 59, 10);
extract(ref, p + 69, 10);
printf("<person id='%s'>\n", id);
printf(" <name>%s</name>\n", name);
printf(" <house>%s</house>\n", number);
printf(" <street>%s</street>\n", street);
printf(" <birthday>%s</birthday>\n", bday);
printf(" <reference>%s</reference>\n", ref);
printf("</person>\n\n");
}
return 0;
}
然而,这里存在风险:当您在特定位置访问字符串
str + pos
时,应确保不超出实际字符串长度。例如,您的字符串可能在名称后终止。当您访问生日时,您会访问有效的内存,但它可能包含垃圾。
您可以通过使用空格填充完整字符串来避免此问题。