在 C 语言中,”” 所给出的字符串字面量都将是常量,也就是说它会放在只读的内存空间中。 char *s = "a string"; 的作用,是将这段只读内存空间的指针赋给 s。因此你不能重新对 s 中的字符进行修改。 而 char s[] = "a string"; 是分配一段可读写的内存空间,并将其中的值初始化为该字符串。
在 C 中,字符串是以 ‘\0’ 结尾的。因此我们只需要让我们所需要的字符串部分的后一位为 ‘\0’,即可得到字符串的这一局部。因此想要将字符串按照 ‘;’ 割成两段,非常简单:
1 2 3 4 5 6 7
char *semi = strchr(s, ';'); // find position of semicolon if (semi) { // strchr() returns NULL if there's no semicolon *semi = '\0'; process(s); process(semi + 1); // what's after semicolon is another part } else process(s);
for (int i = 0; i < 16; i++) { if (!strcmp(s, *(reserved + i))) { returntrue; // is a reserved } } returnfalse; // is not
运算符同理
其实还有一个偷懒的写法:
1 2 3 4 5
char *operators = " + - * / < > = == >= <= != "; // why there is space? char *tmp = malloc(4096); sprintf(tmp, " %s ", s); // add space in the front and rear of s if (strstr(operators, tmp)) returntrue; // !! returnfalse;
保留字是同理。
变量
对于开头,检查是否是字母或下划线;对于后续,检测是否是字母、数字或下划线。
活用 isalpha(), isdigit()…
1 2 3 4 5
if (!(isalpha(*s) || *s == '_')) returnfalse; for (s++; *s != 0; s++) { if (!(isalpha(*s) || isdigit(*s) || s == '_')) returnfalse; } returntrue;
intmain() { int T; scanf("%d", &T); char *a = malloc(1001), *b = malloc(1001); while (T--) { scanf("%s%s", a, b); int la = strlen(a); int lb = strlen(b); for (int i = (la > lb) ? la - lb : 0; i <= la; i++) { // 为什么是 "<=" ? if (strstr(b, a + i) == b) { printf("%s%s\n", a, b + la - i); break; } } } return0; }
思考:为什么这里是 “<=”
思考:strstr(s, "") 的结果
C-参数传递 (parse.c)
Saki 放上去的参考代码里,有一份我的原实现。那是纯纯的超纲写法。 不需要 getopt()。那是 GNUC 的玩意。 也不需要 dup2(),这纯纯的 Linux 系统调用。
思路是,从前往后扫就完事了。
有的同学发现,option requires an argument 只会在最后出现,于是先去看最后一个参数。