Chapter 1, 2 Answer

练习1-10

制表符替换为\t,回退符替换为\b,斜杠替换为\\。

Chapter 1, 2 Answer

难点是怎么输入回退符。

Chapter 1, 2 Answer

getchar没办法从输入流中获取回退符。有人说用getch代替getchar,我试了,但是失败了,换了好几个头文件都报错。

Chapter 1, 2 Answer

我采取的方法是程序从文件中读取数据,Linux Ctrl-V + Ctrl-H,window Ctrl-Q + Ctrl-H生成回退符。

练习1-12 

每行一个单词打印输出。

标准答案在1.5.4代码基础上加了一些逻辑。我没看明白。

我采用的方法是,源码库遇到空白符时先判断上一个字符是否是换行符,如果不是就换行,如果是,说明已经做过换行操作了,这就需要保存上一个字符。碰到非空白符直接输出。

1.5.4统计单词的代码值得好好看。

1 2 3 4 5 6 7 while((c=getchar()) != EOF) { if(c ==  || c == \t || c == \n) state = OUT; else if(state == OUT)  //inside a word state = IN; }

练习2-3 十六进制转换为十进制

参考书中有atoi 代码。atoi曾是百度笔试题。

对于非法输入如何处理?返回一个整数?还是抛出一个异常?异常如何捕捉?

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 int htoi(char s[]) { //begin with 0x or 0X, a~f or A~F are acceptable int i = 0, value = 0; //s[0] = 0, s[1] = x || X for(i = 2; (s[i] >= 0 && s[i] <= 9) || (s[i] >= a && s[i] <= z) || (s[i] >= A && s[i] <= Z); ++i) { value = value * 16; if(s[i] >= 0 && s[i] <= 9) value += s[i] - 0; else if((s[i] >= a && s[i] <= z) || (s[i] >= A && s[i] <= Z)) { switch(s[i]) { case a: case A: value += 10; break; case b: case B: value += 11; break; case c: case C: value += 12; break; case d: case D: value += 13; break; case e: case E: value += 14; break; case f: case F: value += 15; break; } } } return value; }

练习2-4 将字符串 s1 中任何与字符串 s2 中字符匹配的字符都删除。

参考书中2.8代码squeeze。这道题是11年华为给我的源码下载笔试题。

1 2 3 4 5 6 7 8 9 void squeeze(char s[], int c) { int i, j; for(i = j = 0; s[i] != \0; i++) if(s[i] != c) s[j++] = s[i]; s[j] = \0; }

注意代码,匹配到了字符后,不是说把后面的字符往前移动。而是用一个索引 i 记录下一个不匹配字符 c 的位置,另一个索引 j 记录匹配 c 的位置,再用 i 位置的值覆盖 j 位置的值。如果没有匹配到字符 c,顶多是多做一次赋值。但是避免了数据的大量移动。

模仿这段代码,香港云服务器每次从s2中取出一个字符 c

1 2 3 4 5 6 7 8 9 10 11 12 13 void squeeze(char s1[], char s2[]) { int i, j, k; for(j = 0; s2[j] != \0; ++j) { for(i = k = 0; s1[i] != \0; ++i) if(s1[i] != s2[j]) s1[k++] = s1[i]; s1[k] = \0; } }

待续

滇ICP备2023000592号-31