彻底理解'\r'和'\n'

\r return的第一个字母,回到当前行的最左边。 可参考如下程序: #include<stdio.h> int main() { printf("helloworld\n"); printf("helloworld1\r"); getchar(); return 0; } 看截图可知: 光标回到了第一行 \n newline的第一个字母,向下移动一行,并不移动左右 参考如下的程序: #include<stdio.h> int main() { printf("helloworld\r"); printf("world2\n"); //你会发现,由于第一个print后,跳到最左边,第二个print中得“world2”将“hellow”覆盖了! getchar(); return 0; } 看截图如下: 会发现,由于第一个print后,跳到最左边,第二个print中得“world2”将“hellow”覆盖了! 而且,光标确实换行了! 此时,\n表示回车+换行return:回到行首,newline:切换了一行 以上均在centos环境下测试 ======== 以下是在mac环境下测试 在mac下做了一个小测试,得到的结果与centos下的一致,这让我有点怀疑下面的观点: Linux中\n表示回车+换行(上面已验证) Windows中\r\n表示回车+换行(win下可直接使用\n来匹配换行符,但是\r\n与\n\r是有明显区别的) Mac中\r表示回车+换行(我的结果是与linux下一样) 历史及其它 Unix 系统里,每行结尾只有“<换行>”,即“\n”;Windows系统里面,每行结尾是“<回车><换行>”,即“ \r\n”; Mac系统里,每行结尾是“<回车>”。一个直接后果是,Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行; Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。 在计算机还没有出现之 前,有一种叫做电传打字机(Teletype Model 33,Linux/Unix下的tty概念也来自于此)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正 好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。 于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车(return)”,告诉打字机把打印头定位在左边界;另一个叫做“换行(newline)”,告诉打字机把纸向下移一行。这就是“换行”和“回车”的来历 '\r'是回车,'\n'是换行,前者使光标到行首,后者使光标下移一格,通常敲一个回车键,即是回车,又是换行(\r\n)。Unix中每行结尾只有“<换行>”,即“\n”;Windows中每行结尾是“<换行><回车>”,即“\n\r”;Mac中每行结尾是“<回车>”。 摘抄 \n LF或ASCII中的0x0A(10) \r CR或ASCII中的0x0D(13) \n 软回车 \r 软空格 the end.... …

docker

是什么 Docker的核心底层技术是LXC(Linux Container),Docker在其上面加了薄薄的一层,添加了许多有用的功能。 它与lxc的区别在于: Docker提供了一种可移植的配置标准化机制,允许你一致性地在不同的机器上运行同一个Container;而LXC本身可能因为不同机器的不同配置而无法方便地移植运行; Docker以App为中心,为应用的部署做了很多优化,而LXC的帮助脚本主要是聚焦于如何机器启动地更快和耗更少的内存; Docker为App提供了一种自动化构建机制(Dockerfile),包括打包,基础设施依赖管理和安装等等; Docker提供了一种类似git的Container版本化的机制,允许你对你创建过的容器进行版本管理,依靠这种机制,你还可以下载别人创建的Container,甚至像git那样进行合并; Docker Container是可重用的,依赖于版本化机制,你很容易重用别人的Container(叫Image),作为基础版本进行扩展; Docker Container是可共享的,有点类似github一样,Docker有自己的INDEX,你可以创建自己的Docker用户并上传和下载Docker Image; Docker提供了很多的工具链,形成了一个生态系统;这些工具的目标是自动化、个性化和集成化,包括对PAAS平台的支持等; Container & Images Docker使用了一种叫AUFS的文件系统,这种文件系统可以让你一层一层地叠加修改你的文件,最底下的文件系统是只读的,如果需要修改文件,AUFS会增加一个可写的层(Layer),这样有很多好处,例如不同的Container可以共享底层的只读文件系统(同一个Kernel),使得你可以跑N多个Container而不至于你的硬盘被挤爆了!这个只读的层就是Image!而如你所看到的,一个可写的层就是Container。 区别 区别仅仅是一个是只读的层,一个是可写的层,你可以使用docker commit 命令,将你的Container变成一个Image,也就是提交你所运行的Container的修改内容,变成一个新的只读的Image,这非常类似于git commit命令 上下层的关系 Container 进入: docker attach NAME docker ps -a 查看name Dockerfile 在基础的Image(base)为不同的开发环境配置 示例: FROM ubuntu:14.10 RUN apt-get update RUN apt-get install -y ruby ruby-dev gem RUN gem install bundler 构建: docker build --rm -t dev:base . -t 选项构建的base image的tag Dockerfile的每一行指令都会创建一个临时的Container,也就是docker的一层 运行: docker run -i -t --name ruby dev:base irb 这里我们使用dev:base这个Image运行了一个irb解释器,在构建完base之后,可以依样画葫芦构建rails环境,很简单,只需要FROM dev:base,然后RUN安装rails组件就可以了 指定Image入口 1、示例: docker run -i -t --name REPOSITORY REPOSITORY:TAG /bin/bash example//docker run -i -t --name shell dev:base /bin/bash 2、运行服务(修改dockerfile): FROM ubuntu:14.10 RUN apt-get install -y mysql...…

strcpy理解

实现 废话不多说,先上实现的代码~ char * strcpy(char *to, const char *from) { assert(to != NULL && from != NULL) char *p = to; while((*p++ == *from++) != '\0') ; return to; } 说明 源字符串from用const修饰,防止被修改 空指针检查,保证代码的健壮性 返回目标地址 返回char *是因为,返回to的原始值使函数能够支持链式表达式,如:int l=strlen(strcpy(strA,strB)); to from 内存重叠处理 比如: char s[10]="nihao"; strcpy(s, s+1); //应返回ihao //strcpy(s+1, s); //应返回nnihao,但实际会报错,`因为to与from重叠了,把'\0'覆盖了` 所谓重叠,就是from未处理的部分已经被to给覆盖了,只有一种情况:from<=to<=from+strlen(from) 解决 实现memcpy函数,检查内存再做拷贝. #include<stdio.h> #include<string.h> #include<assert.h> char *strcpy(char *to, const char *from){ assert(to != NULL && from != NULL); char *p = to; memcpy(to,from,strlen(from)+1); return p; } char *memcpy(char *to, char *from, int count) { assert(to != NULL && from != NULL); char *res = to; if(to >= from && to...…

this post is featured

重学git

基础 撤销 修改最后一次提交 git commit --amend 此操作可以修改上一次commit的内容 取消暂存的文件 git reset HEAD filename 任何已经提交到 Git 的都可以被恢复。即便在已经删除的分支中的提交,或者用 --amend 重新改写的提交,都可以被恢复 取消当前修改 git checkout -- file 这个命令有点危险,修改全没了,不要轻易用 远程 抓取 git fetch origin 会抓取从你上次克隆以来别人上传到此远程仓库中的所有更新(或是上次 fetch 以来别人提交的更新)。fetch 命令只是将远端的数据拉到本地仓库,并不自动合并到当前工作分支。 git remote show origin //查看远程分支以及详细情况 分支 分支其实就是从某个提交对象往回看的历史 可以想象成一个逻辑框图或者树结构…… git checkout master它把 HEAD 指针移回到 master 分支,并把工作目录中的文件换成了 master 分支所指向的快照内容。 新建一个分支就是向一个文件写入 41 个字节(外加一个换行符) 合并 如果顺着一个分支走下去可以到达另一个分支的话,那么 Git 在合并两者时,只会简单地把指针右移,因为这种单线的历史分支不存在任何需要解决的分歧,所以这种合并过程可以称为快进(Fast forward) 当你在使用分支及合并的时候,一切都是在你自己的 Git 仓库中进行的 — 完全不涉及与服务器的交互 远程分支 远程分支就像是书签,提醒着你上次连接远程仓库时上面各分支的位置 在 fetch 操作下载好新的远程分支之后,你仍然无法在本地编辑该远程仓库中的分支,拥有的只是一个无法移动的指针而已。 接下来需要用: git checkout -b local_branch origin/remote_branch git merge origin/remote_branch 或者合并到当前分支 删除远程分支 git push origin :remote_name 这个`冒号`那可是相当的重要啊 rebase git checkout branch git rebase master 它的原理是回到两个分支最近的共同祖先,根据当前分支(也就是要进行衍合的分支)后续的历次提交对象,生成一系列文件补丁,然后以基底分支(也就是主干分支master)最后一个提交对象为新的出发点,逐个应用之前准备好的补丁文件,最后会生成一个新的合并提交对象,从而改写branch的提交历史,使它成为master分支的直接下游 一旦分支中的提交对象发布到公共仓库,就千万不要对该分支进行衍合操作。 提交 不要在更新中提交多余的白字符,可以用git diff --check检查 每次提交限定于完成一次逻辑功能,适当分解为多次小更新 在推送数据之前,先确认下要并进来的数据究竟是什么,于是运行 git log...…

FUCK_GFW

ssh配置 当然,首先需要自己购买ssh或者拥有ssh,免费得也行,但是不够稳定。 装x法 mac下一条命令搞定: ssh -qTfnN -D 7070 name@ip 然后输入密码,就开启了通道,同时设置socks,127.0.0.1:7070 安静的办法 安装 SSH Proxy for mac,按照要求填写地址即可~ 开始连接可能连接不上,可以先试试上面的命令,设置know_hosts等 chrome 可以用SwitchOmega Options, 里面的goagent设置可以不管,自己自行添加一条: protocol : socks5 server : 127.0.0.1 port : 7070 然后切换为ssh即可……一直开着,也可以设置黑名单和白名单,哪些走代理,哪些不走代理 firefox 不用装插件了,简单点。 首选项-->高级-->网络-->设置-->手动代理-->socks主机-->127.0.0.1:7070 然后输入: about:config 搜索:network.proxy.socks_remote_dns 双击,设置为:true即可 全局设置 mac-->网络-->socks5设置…… VPN设置 这里的VPN必须推荐一下,虽然我自己花钱买了…… 网站本身就需要翻墙,所以呢……还是需要先翻墙再去找…… 短时间用还是可以找到很多的…… 极路由+VPN 这个设置也不错,方便快捷,还带自动切换功能,国内走国内,国外走代理,很赞…… 但是极路由重启一次很费时间…… 感觉翻墙就是在跟国家战斗……vpn服务也不知道能用多久……但愿有一天…… …