我正在尝试了解示例指针程序的以下片段,不确定是否可以提出这些问题,如果不是,我会删除!
void f1(char *s) {
char *p, *q;
for (p=q=s; *p != '\0'; p++) {
if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z'))
*q++ = *p;
else if (q > s && *(q-1) != '\n')
*q++ = '\n';
}
*q = '\0';
}
我知道有三个指针p,s和q,但我不确定p=q=s
需要什么?是否检查指针p和q是否在char
a-z之间(一个是小写,另一个是大写)和迭代字母?
任何帮助将不胜感激!
答案 0 :(得分:3)
回答你的问题,如果一个字符不是一个字母,snips会将一个字符串标记为行,它也会将标记组合在一起并剥离它是否在第一行,但不是在最后一个,它将留下一个换行符。
评论它:
void f1(char *s) {
/* Two pointers, q for writing and p for reading */
char *p, *q;
/* Initialize both at the beginning and start looping the input string */
for (p=q=s; *p != '\0'; p++) {
/* If it is a letter, just keep it */
if ((*p >= 'A' && *p <= 'Z') || (*p >= 'a' && *p <= 'z'))
*q++ = *p;
/* If not, increment the write pointer only if the last
is not a newline with boundary check */
else if (q > s && *(q-1) != '\n')
*q++ = '\n';
}
*q = '\0';
}
如果您输入:
char var [] = " THIS.is a STRING\n"
"with two lines...";
结果是:
THIS
is
a
STRING
with
two
lines
/*with one newline at the end */
答案 1 :(得分:0)
如果我们在for循环开始之前查看基本上意味着SelectTagHelper
,请设置SelectListDescriptor
和<select asp-descriptor="@ViewBag.CountryDescriptor"><option value="">-- Choose country</option<</select>
。在C语言中,这意味着p,q和s最初被设置为等于相同的字符串(或者更具体地说,指向相同的地址)
答案 2 :(得分:0)
使用索引而不是指针的版本:
void f1(char *buf) {
size_t src, dst;
for (src=dst=0; buf[src]; src++) {
if ((buf[src] >= 'A' && buf[src] <= 'Z') || (buf[src] >= 'a' && buf[src] <= 'z'))
buf[dst++] = buf[src];
else if (dst && buf[dst-1] != '\n')
buf[dst++] = '\n';
}
*q = '\0';
}
Kernighan-style :
void f1(char *buf) {
size_t src, dst;
for (src=dst=0; buf[dst] = buf[src]; src++) {
if (buf[src] >= 'A' && buf[src] <= 'Z' || buf[src] >= 'a' && buf[src] <= 'z')
{ dst++; continue; }
if (dst && buf[dst-1] != '\n')
{ buf[dst++] = '\n'; }
}
}
注意: Kernighan风格的有一个很好的属性:
for (src=dst=0; buf[dst] = buf[src]; src++) {...}
保证在循环结束后将'\ 0'写入目标。所以,没有可能忘记它。 (除了突破循环时,这里没有这样做)
(当然真正的 Kernighan风格会使用指针和单字母变量; - )