void increase() { //增加学生信息 int m, flag, i = n, j;//n是一开始定义的n=0赋值给i printf("请输入待添加的学生人数:\n"); scanf("%d", &m);//输入整数并赋值给m if (m > 0) {//可输入人数 do {//先执行后判断 flag = 1; while (flag != 0) {//循环一直到flag不等于0 flag = 0; printf("请输入第%d位学生的学号:\n", i + 1);//控制i>j 并且能够进行下一次的循环 getchar(); gets(stu[i].num);//学生数组序号 for (j = 0; j < i; j++) { //i就是n是学生的总数控制j小于50,j不断增加i为人数i与j相等人数重复 if (strcmp(stu[i].num, stu[j].num) == 0) { //用于比较两个字符串根据比较结果两个字符串相等为0 printf("该学号已存在,请重新输入!\n"); flag = 1;//flag等于1满足初始跳出循环 break; } } } printf("请输入第%d位学生姓名:\n", i + 1); gets(stu[i].name); printf("请输入第%d位学生性别:\n", i + 1); gets(stu[i].sex); printf("请输入第%d位学生年龄:\n", i + 1); scanf("%d", &stu[i].age); printf("请输入第%d位学生籍贯:\n", i + 1); scanf("%s", &stu[i].baera); printf("请输入第%d位学生系别:\n", i + 1); scanf("%s", &stu[i].department); printf("请输入第%d位学生专业:\n", i + 1); scanf("%s", &stu[i].major); printf("请输入第%d位学生班级:\n", i + 1); scanf("%s", stu[i].Class); i++; } w
时间: 2023-06-13 16:08:41 浏览: 64
hile (--m > 0); //如果还有剩余的待添加学生,继续执行循环 n = i; //将添加学生后的总人数赋值给n,便于后续操作。} else {//不可输入人数 printf("输入有误,请重新输入!\n"); }}
这是一个用于增加学生信息的函数,通过输入待添加的学生人数,然后逐一输入学生信息,包括学号、姓名、性别、年龄、籍贯、系别、专业、班级等信息。在输入学号时,通过对已有学号进行比较,确保输入的学号唯一。最后将添加学生后的总人数赋值给n,以便于后续操作。
相关问题
c/c++使用ffmpeg库推流本地文件,并使用av_seek_frame实现跳转功能的完整代码
这里是使用ffmpeg库推流本地文件,并使用av_seek_frame实现跳转功能的完整C++代码:
```cpp
#include <iostream>
#include <string>
extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/mathematics.h>
}
#define STREAM_DURATION 10.0
#define STREAM_FRAME_RATE 25 /* 25 images/s */
#define STREAM_PIX_FMT AV_PIX_FMT_YUV420P /* default pix_fmt */
/* add a video output stream */
static AVStream *add_video_stream(AVFormatContext *oc, enum AVCodecID codec_id) {
AVCodecContext *c;
AVStream *st;
st = avformat_new_stream(oc, NULL);
if (!st) {
std::cerr << "Could not allocate stream" << std::endl;
exit(1);
}
c = st->codec;
c->codec_id = codec_id;
c->codec_type = AVMEDIA_TYPE_VIDEO;
/* put sample parameters */
c->bit_rate = 400000;
/* resolution must be a multiple of two */
c->width = 352;
c->height = 288;
/* frames per second */
c->time_base = (AVRational) { 1, STREAM_FRAME_RATE };
st->time_base = c->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
/* some formats want stream headers to be separate */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
return st;
}
/* open the output file, and allocate the format context */
static void open_output_file(const std::string &filename, AVFormatContext **oc, AVOutputFormat *fmt) {
int ret;
/* allocate the output media context */
avformat_alloc_output_context2(oc, fmt, NULL, filename.c_str());
if (!(*oc)) {
std::cerr << "Could not create output context" << std::endl;
exit(1);
}
/* add the video stream using the default format codecs and initialize the codecs */
add_video_stream(*oc, (*oc)->oformat->video_codec);
/* open the output file, if needed */
if (!((*oc)->oformat->flags & AVFMT_NOFILE)) {
ret = avio_open(&(*oc)->pb, filename.c_str(), AVIO_FLAG_WRITE);
if (ret < 0) {
std::cerr << "Could not open output file" << std::endl;
exit(1);
}
}
/* write the stream header, if any */
ret = avformat_write_header(*oc, NULL);
if (ret < 0) {
std::cerr << "Error occurred when opening output file" << std::endl;
exit(1);
}
}
/* close the output file and free the format context */
static void close_output_file(AVFormatContext *oc) {
/* write the trailer, if any */
av_write_trailer(oc);
/* close the output file */
if (!(oc->oformat->flags & AVFMT_NOFILE))
avio_closep(&oc->pb);
/* free the stream */
avformat_free_context(oc);
}
/* seek to a specific frame in a video file */
static void seek_to_frame(AVFormatContext *fmt_ctx, int stream_index, int64_t timestamp) {
int ret;
/* seek to the timestamp */
ret = av_seek_frame(fmt_ctx, stream_index, timestamp, AVSEEK_FLAG_BACKWARD);
if (ret < 0) {
std::cerr << "Error seeking to timestamp " << timestamp << std::endl;
exit(1);
}
/* flush the codec buffers */
avcodec_flush_buffers(fmt_ctx->streams[stream_index]->codec);
}
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << " <output file>" << std::endl;
return 1;
}
AVOutputFormat *fmt;
AVFormatContext *oc;
AVPacket pkt;
int frame_count, i;
double t, tincr;
int64_t next_pts;
/* register all codecs and formats */
av_register_all();
/* allocate the output media context */
fmt = av_guess_format(NULL, argv[1], NULL);
if (!fmt) {
std::cerr << "Could not determine output format" << std::endl;
return 1;
}
open_output_file(argv[1], &oc, fmt);
/* initialize the frame counter */
frame_count = 0;
/* initialize the timestamp increment */
tincr = 2 * M_PI * STREAM_FRAME_RATE / STREAM_DURATION;
next_pts = 0;
/* main loop */
for (i = 0; i < 100; i++) {
AVStream *st;
AVCodecContext *c;
AVRational time_base;
AVFrame *frame;
int got_packet = 0;
int ret;
/* get the video stream */
st = oc->streams[0];
c = st->codec;
time_base = st->time_base;
/* allocate a new frame */
frame = av_frame_alloc();
if (!frame) {
std::cerr << "Could not allocate video frame" << std::endl;
exit(1);
}
/* generate synthetic video */
frame->pts = av_rescale_q(frame_count, time_base, c->time_base);
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
std::cerr << "Could not allocate frame data" << std::endl;
exit(1);
}
for (int y = 0; y < c->height; y++)
for (int x = 0; x < c->width; x++)
frame->data[0][y * frame->linesize[0] + x] = x + y + frame_count * 3;
for (int y = 0; y < c->height / 2; y++) {
for (int x = 0; x < c->width / 2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + frame_count * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + frame_count * 5;
}
}
/* encode the frame */
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
std::cerr << "Error encoding video frame" << std::endl;
exit(1);
}
/* if the frame was encoded, write it to the file */
if (got_packet) {
pkt.stream_index = st->index;
av_packet_rescale_ts(&pkt, time_base, st->time_base);
ret = av_interleaved_write_frame(oc, &pkt);
if (ret < 0) {
std::cerr << "Error while writing video frame" << std::endl;
exit(1);
}
}
/* increase the frame count */
frame_count++;
/* calculate the next presentation timestamp */
t = (double)frame_count / STREAM_FRAME_RATE;
next_pts += (int64_t)(tincr * 1000);
if (next_pts > (double)av_gettime()) {
av_usleep(next_pts - av_gettime());
}
/* free the frame */
av_frame_free(&frame);
}
/* seek to a specific frame */
seek_to_frame(oc, 0, 30);
/* continue encoding frames */
for (; i < 200; i++) {
AVStream *st;
AVCodecContext *c;
AVRational time_base;
AVFrame *frame;
int got_packet = 0;
int ret;
/* get the video stream */
st = oc->streams[0];
c = st->codec;
time_base = st->time_base;
/* allocate a new frame */
frame = av_frame_alloc();
if (!frame) {
std::cerr << "Could not allocate video frame" << std::endl;
exit(1);
}
/* generate synthetic video */
frame->pts = av_rescale_q(frame_count, time_base, c->time_base);
frame->format = c->pix_fmt;
frame->width = c->width;
frame->height = c->height;
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
std::cerr << "Could not allocate frame data" << std::endl;
exit(1);
}
for (int y = 0; y < c->height; y++)
for (int x = 0; x < c->width; x++)
frame->data[0][y * frame->linesize[0] + x] = x + y + frame_count * 3;
for (int y = 0; y < c->height / 2; y++) {
for (int x = 0; x < c->width / 2; x++) {
frame->data[1][y * frame->linesize[1] + x] = 128 + y + frame_count * 2;
frame->data[2][y * frame->linesize[2] + x] = 64 + x + frame_count * 5;
}
}
/* encode the frame */
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
std::cerr << "Error encoding video frame" << std::endl;
exit(1);
}
/* if the frame was encoded, write it to the file */
if (got_packet) {
pkt.stream_index = st->index;
av_packet_rescale_ts(&pkt, time_base, st->time_base);
ret = av_interleaved_write_frame(oc, &pkt);
if (ret < 0) {
std::cerr << "Error while writing video frame" << std::endl;
exit(1);
}
}
/* increase the frame count */
frame_count++;
/* calculate the next presentation timestamp */
t = (double)frame_count / STREAM_FRAME_RATE;
next_pts += (int64_t)(tincr * 1000);
if (next_pts > (double)av_gettime()) {
av_usleep(next_pts - av_gettime());
}
/* free the frame */
av_frame_free(&frame);
}
/* close the output file and free the format context */
close_output_file(oc);
return 0;
}
```
这个代码会生成一个10秒的视频,并在第30帧处进行跳转,继续生成另外10秒的视频。视频中的图像是随机生成的。你可以根据自己的需求进行修改。
优化这段代码//按键控制舵机 #include <msp430.h> #define CPU_F ((double)1000000) #define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))//重新定义延时函数 #define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0)) void TimeA0__PWM_Init(void) { P1SEL |= BIT3; //IO口复用 P1DIR |= BIT3; TA0CTL = TASSEL__SMCLK + MC_3; //SMCLK,增减模式,计数到CCR0处 TA0CCR0 = 10000 - 1; // PWM周期为20ms,对应时钟频率为1MHz TA0CCR2 = 250; //将占空比设置为50% (TACCR0 - TACCR2) / TACCR0 = (20000 - 10000) / 20000 = 0.5 TA0CCTL2 = OUTMOD_6; //选择比较模式,模式6:Toggle/set } void set_servo_angle(float angle) { if (angle < 0.0f) { angle = 0.0f; // 最小角度限制 //非常好,12个是90度 } // else if (angle > 360.0f) // { // angle = 359.0f; // 最大角度限制 // } unsigned int position = (angle / 360.0f) * (1250 - 250) + 250; TA0CCR2 = position; // 设置脉冲宽度,对应舵机位置 __delay_cycles(10000); // 延时等待舵机调整到目标位置 } int main(void) { WDTCTL = WDTPW | WDTHOLD; // stop watchdog timer TimeA0__PWM_Init(); P2DIR &= ~BIT1; // 设置P2.1为输入 P2REN |= BIT1; // 启用P2.1的上拉电阻 P2OUT |= BIT1; // 将P2.1的上拉电阻设置为上拉 unsigned int angle = 0; while(1) { set_servo_angle(angle); if ((P1IN & BIT1) == 0) // 检测按键是否按下 { angle += 10; // 每次按键增加10度 // if (angle > 360) // { // angle = 360; // 最大角度限制 // } set_servo_angle(angle); delay_ms(200); // 延时一段时间避免按键反弹 } } }
这段代码是用来按键控制舵机角度的。以下是对代码进行优化的一些建议:
1. 将硬编码的数值定义为常量,以提高代码的可读性。例如,将占空比50%的值定义为一个常量。
2. 使用位操作来设置和清除引脚状态。例如,使用`P1OUT |= BIT3`来设置P1.3引脚为高电平,使用`P1OUT &= ~BIT3`来清除P1.3引脚。
3. 考虑使用中断来检测按键状态,而不是在循环中轮询检测。这样可以减少CPU的负载,提高代码的效率。
4. 考虑使用定时器中断来实现舵机位置调整,而不是使用延时函数。这样可以避免在调整舵机位置时阻塞其他操作。
下面是优化后的代码示例:
```cpp
#include <msp430.h>
#define CPU_F ((double)1000000)
#define delay_us(x) __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#define delay_ms(x) __delay_cycles((long)(CPU_F*(double)x/1000.0))
#define PWM_PERIOD 10000
#define PWM_DUTY_CYCLE 5000
#define ANGLE_INCREMENT 10
#define DEBOUNCE_DELAY 200
volatile unsigned int angle = 0;
void TimeA0_PWM_Init(void)
{
P1SEL |= BIT3;
P1DIR |= BIT3;
TA0CTL = TASSEL__SMCLK + MC_3;
TA0CCR0 = PWM_PERIOD - 1;
TA0CCR2 = PWM_DUTY_CYCLE;
TA0CCTL2 = OUTMOD_6;
}
void set_servo_angle(unsigned int angle)
{
if (angle > 360)
{
angle = 360;
}
unsigned int position = (angle / 360.0f) * (1250 - 250) + 250;
TA0CCR2 = position;
delay_us(10000);
}
void init_button_interrupt()
{
P2DIR &= ~BIT1;
P2REN |= BIT1;
P2OUT |= BIT1;
P2IE |= BIT1; // Enable interrupt for P2.1
P2IES |= BIT1; // Set interrupt edge select to falling edge
P2IFG &= ~BIT1; // Clear P2.1 interrupt flag
}
#pragma vector=PORT2_VECTOR
__interrupt void Port_2(void)
{
if ((P2IFG & BIT1) != 0) // Check if P2.1 caused the interrupt
{
angle += ANGLE_INCREMENT; // Increase angle by increment value
set_servo_angle(angle);
delay_ms(DEBOUNCE_DELAY); // Delay to avoid button bounce
P2IFG &= ~BIT1; // Clear P2.1 interrupt flag
}
}
int main(void)
{
WDTCTL = WDTPW | WDTHOLD;
TimeA0_PWM_Init();
init_button_interrupt();
__enable_interrupt();
while (1)
{
// Do other operations here
}
}
```
这个优化后的代码将使用定时器中断来检测按键状态,并使用位操作来设置和清除引脚状态。舵机位置调整也改为使用定时器中断,以避免阻塞其他操作。