1.C语言strtok函数分割含有空值的源码字符串
2.斯坦福大学Pintos Project1、2 指南+总结
3.C语言中从键盘输入一个英文句子,源码输出所有首字母大写的单词.
C语言strtok函数分割含有空值的字符串
如果你使用 strtok 函数, 那就没办法了.因为strtok函数里面采用了 strspn()这个函数.
而 strspn 每次都将指针移动到第一个非 "|" 中的字符的位置.
附上源码:
#include <string.h>static char *olds;
#undef strtok
char * strtok (char *s,const char *delim)
{
char *token;
if (s == NULL)
s = olds;
/* Scan leading delimiters. */
s += strspn (s, delim); //将指针移到第一个非delim中的字符的位置
if (*s == '\0')
{
olds = s;
return NULL;
}
/* Find the end of the token. */
token = s;
s = strpbrk (token, delim);// 获取到delimz中字符在字符串s中第一次出现的位置
if (s == NULL)
/* This token finishes the string. */
olds = __rawmemchr (token, '\0');
else
{
/* Terminate the token and make OLDS point past it. */
*s = '\0';
olds = s + 1;
}
return token;
}
斯坦福大学Pintos Project1、2 指南+总结
前言:斯坦福大学的源码Pintos Project是OS实践课程的作业之一,尽管课程只有1个学分,源码但其难度和投入时间之多,源码远超许多4学分的源码OS共振源码大课程,可谓是源码上个学期的噩梦。在项目实施过程中,源码我参考了大量的源码在线资料和源码,遇到了各种难题。源码如今课程已结束,源码虽然最终成绩优异,源码但以斯坦福大学的源码标准衡量,我自认还有提升空间。源码源码众创趁着寒假的源码空闲,回顾整个项目,记录心得和遇到的困难,希望能为后来者提供帮助。
一、环境安装
环境安装是开始项目的关键步骤,对于不熟悉Linux环境的人来说,这一部分尤为困难。网上教程多,但细节上的遗漏可能导致各种问题。推荐使用以下两个教程进行环境配置,同时注意用户名、路径的ma源码使用一致性,避免漏步。
在安装Bochs之前,确保安装或更新编译所需的库(如build-essential、libx-dev)。配置环境变量至关重要,避免直接照搬教程中的用户名和路径,确保与自己的环境匹配。
执行关键测试命令,如在threads目录下的build中输入`pintos --run alarm-multiple`,查看是否能够顺利运行。若能通过`make check`测试,表示环境安装成功。推荐在pintos/src/threads目录下执行`make check`,全球源码托管以进一步验证环境的正确性。
二、Pintos项目上手
项目启动时,查阅斯坦福大学官网提供的官方指南,解决绝大多数问题。JHU的Pintos Project Guide也是值得参考的资源。对于Project 1(threads),质量参差不齐,精选文章如CSDN博客提供了实用的实验报告。Project 2(userprog)讲解资料较少,建议参考GitHub上他人的代码,理解其设计意图。
当直接从GitHub下载文件夹覆盖原有Pintos文件夹时,公式程序源码可能会遇到环境变量不匹配的问题。正确的做法是将代码的源文件(.c)逐一覆盖至对应的目录中,进行备份后操作,避免整个文件夹覆盖导致的潜在问题。
三、项目准备与知识预习
项目包含多个文件夹,每个文件夹对应特定的功能。Project 1主要关注threads和timer下的.c文件,Project 2则集中在userprog下的.c文件。两个项目是独立的,完成第一个项目并不影响第二个项目的测试结果。
为了高效定位函数位置,建立代码索引是必要的。在Ubuntu环境下,利用Visual Studio导入.pintos下的.h和.c文件,生成项目解决方案,可以快速查找函数。gdb在分析Pintos代码时至关重要,学习使用gdb可以提高调试效率。
四、Project 1:线程讨论
Project 1探讨了时钟、线程状态、优先级调度、信号量等主题。通过GDB调试,可以总结Pintos系统运行流程。重点在于解决alarm、优先级调度和抢占中的问题。对于alarm测试,通过“挂起”暂时不用的线程,提高系统吞吐率。在优先级调度中,使用堆(heap)或O(n)扫描算法来选择优先级最高的线程。
优先级捐赠和多级反馈队列(mlfqs)是Project 1的核心,难度较高。优先级捐赠解决了优先级翻转问题,需要和信号量、条件变量、锁等数据结构交互。mlfqs的实现主要根据官方指南提示,涉及浮点运算后的调度公式计算。
五、Project 2:用户程序
Project 2相对Project 1较为容易,主要关注参数分离和系统调用。参数分离需要对栈机制有深入理解,遵循用户空间从高向低生长的规则进行参数压栈。实现参数分离时,需要对thread.h进行修改,实现树形线程结构。系统调用的实现遵循“上锁、异常处理、调函数、释放锁”的原则,特别注意对于stdin和stdout的特殊情况处理。
通过gdb调试,观察process_wait函数的实现,理解如何等待子线程结束。实现参数分离后,使用strtok_r函数将命令参数按照空格分离。在setup_stack函数中添加参数传递,确保参数按照栈从高到低的顺序正确压入。
六、总结
本文旨在提供一个上手Pintos项目的指导方向,分享个人在项目过程中遇到的困难与解决方案。希望这些经验能为后来者提供帮助,Pintos项目不仅加深了对OS概念的理解,还提供了将理论知识转化为实践应用的宝贵机会。如果你对OS感兴趣,Pintos是一个理想的入门项目,值得一试。
C语言中从键盘输入一个英文句子,输出所有首字母大写的单词.
#include <stdio.h>
int main(void)
{
char str[];
char *cp;
printf("Input sentence:");
gets(str);
for(cp = str; *cp != '\0'; cp++)
{
/* 判断单词首字母是否是大写 */
if((cp == str || *(cp -1) == ' ') && *cp >= 'A' && *cp <= 'Z')
{
while((*cp >= 'A' && *cp <= 'Z') || (*cp >= 'a' && *cp <= 'z'))
{
printf("%c", *cp);
cp++;
}
printf("\n");
}
}
return 0;
}