为什么在VS Code中使用fopen无法打开文件?

我使用VS Code运行以下代码,没有报错,也没有任何反应。VS Code配置的是gcc。
但同样的代码在Dev C++中运行就没有问题。
问题出在fopen这个地方,请问各位这是怎么回事?

#include <stdio.h>
#include <stdlib.h>

typedef struct huffman_node 
{
    int data;
    int lchild;
    int rchild;
    int parent;
}bnode;  //定义二叉链表结点结构

void SelectIJ(int k, bnode node[], int *i, int *j)
{

}

void HuffmanTree(int n, bnode node[],int w[])
{
}

void main()
{
    FILE *fp;
    int weight[26];

    int i,j;
    int ch;
    int n;

    bnode *node;
    unsigned long code;

    for(i=0; i<26; i++)
    {
        weight[i] = 0;
    }

    if( (fp = fopen("StrayBirds.txt","r")) == NULL ){
        printf("Failed");
        //return;
    }

    do {
        ch = fgetc(fp);

        if (!( ((ch>=97)&&(ch<=122)) ||
               ((ch>=65)&&(ch<=90 ))     )
           )
        {
            continue;
        }
        if( (ch>=97)&&(ch<=122) )
        {
            ch -= 32;
        }
        putchar(ch);
        weight[ch-65]++;
    } while(feof(fp)==0);

    printf("\n");

    n = 0;
    for(i=0; i<26; i++)
    {
        if(weight[i] > 0) 
        {
            n++;
            printf("%c  %d \n", i+65, weight[i]);
        }
    }

    node = (bnode *)malloc((2*26-1) * sizeof(bnode));

    //建立哈夫曼树
    //HuffmanTree(26, node, weight);

    //哈夫曼编码
    for (i=0; i<26; i++)
    {
        printf("Now processing %c -----", i+65);

        printf("\n");
    }

    free(node);
    fclose(fp);
    getchar();
}


图片说明
图片说明

1个回答

Csdn user default icon
上传中...
上传图片
插入图片
抄袭、复制答案,以达到刷声望分或其他目的的行为,在CSDN问答是严格禁止的,一经发现立刻封号。是时候展现真正的技术了!
其他相关推荐
fopen 频繁写文件问题,谢谢
recieve 线程收到消息后,转给另外一个线程B进行处理,B会打开一个文件, 并将消息内容写入文件,然后关闭文件。现在因为频繁写,出现了open file error问题。 2018/04/26 10:28:44.222 I ThreadB Process message: src= 5 2018/04/26 10:28:44.223 I ThreadB Process message: src= 0 2018/04/26 10:28:44.482 I ThreadB Process message: src= 1 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 2018/04/26 10:28:44.482 I ThreadB Process message: src= 2 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 2018/04/26 10:28:44.482 I ThreadB Process message: src= 3 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 从log可以看到从src 0和5发来的message,可以正确处理,并更新文件,但是从src 1/2/3发来的消息,会在同一时间发起fopen操作,然后报error,请问大牛,在同一个线程中,为什么会出现这种情况呢? code结构很老,没有看到用message queue或者同步的处理,基于这种现象,求解释。 谢谢
关于fopen频繁写文件的error原因分析及解决方案 (再次求助)
进程A中,在一个单独的线程里对收到的消息数据进行处理,并打开一个文件,写入数据,关闭文件。关闭文件后,执行CopyFile, 复制当前文件,生成一个新文件,再由另一个进程B对新生成的文件进行读取。 现在在fopen时,会频繁报错 open file error,但是具体的error原因,没有在code中打出来,目前也无法得知。 2018/04/26 10:28:44.222 I ThreadB Process message: src= 5 2018/04/26 10:28:44.223 I ThreadB Process message: src= 0 2018/04/26 10:28:44.482 I ThreadB Process message: src= 1 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 2018/04/26 10:28:44.482 I ThreadB Process message: src= 2 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 2018/04/26 10:28:44.482 I ThreadB Process message: src= 3 2018/04/26 10:28:44.482 E ThreadB Error Opening ** file: C:\writting.txt 从log中可以看到,起初的一段时间,是可以正常工作的,有三四个open error出现,基本在几个毫秒级别,然后又回复正常,然后会重复这种情况,间隔几秒,十几秒,或者几分钟会出现几个error,最后,会连续出现error,然后就无法恢复了。最后只有重启进程,删掉文件并重建。 对文件处理不是很了解,重开一贴顶上去,请大牛指教原因。 谢谢
为什么我这个程序运行到fopen语句就结束了?
``` int FileCodingWords(HuffmanCode HC[],CW *cw)//对文件进行编码 { FILE *file; int i,j; file=fopen("text.txt","r");//运行到这里就不行了 printf("1");//检测运行到哪里出错用的 if(file!=0) { word=fgetc(file); for(i=1;word!=cw->c[i]&&i<=cw->n;i++){ } if(word=cw->c[i]){ for (j=HC[i].start+1; j <=cw->n; j++) { printf ("%d", HC[i].code[j]); } } else{ printf("您创建的字符集中此字符的对应编码。\n即将停止编码。\n") ; return ERROR; } while(word!=EOF){ word=fgetc(file); for(i=1;word!=cw->c[i]&&i<=cw->n;i++){ } if(word=cw->c[i]){ for (j=HC[i].start+1; j <=cw->n; j++) { printf ("%d", HC[i].code[j]); } } else{ printf("您创建的字符集中此字符的对应编码。\n即将停止编码。\n") ; return ERROR; } } printf("\n") ; fclose(file); } if(file==0) { printf("文件打开失败,或是文件不存在。\n"); return ERROR; } return OK; } ``` 文件是存在的,和程序在一个目录下。 到fopen语句就返回异常值结束了: Process exited after 15.38 seconds with return value 3221225725 请按任意键继续. . .
关于c语言 fopen触发断点问题,求大神解惑
数据结构作业要构造huffman树并输出文件,但是过程遇到问题,困了好几天没能解决。 ![图片说明](https://img-ask.csdn.net/upload/201910/15/1571149416_706766.png)![图片说明](https://img-ask.csdn.net/upload/201910/15/1571149429_15842.png) 如图,我尝过许多方法,文件名字符串双斜杠试过,作为变量传入也试过,但是都会发生这样的情况。但是更让我难以理解的是偶尔会成功打开并且成功写入,这就让我不知道要从哪里找问题了。 部分代码如下,程序还未完成但是可以调试部分功能了 ``` #include<stdio.h> #include<stdlib.h> #include<string.h> #define ERROR 0 #define OK 1 typedef int status; typedef struct { unsigned int weight; unsigned parent, lchild, rchild; }HTNode, *HuffmanTree; typedef char **HuffmanCode; void Get_Info(int *n, char **charset, int **w) { printf("请输入字符集大小:"); scanf("%d", n); getchar(); int i, m = 2 * (*n) - 1; *charset = (char*)malloc((*n) * sizeof(char)); *w = (int*)malloc((*n) * sizeof(int)); for (i = 0; i < *n; i++) { printf("请输入第%d个字符及其权值(中间用空格隔开):", i + 1); scanf("%c", (*charset)+i); getchar(); scanf("%d", (*w)+i); getchar(); } } void Select(HuffmanTree HT, int m, int *s1, int *s2) { //s1.w<s2.w int i, temp, tag = 1; HuffmanTree p; for (i = 1, p = HT + 1; i <= m; p++, i++) { if (p->parent == 0 && tag == 1) { *s1 = i; tag++; } else if (p->parent == 0 && tag == 2) { //没加else,导致同时执行 *s2 = i; break; } } if (HT[*s1].weight > HT[*s2].weight) { temp = *s1; *s1 = *s2; *s2 = temp; } for (i = 1, p = HT + 1; i <= m; p++, i++) { if (p->weight < HT[*s1].weight && p->parent == 0) { *s2 = *s1; *s1 = i; } else if (p->weight < HT[*s2].weight && p->weight != HT[*s1].weight && p->parent == 0) *s2 = i; } } void CreateHT(HuffmanTree *HT, int n, char *charset, int* w, char treefilename[]) { int i, m; int s1, s2; FILE *Huffman; HuffmanTree p; //初始化 m = 2 * n - 1; (*HT) = (HuffmanTree)malloc((m + 1) * sizeof(HuffmanCode)); for (p = *HT + 1, i = 1; i <= m; i++, p++) { p->weight = 0; p->parent = 0; p->lchild = 0; p->rchild = 0; } for (p = *HT + 1, i = 1; i <= n; i++, p++, w++) p->weight = *w; //建Huffman树 for (i = n + 1; i <= m; i++) { //调试分析1:写成i = 1,发生错误。 Select(*HT, i - 1, &s1, &s2); /*调试分析3:刚开始设置为i,导致select函数多找一位,Huffman树生成错误,应为i-1*/ (*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight; (*HT)[i].lchild = s1; (*HT)[i].rchild = s2; (*HT)[s1].parent = i; (*HT)[s2].parent = i; } //输出到Huffman文件 Huffman = fopen(treefilename, "w"); fprintf(Huffman, "W P L R\n"); for (i = 1; i <= m; i++) fprintf(Huffman, "%d %d %d %d\n", (*HT)[i].weight, (*HT)[i].parent, (*HT)[i].lchild, (*HT)[i].rchild); fclose(Huffman); } void Coding(HuffmanTree HT,HuffmanCode *HC, int n) { int start; unsigned int c, f; char *cd; (*HC) = (HuffmanCode)malloc((n + 1) * sizeof(char*)); cd = (char*)malloc(n * sizeof(char)); cd[n - 1] = '\0'; for (int i = 1; i <= n; ++i) { start = n - 1; for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) { if (HT[f].lchild == c) cd[--start] = '0'; else cd[--start] = '1'; } (*HC)[i] = (char*)malloc((n - start) * sizeof(char)); strcpy((*HC)[i], &cd[start]); } free(cd); } status CodeFile(HuffmanCode HC, char *textfilename, char *codefilename, char *charset) { FILE *CodeFile, *TextFile; char text[1000],code[5000]; int length = 0, i, j; TextFile = fopen(textfilename, "r"); if (TextFile == NULL) { printf("正文文件不存在。请重试\n"); return ERROR; } while ((text[length] = fgetc(TextFile)) != EOF) length++; fclose(TextFile); CodeFile = fopen(codefilename, "w"); for (i = 0; i < length; i++) { j = 0; while (charset[j] != text[i]) j++; j++; fputs(HC[j], CodeFile); } fclose(CodeFile); return OK; } status Get_HT(HuffmanTree *HT, char *treefilename, int *n) { int status; char garbage[100]; FILE *Huffman; HuffmanTree p ,q; (*n) = 0; p = (HuffmanTree)malloc(sizeof(HuffmanCode)*2); Huffman = fopen(treefilename, "r"); if (Huffman == NULL) { printf("文件不存在!"); status = ERROR; } else { (*HT) = (HuffmanTree)malloc(sizeof(HTNode)); for (int i = 0; i < 100;i++) { fgets(garbage, 37, Huffman); puts(garbage); printf("*%d*", i); } while ((fscanf(Huffman ,"%d %d %d %d", &(p[*n+1].weight), &(p[*n + 1].parent), &(p[*n + 1].lchild), &(p[*n + 1].rchild)))!=EOF) {//eof标识文件输入结束 (*n)++; printf("%d %d %d %d\n", p[*n + 1].weight, p[*n + 1].parent, p[*n + 1].lchild, p[*n + 1].rchild); p = (HuffmanTree)realloc(p, sizeof(HuffmanCode)*(*n + 2)); } (*HT) = p; status = OK; } return status; } int main() { char *charset, treefilename[40], codefilename[40], textfilename[40], c; int i, n, *w, status; int op; HuffmanTree HT = NULL; HuffmanCode HC = NULL; printf("姓名:陈志涛 学号:2018051234 时间:2019/10/10\n"); printf("=======================Huffman编码=======================\n"); printf("操作说明:请输入操作序号,并根据提示输入\n"); printf("菜 单:1、构建Huffman树\n"); printf(" 2、编码\n"); printf(" 3、译码\n"); printf(" 4、退出程序\n"); do { printf("\n>>>请输入操作序号:"); scanf("%d", &op); getchar(); switch (op){ case 1: Get_Info(&n, &charset, &w); printf("请输入Huffman树的文件存储地址:"); gets_s(treefilename); CreateHT(&HT, n, charset, w, treefilename); printf("Huffman树构建并保存成功。\n"); break; case 2: if (HT == NULL) { printf("当前未构建Huffman树,是否从文件中读取(Y/N)?"); scanf("%c", &c); getchar(); if (c == 'Y' || c == 'y') { printf("请输入Huffman文件存储地址:"); gets_s(treefilename); status = Get_HT(&HT, treefilename, &n); if (status == ERROR) { printf("获取Huffman树失败,请检查。"); break; } } else break; } Coding(HT, &HC, n); printf("请输入正文文件的存储地址:"); gets_s(textfilename); printf("请输入Huffman编码的目标存储地址:"); gets_s(codefilename); CodeFile(HC, textfilename, codefilename, charset); break; } printf("\n"); } while (1); system("pause"); return 0; } ``` 希望有好心人帮帮忙解惑
修改程序:信源编解码(c语言)
修改程序:问题1。源文件source文本空间太长汉字太多无法运行2,未按频度要求排序 问题描述: 信源编解码是通信系统的重要组成部分。本实验旨在通过程序设计实现基于哈夫曼编码的信源编解码算法。程序具备以下功能: 对于给定的源文档 SourceDoc.txt, 1) 统计其中所有字符的频度(某字符的频度等于其出现的总次数除以总字符数) , 包括字母(区分大小写) 、标点符号及格式控制符(空格、回车等) 。 2) 按频度统计结果生成哈夫曼编码码表。 3) 基于哈夫曼码表进行编码,生成对应的二进制码流,并输出到文件 Encode.dat。 4) 对二进制码流进行哈夫曼解码,把结果输出到文件 DecodeDoc.txt。 5) 判断DecodeDoc.txt与SourceDoc.txt内容是否一致,以 验证编解码系统的正确性。 要求: 1) 用 C 语言实现。 2) 用子函数实现各功能模块。 3) 输出文件 Statistic.txt,包含的信息有:按频度大小排序的字符表,及各字符出现 的次数、频度及哈夫曼编码。 4) 应至少包含链表、二叉树的数据结构。 5) 不能用冒泡排序算法。 #include<stdio.h> #include<stdlib.h> #include<string.h> #include<sys/stat.h> #include<sys/types.h> #include<fcntl.h> #include<unistd.h> #include<errno.h> #define N 10000 int count = 0; //每增加一个新的字符, count增加1, 可表示a中的字符种类数, 也即哈夫曼树叶子点个数 /*定义哈夫曼树结构体*/ typedef struct HuffmanTree{ int weight; int parent; int Lchild; int Rchild; }HuffmanTree[2*N]; /*定义储存字符及其出现次数的结构体*/ typedef struct DifferentCharacter{ char char_date; int num; //相同字符出现的次数 char a_code[100]; //每种字符对应的编码 }difcha[N]; /*在一定范围内选择两个weight最小的结点, 并将两个结点的序号赋给s1, s2*/ void select_two(HuffmanTree ht, int j, int *s1, int *s2) { int i = 1, temp; int min1 = 0, min2 = 0; while( (ht[i].parent != 0) && (i <= j) ) i++; *s1 = i; min1 = ht[i++].weight; while( (ht[i].parent != 0) && (i <= j) ) i++; *s2 = i; min2 = ht[i++].weight; if(min1 > min2){ temp = min1; min1 = min2; min2 = temp; } for(; i <= j; i++){ //遍历parent不为0的结点 if(ht[i].parent != 0) continue; if(ht[i].weight <= min1){ min2 = min1; min1 = ht[i].weight; *s2 = *s1; *s1 = i; } else if( (ht[i].weight < min2) && (ht[i].weight > min1) ) { min2 = ht[i].weight; *s2 = i; } } } /*建哈夫曼树*/ void EstHuffmanTree(HuffmanTree ht, int *w, int n){ int i; int s1 = 0, s2 = 0; for(i = 1; i <= n; i++){ //初始化哈夫曼树, 前n个单元存放叶子点 ht[i].weight = w[i]; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ //后n-1个单元存放非叶子点 ht[i].weight = 0; ht[i].parent = 0; ht[i].Lchild = 0; ht[i].Rchild = 0; } for(i = n+1; i <= 2*n-1; i++){ select_two(ht, i-1, &s1, &s2); //创建非叶子点, 建立哈夫曼树, 每次在ht[1]~ht[i-1]范围内选两个最小的weight结点,并将其序号赋给s1, s2 ht[i].weight = ht[s1].weight + ht[s2].weight; ht[i].Lchild = s1; ht[i].Rchild = s2; ht[s1].parent = i; ht[s2].parent = i; } //哈夫曼树建立完毕 } /*求哈弗曼编码*/ void CrtHuffmanCode(HuffmanTree ht, char **hcd, int n){ int start = 0, c = 0, p = 0, i; char *cd = (char*)malloc(n*sizeof(char)); //分配求当前编码的工作空间 cd[n-1] = '\0'; //从左向右存放编码 for(i = 1; i <= n; i++) { start = n-1; //初始化编码起始指针 c = i; p = ht[i].parent; while(p != 0){ start--; if(ht[p].Lchild == c) cd[start] = '0'; //左分支标0 else cd[start] = '1'; //右分支标1 c = p; //向上倒推 p = ht[c].parent; } hcd[i] = (char*)malloc((n-start)*sizeof(char)); strcpy(hcd[i], &cd[start]); } free(cd); } /*自定义错误处理函数*/ void my_err(char *err_string, int line){ printf("Line %d:\n", line); perror(err_string); exit(1); } /*从 buf_read 中统计每个字符出现的次数,将次数作为该字符的权值*/ void Statistics(difcha a, char *buf_read){ int i, j = 0; for(i = 0; i < strlen(buf_read) ; i++){ //对buf_read中的字符遍历 for(j = 0; j < count; j++){ //检查是否是新的字符 if(a[j].char_date == buf_read[i]){ a[j].num++; //若是旧字符, 则num++; break; } } if(j == count){ //若是新字符, 则记录到a中, 且对应的num++ a[count].char_date = buf_read[i]; a[count].num++; count++; //更新count } } } /*从 SourceDoc.txt 读取数据到 buf_read */ void ReadFile(char *pathName, char *buf_read){ int fd_date; int len = 0; if( (fd_date = open(pathName, O_RDWR)) < 0) //以读写方式打开SourceDoc.txt文件 my_err("open SourceDoc.txt", __LINE__); if(lseek(fd_date, 0, SEEK_END) < 0) //获取文件长度,并保持文件读写指针在文件开始处 my_err("lseek", __LINE__); if( (len = lseek(fd_date, 0, SEEK_CUR)) < 0 ) my_err("lseek", __LINE__); if(lseek(fd_date, 0, SEEK_SET) < 0) my_err("lseek", __LINE__); if(read(fd_date, buf_read, len) > len) //从SourceDoc.txt中读取内容 my_err("read SourceDoc.txt", __LINE__); } /*将 buf_code 写入 Encode.dat 中*/ void WriteFile(char *pathName, char *buf_code){ int fd_code; if((fd_code = open(pathName, O_CREAT|O_TRUNC|O_RDWR, S_IRWXU)) < 0) //创建Encode.dat文件 my_err("open Encode.dat", __LINE__); if( write(fd_code, buf_code, strlen(buf_code)) != strlen(buf_code) ) //将 buf_code 写入Encode.dat my_err("write Encode.dat", __LINE__); } /*主函数*/ void main(){ char buf_read[N] = {'\0'}; char buf_code[N] = {'\0'}; char buf_yima[N] = {'\0'}; char *hcd[N]; char temp[50] = {'\0'}; difcha a; int i, j, n, k = 0, m = 0; int w[N] = {0}; HuffmanTree ht; ReadFile("SourceDoc.txt", buf_read); Statistics(a, buf_read); for(i = 0; i < count; i++) w[i+1] = a[i].num; EstHuffmanTree(ht, w, count); //建HuffmanTree CrtHuffmanCode(ht, hcd, count); //对树中字符进行编码 for(i = 1; i <= count; i++) //将每个字符对应的编码存入结构体 a 中 strcpy(a[i-1].a_code, hcd[i]); FILE *fp1; fp1=fopen("Statistic.txt","w"); for(i = 0; i < count; i++) //查看每个字符的权值和对应的编码 fprintf(fp1,"%c %d %s\n", a[i].char_date, a[i].num, a[i].a_code); fclose(fp1); for(i = 0; i < strlen(buf_read) ; i++){ //遍历 buf_read, 给 SourceDoc.txt 中每个字符匹配编码, 存入 buf_code 中 for(j = 0; j < count; j++){ if(buf_read[i] == a[j].char_date){ strcat(buf_code, a[j].a_code); break; } } if(j == count) //匹配异常 printf("Unknown Character: %c\n", buf_read[i]); } WriteFile("Encode.dat", buf_code); //将 buf_code 写入 Encode.dat 中 ReadFile("Encode.dat", buf_read); //从 Encode.dat 中读取全部编码 n = strlen(buf_read); for(i = 0; i < n; i++){ //为 Encode.dat 中的编码匹配字符 temp[k++] = buf_read[i]; for(j = 0; j < count; j++){ if(strcmp(temp, a[j].a_code) == 0){ buf_yima[m++] = a[j].char_date; break; } } if(j < count){ //匹配成功, 对 temp 初始化 for(;k > 0; k--) temp[k] = '\0'; } } FILE *fp2; fp2=fopen("DecodeDoc.txt","w"); fprintf(fp2,"%s", buf_yima); fclose(fp2); }
请问如何才能将本地时间保存成txt文件的文件名
我的问题是这样的,容我赘述: 我的PC外接一个硬件系统,这个系统会通过我的程序传回相应的测量数值,我实时地保存传回的数值,将他们写在txt文件里面。但是,我现在的程序每次读写的文本文件都是固定的那一个,如果我想保留我上一次测量的数据我就需要打开我的文本文件,Ctrl+A然后Ctrl+C,最后粘贴到另一个文件里,太麻烦。 我希望达到这样的情况:每记录完一次数据,就以本地PC时间为文件名保存成“YYYYMMMMDDDD a=* b=* c=*.txt”的文件,而且这个文件名能传递给其他函数,如传递给fopen等,以备其他需要时使用。 外加一个问题:如果我要修改保存路径,将文件保存在一个绝对路径里,或者一个固定的路径里,应该使用哪个函数呢。 我是初学水平,没学过程序设计或者数据结构这类的计算机课程。水平比较凹。 [code=c]void MotioncaptureSystem10View::On2X32781() //Origin(100,450) { // TODO: 在此添加命令处理程序代码 CPoint point; static CPoint ORIpoint; char ch[500],rch[400],result[400]; int i=0,len=0,t=0,num=0,clen=0; memset(ch,0,500); memset(rch,0,400); memset(result,0,400); CFile file(_T("Collection of data.txt"),CFile::modeRead | CFile::shareDenyNone ); CFile file2(_T("result.txt"),CFile::modeCreate | CFile::modeWrite | CFile::shareDenyNone); sprintf_s(ch,("2015/02/11 15:01:04 Wednesday 本年第042天 中国标准时间\n|数据序列 传感器号| X坐标 Y坐标 Z坐标 A角度 E角度 R角度| 时间|\n|-----------------|--------------------------------------------------------|--------------|\n")); len=strlen("| 1 [ 0]| 19.521 5.186 5.774: 29.53 -25.18 50.93 | 0.0050|")+2; Erase();//自定义函数 //Coordinate(2);//自定义函数 ORIpoint.x=100;ORIpoint.y=450; Coordinate(X_Z,ORIpoint,1320,820,500);//自定义函数 if(file.Seek(strlen(ch)+1,CFile::begin)) { for(i=0;i<records;i++) { file.Read(rch,len); readtext(rch,len);//自定义函数 point.x=(int)(Dx*10+ORIpoint.x); point.y=(int)(Dz*10)+ORIpoint.y; if(!PaintFork(point))//自定义函数 break; } } file.Close(); file2.Close(); }[/code] 这是我的读取操作,我的写入操作是由fprintf完成的。 我就剩10分,望笑纳。巴萨赢了我就来分了!!
|undefined reference to `init_student_info_list'| 怎么解决?
大一c语言作业出现bug,求解决 ```main #include "student.h" #include <stdlib.h> #include <stdio.h> void menu(); //学生信息链表 student_info* student_list; //用户可以选择1-7可以分别进行学生信息的查看、添加、删除,修改,计算平均成绩,保存,退出系统操作。 int main() { int choice; int num; printf("**************************\n"); printf("欢迎使用学生信息管理系统\n"); printf("**************************\n"); printf("-----------------------------\n"); init_student_info_list(); if(read_file()) printf("从文件中读取学生信息成功.\n"); else printf("从文字中读取学生信息失败.\n"); printf("-----------------------------\n"); menu(); while(1) { printf("请选择操作: "); scanf("%d",&choice); switch(choice) { case 1: if(student_list_empty()) printf("学生信息表为空,请先添加学生信息.\n"); else display_student_info(); break; case 2: if(add_student_info()) printf("添加学生信息成功.\n"); else printf("添加学生信息失败.\n"); break; case 3: if(student_list_empty()) printf("学生信息表为空,请先添加学生信息.\n"); else { printf("请输入要删除学生信息的学号: "); scanf("%d",&num); if(delete_student_info(num)) printf("成功删除该学号对应的学生信息.\n"); else printf("删除失败.\n"); } break; case 4: if(student_list_empty()) printf("学生信息表为空,请先添加学生信息.\n"); else { printf("请输入要修改学生信息的学号: "); scanf("%d",&num); if(modify_student_info(num)) printf("成功修改该学号对应的学生信息.\n"); else printf("修改失败.\n"); } break; case 5: if(student_list_empty()) printf("学生信息表为空,请先添加学生信息.\n"); else display_average(); break; case 6: if(student_list_empty()) printf("学生信息表为空,请先添加学生信息.\n"); else if(save_file()) printf("保存学生信息成功.\n"); else printf("保存学生信息失败.\n"); break; case 0: printf("欢迎下次使用,再见.\n"); system("pause"); exit(0); break; default: printf("输入错误,请重新选择操作.\n"); } } system("pause"); return 0; } void menu() { printf("1.查看学生信息.\n"); printf("2.添加学生信息.\n"); printf("3.删除学生信息.\n"); printf("4.修改学生信息.\n"); printf("5.输出平均成绩.\n"); printf("6.保存学生信息.\n"); printf("0.退出系统操作.\n"); } ``` student。h #ifndef STUDENT_HEAD #define STUDENT_HEAD typedef struct node /*定义结构体*/ { int num; //学号 char name[15];//姓名 char sex[9]; //性别 int age; //年龄 int english; //英语成绩 int math; //数学成绩 int computer;//计算机成绩 int average; //平均成绩 struct node *next; //链表指针域 }student_info; //学生信息链表 extern student_info* student_list; //全局变量声明 //初始化函数声明 //初始化学生信息链表 void init_student_info_list(); //判断学生信息链表是否为空 int student_list_empty(); //操作函数声明 //向学校信息表中添加学生信息记录 int add_student_info(); //根据学号删除学生信息 int delete_student_info(int num); //根据学号修改学生信息 int modify_student_info(int num); //根据学号查找学生信息 student_info* search_student_info(int num); //输出每个学生的平均成绩 void display_average(); //显示所有学生信息 void display_student_info(); //将学生信息保存到文件 int save_file(); //从文件中读取学生信息 int read_file(); #endif ``` student。cpp #include "student.h" #include <stdio.h> #include <string.h> #include <malloc.h> //初始化学生信息链表 void init_student_info_list() { //学生信息链表头结点 student_list = (student_info*)malloc(sizeof(student_info)); student_list->next = NULL; } //判断学生信息链表是否为空 int student_list_empty() { return student_list->next == NULL; } //操作函数实现 //向学校信息表中添加学生信息记录 int add_student_info() { student_info *pstu = (student_info*)malloc(sizeof(student_info)); if(pstu == NULL) { printf("内存分配失败.\n"); return 0; } printf("请按要求一次输入学生的信息.\n"); printf("请输入学号: "); scanf("%d",&pstu->num); //判断该学号是否已经存在 if(search_student_info(pstu->num) != NULL) { printf("该学号已经存在学生信息表中.\n"); return 0; } printf("请输入姓名: "); getchar(); gets(pstu->name); printf("请输入性别: "); scanf("%s",pstu->sex); printf("请输入年龄: "); scanf("%d",&pstu->age); printf("请输入英语成绩: "); scanf("%d",&pstu->english); printf("请输入数学成绩: "); scanf("%d",&pstu->math); printf("请输入计算机成绩: "); scanf("%d",&pstu->computer); pstu->average = (pstu->english + pstu->math + pstu->computer)/3; //每次从学生信息链表的头部插入; pstu->next = student_list->next; student_list->next = pstu; return 1; } //根据学号删除学生信息 int delete_student_info(int num) { student_info *pstu; student_info *qstu; if(search_student_info(num) == NULL) { printf("不存在该学好为%d的学生信息.\n",num); return 0; } pstu = student_list->next; qstu = student_list; while(pstu->num != num) { qstu = pstu; pstu = pstu->next; } qstu->next = pstu->next; free(pstu); return 1; } //根据学号修改学生信息 int modify_student_info(int num) { int choice; student_info *pstu = search_student_info(num); if(pstu == NULL) { printf("不存在该学好为%d的学生信息.\n",num); return 0; } printf("1.姓名 2.性别 3.年龄 4.英语成绩 5.数学成绩 6.计算机成绩.\n"); printf("请选择修改的信息: "); scanf("%d",&choice); switch(choice) { case 1: printf("请输入新的姓名: "); getchar(); gets(pstu->name); break; case 2: printf("请输入新的性别: "); scanf("%s",pstu->sex); break; case 3: printf("请输入新的年龄: "); scanf("%d",&pstu->age); break; case 4: printf("请输入新的英语成绩: "); scanf("%d",&pstu->english); break; case 5: printf("请输入新的数学成绩: "); scanf("%d",&pstu->math); break; case 6: printf("请输入新的计算机成绩: "); scanf("%d",&pstu->computer); break; default: printf("请按提示要求操作.\n"); } return 1; } //根据学号查找学生信息 student_info* search_student_info(int num) { student_info *pstu; pstu = student_list->next; while(pstu && pstu->num != num) { pstu = pstu->next; } return pstu; } //输出每个学生的平均成绩 void display_average() { student_info *pstu; pstu = student_list->next; while(pstu) { printf("学号为%d,姓名为%s的学生平均成绩为: %d\n",pstu->num,pstu->name,pstu->average); pstu = pstu->next; } } //显示所有学生信息 void display_student_info() { student_info *pstu; pstu = student_list->next; printf("所有学生信息如下所示.\n"); printf("学号\t姓名\t性别\t年龄\t英语\t数学\t计算机\t平均成绩.\n"); while(pstu) { printf("%d\t",pstu->num); printf("%s\t",pstu->name); printf("%s\t",pstu->sex); printf("%d \t",pstu->age); printf("%d \t",pstu->english); printf("%d \t",pstu->math); printf("%d \t",pstu->computer); printf("%d\n",pstu->average); pstu = pstu->next; } } //将学生信息保存到文件 int save_file() { FILE *pfile; student_info *pstu; pfile = fopen("student.txt","w"); if(pfile == NULL) { printf("打开文件失败.\n"); return 0; } pstu = student_list->next; while(pstu) { fprintf(pfile,"%5d%15s%9s%3d%4d%4d%4d%4d",pstu->num,pstu->name,pstu->sex,pstu->age, pstu->english,pstu->math,pstu->computer,pstu->average); pstu = pstu->next; } fclose(pfile); return 1; } //从文件中读取学生信息 int read_file() { FILE *pfile; student_info *pstu; pfile = fopen("student.txt","r"); if(pfile == NULL) { printf("打开文件失败.\n"); return 0; } while(!feof(pfile)) { pstu = (student_info*)malloc(sizeof(student_info)); fscanf(pfile,"%5d%15s%9s%4d%4d%4d%4d%4d",&pstu->num,pstu->name,pstu->sex,&pstu->age, &pstu->english,&pstu->math,&pstu->computer,&pstu->average); pstu->average = (pstu->english + pstu->math + pstu->computer)/3; //每次从学生信息链表的头部插入; pstu->next = student_list->next; student_list->next = pstu; } fclose(pfile); return 1; } ``` 用code blokes运行 出现 D:\Projects\C\3\main.c|19|undefined reference to `init_student_info_list'| D:\Projects\C\3\main.c|20|undefined reference to `read_file'| D:\Projects\C\3\main.c|33|undefined reference to `student_list_empty'| 怎么解决啊?
CRC-32校验通信软件设计
环境要求:Windows;信息交换内容为文本文件;WinSock通信 编码要求:用模2除法计算CRC码,生成多项式为CRC-32 功能要求:能在两台计算机机上运行程序,一台产生CRC码,另一台校验。 我已经有生成CRC码的程序了,但是不知道怎么可以实现WinSock通信,一定要满足WinSock通信的要求,最好是C语言的,要是别的能成功也行。 跪求大神帮帮忙,我把资料都发过去,一直在线等!! 1.发送端电脑A源程序: ``` #include <stdio.h> #include <stdlib.h> __int64 crc; //定义全局变量crc __int64 create(__int64 data,__int64 POLY,int crcbitnumber) //生成crc码子函数 { __int64 regi = 0x0; // 使寄存器为0 __int64 data_temp; data_temp=data; int databitnumber=32; //定义数据位数,即输入的十六进制数最多8位 data<<= crcbitnumber; //data左移32位即在数据位后添加32个0 for ( int cur_bit = databitnumber+crcbitnumber-1; cur_bit >= 0; -- cur_bit ) //处理64 次(32 比特待测数据+32 比特扩展0),前32次是加载32比特待测数据,后32次是加载一比特扩展0 { if ( ( ( regi >> crcbitnumber ) & 0x0001 ) == 0x1 ) regi = regi ^ POLY; regi <<= 1; unsigned short tmp = ( data >> cur_bit ) & 0x0001; //加载待测数据1比特到tmp中,tmp只有1比特 regi |= tmp; //这1比特加载到寄存器中 } if ( ( ( regi >> crcbitnumber ) & 0x0001 ) == 0x1 ) regi = regi ^ POLY; //做最后一次XOR printf("\t\t\tcrc=%x\n",regi); crc=regi; data_temp<<=32; data_temp=data_temp+regi; return data_temp; } void main() { FILE*lp_code,*lp_crc;//定义文件指针 __int64 code;//code即为实际传输的数据 __int64 data;//data为从键盘输入的数据即要传输的数据 __int64 POLY= (__int64)0x254028D1*0x7 ; int crcbitnumber=32; printf("\n\t\t************** CRC校验发送端 **************\n\n"); printf("\t\t\t请输入需要传输的数据:"); scanf("%I64x",&data); //%x,输入16进制整数 code=create(data,POLY,crcbitnumber); printf("\t\t\tCODE=%I64x\n\n",code); lp_code=fopen("D:\\tongxinwang\\code.txt","w"); //建立文件,以写入方式打开 lp_crc = fopen("D:\\tongxinwang\\crc.txt","w"); fprintf(lp_code,"%I64x",code); fprintf(lp_crc,"%I64x",crc); getchar(); fclose(lp_code); fclose(lp_crc); } ``` 2.接收端电脑B源程序: ``` #include <stdio.h> #include <stdlib.h> __int64 exam(__int64 data,__int64 POLY,int crcbitnumber) { __int64 regi = 0x0; __int64 data_temp; data_temp=data; int databitnumber=32; for ( int cur_bit = databitnumber+crcbitnumber-1; cur_bit >= 0; -- cur_bit ) { if ( ( ( regi >> crcbitnumber ) & 0x0001 ) == 0x1 ) regi = regi ^ POLY; regi <<= 1; unsigned short tmp = ( data >> cur_bit ) & 0x0001; regi |= tmp; } if ( ( ( regi >> crcbitnumber ) & 0x0001 ) == 0x1 ) regi = regi ^ POLY; return(regi); } void main() {FILE* lp_code; __int64 code; __int64 result; __int64 POLY=(__int64) 0x254028D1*0x7; int crcbitnumber=32; printf("\n\t\t************** CRC校验接收端 **************\n\n"); lp_code=fopen("\\\\192.168.0.27\\tongxinwang\\code.txt","r"); fscanf(lp_code,"%I64x\n",&code); printf("\t\t\tcode=%I64x\n\n",code); fclose(lp_code); result=exam(code,POLY,crcbitnumber); printf("\t\t\tresult=%I64x,",result); if (result==0) {printf("数据传输正确!\n\n"); code>>=32; printf("\t\t\t去除CRC校验码后数据是%I64x。\n\n",code); } else printf("\n\t\t\t数据传输失败。"); } ```
huffman树编码压缩解压 压缩码表
// 压缩函数 int compress(char *ifname, char *ofname) { unsigned int i, j; unsigned int char_kinds; // 字符种类 unsigned char char_temp; // 暂存8bits字符 unsigned long file_len = 0; FILE *infile, *outfile; TmpNode node_temp; unsigned int node_num; HufTree huf_tree; char code_buf[256] = "\0"; // 待存编码缓冲区 unsigned int code_len; /* ** 动态分配256个结点,暂存字符频度, ** 统计并拷贝到树结点后立即释放 */ TmpNode *tmp_nodes =(TmpNode *)malloc(256*sizeof(TmpNode)); // 初始化暂存结点 for(i = 0; i < 256; ++i) { tmp_nodes[i].weight = 0; tmp_nodes[i].uch = (unsigned char)i; // 数组的256个下标与256种字符对应 } // 遍历文件,获取字符频度 infile = fopen(ifname, "rb"); // 判断输入文件是否存在 if (infile == NULL) return -1; fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 读入一个字符 while(!feof(infile)) { ++tmp_nodes[char_temp].weight; // 统计下标对应字符的权重,利用数组的随机访问快速统计字符频度 ++file_len; fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 读入一个字符 } fclose(infile); // 排序,将频度为零的放最后,剔除 for(i = 0; i < 256-1; ++i) for(j = i+1; j < 256; ++j) if(tmp_nodes[i].weight < tmp_nodes[j].weight) { node_temp = tmp_nodes[i]; tmp_nodes[i] = tmp_nodes[j]; tmp_nodes[j] = node_temp; } // 统计实际的字符种类(出现次数不为0) for(i = 0; i < 256; ++i) if(tmp_nodes[i].weight == 0) break; char_kinds = i; if (char_kinds == 1) { outfile = fopen(ofname, "wb"); // 打开压缩后将生成的文件 fwrite((char *)&char_kinds, sizeof(unsigned int), 1, outfile); // 写入字符种类 fwrite((char *)&tmp_nodes[0].uch, sizeof(unsigned char), 1, outfile); // 写入唯一的字符 fwrite((char *)&tmp_nodes[0].weight, sizeof(unsigned long), 1, outfile); // 写入字符频度,也就是文件长度 free(tmp_nodes); fclose(outfile); } else { node_num = 2 * char_kinds - 1; // 根据字符种类数,计算建立哈夫曼树所需结点数 huf_tree = (HufNode *)malloc(node_num*sizeof(HufNode)); // 动态建立哈夫曼树所需结点 // 初始化前char_kinds个结点 for(i = 0; i < char_kinds; ++i) { // 将暂存结点的字符和频度拷贝到树结点 huf_tree[i].uch = tmp_nodes[i].uch; huf_tree[i].weight = tmp_nodes[i].weight; huf_tree[i].parent = 0; } free(tmp_nodes); // 释放字符频度统计的暂存区 // 初始化后node_num-char_kins个结点 for(; i < node_num; ++i) huf_tree[i].parent = 0; CreateTree(huf_tree, char_kinds, node_num); // 创建哈夫曼树 HufCode(huf_tree, char_kinds); // 生成哈夫曼编码 // 写入字符和相应权重,供解压时重建哈夫曼树 outfile = fopen(ofname, "wb"); // 打开压缩后将生成的文件 fwrite((char *)&char_kinds, sizeof(unsigned int), 1, outfile); // 写入字符种类 for(i = 0; i < char_kinds; ++i) { fwrite((char *)&huf_tree[i].uch, sizeof(unsigned char), 1, outfile); // 写入字符(已排序,读出后顺序不变) fwrite((char *)&huf_tree[i].weight, sizeof(unsigned long), 1, outfile); // 写入字符对应权重 } // 紧接着字符和权重信息后面写入文件长度和字符编码 fwrite((char *)&file_len, sizeof(unsigned long), 1, outfile); // 写入文件长度 infile = fopen(ifname, "rb"); // 以二进制形式打开待压缩的文件 fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 每次读取8bits while(!feof(infile)) { // 匹配字符对应编码 for(i = 0; i < char_kinds; ++i) if(char_temp == huf_tree[i].uch) strcat(code_buf, huf_tree[i].code); // 以8位(一个字节长度)为处理单元 while(strlen(code_buf) >= 8) { char_temp = '\0'; // 清空字符暂存空间,改为暂存字符对应编码 for(i = 0; i < 8; ++i) { char_temp <<= 1; // 左移一位,为下一个bit腾出位置 if(code_buf[i] == '1') char_temp |= 1; // 当编码为"1",通过或操作符将其添加到字节的最低位 } fwrite((char *)&char_temp, sizeof(unsigned char), 1, outfile); // 将字节对应编码存入文件 strcpy(code_buf, code_buf+8); // 编码缓存去除已处理的前八位 } fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 每次读取8bits } // 处理最后不足8bits编码 code_len = strlen(code_buf); if(code_len > 0) { char_temp = '\0'; for(i = 0; i < code_len; ++i) { char_temp <<= 1; if(code_buf[i] == '1') char_temp |= 1; } char_temp <<= 8-code_len; // 将编码字段从尾部移到字节的高位 fwrite((char *)&char_temp, sizeof(unsigned char), 1, outfile); // 存入最后一个字节 } // 关闭文件 fclose(infile); fclose(outfile); // 释放内存 for(i = 0; i < char_kinds; ++i) free(huf_tree[i].code); free(huf_tree); } }//compress 代码如上 不懂的就是压缩后码表的部分 希望各位懂得帮帮忙 huffman树以及码表如下图,求解释码表下半部分引出部分。
huffman编码压缩的码表看不懂求解
// 压缩函数 int compress(char ifname, char *ofname) { unsigned int i, j; unsigned int char_kinds; // 字符种类 unsigned char char_temp; // 暂存8bits字符 unsigned long file_len = 0; FILE *infile, *outfile; TmpNode node_temp; unsigned int node_num; HufTree huf_tree; char code_buf[256] = "\0"; // 待存编码缓冲区 unsigned int code_len; / ** 动态分配256个结点,暂存字符频度, ** 统计并拷贝到树结点后立即释放 */ TmpNode *tmp_nodes =(TmpNode *)malloc(256*sizeof(TmpNode)); // 初始化暂存结点 for(i = 0; i < 256; ++i) { tmp_nodes[i].weight = 0; tmp_nodes[i].uch = (unsigned char)i; // 数组的256个下标与256种字符对应 } // 遍历文件,获取字符频度 infile = fopen(ifname, "rb"); // 判断输入文件是否存在 if (infile == NULL) return -1; fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 读入一个字符 while(!feof(infile)) { ++tmp_nodes[char_temp].weight; // 统计下标对应字符的权重,利用数组的随机访问快速统计字符频度 ++file_len; fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 读入一个字符 } fclose(infile); // 排序,将频度为零的放最后,剔除 for(i = 0; i < 256-1; ++i) for(j = i+1; j < 256; ++j) if(tmp_nodes[i].weight < tmp_nodes[j].weight) { node_temp = tmp_nodes[i]; tmp_nodes[i] = tmp_nodes[j]; tmp_nodes[j] = node_temp; } // 统计实际的字符种类(出现次数不为0) for(i = 0; i < 256; ++i) if(tmp_nodes[i].weight == 0) break; char_kinds = i; if (char_kinds == 1) { outfile = fopen(ofname, "wb"); // 打开压缩后将生成的文件 fwrite((char *)&char_kinds, sizeof(unsigned int), 1, outfile); // 写入字符种类 fwrite((char *)&tmp_nodes[0].uch, sizeof(unsigned char), 1, outfile); // 写入唯一的字符 fwrite((char *)&tmp_nodes[0].weight, sizeof(unsigned long), 1, outfile); // 写入字符频度,也就是文件长度 free(tmp_nodes); fclose(outfile); } else { node_num = 2 * char_kinds - 1; // 根据字符种类数,计算建立哈夫曼树所需结点数 huf_tree = (HufNode *)malloc(node_num*sizeof(HufNode)); // 动态建立哈夫曼树所需结点 // 初始化前char_kinds个结点 for(i = 0; i < char_kinds; ++i) { // 将暂存结点的字符和频度拷贝到树结点 huf_tree[i].uch = tmp_nodes[i].uch; huf_tree[i].weight = tmp_nodes[i].weight; huf_tree[i].parent = 0; } free(tmp_nodes); // 释放字符频度统计的暂存区 // 初始化后node_num-char_kins个结点 for(; i < node_num; ++i) huf_tree[i].parent = 0; CreateTree(huf_tree, char_kinds, node_num); // 创建哈夫曼树 HufCode(huf_tree, char_kinds); // 生成哈夫曼编码 // 写入字符和相应权重,供解压时重建哈夫曼树 outfile = fopen(ofname, "wb"); // 打开压缩后将生成的文件 fwrite((char *)&char_kinds, sizeof(unsigned int), 1, outfile); // 写入字符种类 for(i = 0; i < char_kinds; ++i) { fwrite((char *)&huf_tree[i].uch, sizeof(unsigned char), 1, outfile); // 写入字符(已排序,读出后顺序不变) fwrite((char *)&huf_tree[i].weight, sizeof(unsigned long), 1, outfile); // 写入字符对应权重 } // 紧接着字符和权重信息后面写入文件长度和字符编码 fwrite((char *)&file_len, sizeof(unsigned long), 1, outfile); // 写入文件长度 infile = fopen(ifname, "rb"); // 以二进制形式打开待压缩的文件 fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 每次读取8bits while(!feof(infile)) { // 匹配字符对应编码 for(i = 0; i < char_kinds; ++i) if(char_temp == huf_tree[i].uch) strcat(code_buf, huf_tree[i].code); // 以8位(一个字节长度)为处理单元 while(strlen(code_buf) >= 8) { char_temp = '\0'; // 清空字符暂存空间,改为暂存字符对应编码 for(i = 0; i < 8; ++i) { char_temp <<= 1; // 左移一位,为下一个bit腾出位置 if(code_buf[i] == '1') char_temp |= 1; // 当编码为"1",通过或操作符将其添加到字节的最低位 } fwrite((char *)&char_temp, sizeof(unsigned char), 1, outfile); // 将字节对应编码存入文件 strcpy(code_buf, code_buf+8); // 编码缓存去除已处理的前八位 } fread((char *)&char_temp, sizeof(unsigned char), 1, infile); // 每次读取8bits } // 处理最后不足8bits编码 code_len = strlen(code_buf); if(code_len > 0) { char_temp = '\0'; for(i = 0; i < code_len; ++i) { char_temp <<= 1; if(code_buf[i] == '1') char_temp |= 1; } char_temp <<= 8-code_len; // 将编码字段从尾部移到字节的高位 fwrite((char *)&char_temp, sizeof(unsigned char), 1, outfile); // 存入最后一个字节 } // 关闭文件 fclose(infile); fclose(outfile); // 释放内存 for(i = 0; i < char_kinds; ++i) free(huf_tree[i].code); free(huf_tree); } }//compress 代码如上 不懂的就是压缩后码表的部分 希望各位懂得帮帮忙 huffman树以及码表如
求大神解决这个问题,error2143: missing ':' before ';'
我是新入行的,很多不懂 希望大家多指教了。这个错误是什么原因啊 有点奇葩。我把 代码贴以下把; ``` // TODO: Add your command handler code here FILE *fp; fp=fopen("C:\\Users\\zcq\\Desktop\\draw.txt","rb"); CRect rc; GetClientRect(&rc); if(fp==NULL) { AfxMessageBox("文件打开失败,请检查路径是否正确"); return; } while(!feof(fp)) { UINT type,size; size=fread(&type,sizeof(UINT),1,fp); CDrawer *drawer=NULL; if(!size) return; switch(type) { case LINE_TYPE: drawer=new CLineDrawer(); break; default: break; } drawer->ReadFile(fp,rc,m_map.m_zero,m_map.m_perSize); } ```
求大神帮我改成链表方法。。
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Student { char id[20]; char name[20]; float Chinese; float Math; float English; float average; }students[1024]; int j=0; int id1(char id[]) { int i; for (i=0;i<j;i++) { if (strcmp(students[i].id,id)==0) { return i; } } return -1; } int name1(char name[]) { int i; for (i=0;i<j;i++) { if (strcmp(students[i].name,name)==0) { return i; } } return -1; } void personal(int code) { printf("%10s%10s%10s%10s%10s%10s\n","学号","姓名","语文成绩","数学成绩","英语成绩","平均成绩"); printf("**************************************************************\n"); printf("%10s%10s%10g%10g%10g%10g\n",students[code].id,students[code].name,students[code].Chinese,students[code].Math,students[code].English,students[code].average); puts(""); } void display() { int i; printf("%10s%10s%10s%10s%10s%10s\n","学号","姓名","语文成绩","数学成绩","英语成绩","平均成绩"); printf("**************************************************************\n"); for (i=0;i<j;i++) { printf("%10s%10s%10g%10g%10g%10g\n",students[i].id,students[i].name,students[i].Chinese,students[i].Math,students[i].English,students[i].average); } } void namesearch() { while(1) { char name[20]; int code; printf("请输入要查询的学生的姓名:"); scanf("%s",&name); puts(""); getchar(); code=name1(name); if (code==-1) { printf("学生不存在!\n"); } else { printf("你要查询的学生信息为:\n"); puts(""); personal(code); } printf("是否继续?(Y/N)"); if (getchar()=='N') { break; } } } void idsearch() { while(1) { char id[20]; int code; printf("请输入要查询学生的学号:"); scanf("%s",&id); puts(""); getchar(); code=id1(id); if (code==-1) { printf("学生不存在!\n"); } else { printf("你要查询的学生信息为:\n"); puts(""); personal(code); } printf("是否继续?(Y/N)"); if (getchar()=='N') { break; } } } void input() { while(1) { printf("输入学号:"); scanf("%s",&students[j].id); getchar(); printf("输入姓名:"); scanf("%s",&students[j].name); getchar(); printf("输入语文成绩:"); scanf("%f",&students[j].Chinese); getchar(); printf("输入数学成绩:"); scanf("%f",&students[j].Math); getchar(); printf("输入英语成绩:"); scanf("%f",&students[j].English); getchar(); students[j].average=(students[j].Chinese+students[j].Math+students[j].English)/3; printf("平均成绩为:%g\n",students[j].average); j++; puts(""); printf("是否继续?(Y/N)"); if (getchar()=='N') { break; } } puts(""); } int cmp(const void*a,const void*b) { return ((struct Student*)a)->average < ((struct Student*)b)->average ? 1 : 0 ; } void sort() { qsort(students,j,sizeof(struct Student),cmp); } void modify() { while(1) { char id[20]; int code; printf("请输入要修改的学生的学号:"); scanf("%s",&id); puts(""); getchar(); code=id1(id); if (code==-1) { printf("学生不存在!\n"); } else { printf("你要修改的学生信息为:\n"); puts(""); personal(code); printf("************ 请重新输入学生信息 ************\n"); puts(""); printf("输入学号:"); scanf("%s",&students[code].id); getchar(); printf("输入姓名:"); scanf("%s",&students[code].name); getchar(); printf("输入语文成绩:"); scanf("%f",&students[code].Chinese); getchar(); printf("输入数学成绩:"); scanf("%f",&students[code].Math); getchar(); printf("输入英语成绩:"); scanf("%f",&students[code].English); getchar(); students[j].average=(students[code].Chinese+students[code].Math+students[code].English)/3; printf("平均成绩为:%g\n",students[code].average); } puts(""); printf("是否继续?(Y/N)"); if (getchar()=='N') { break; } } puts(""); } void delete() { int i; while(1) { char id[20]; int code; printf("请输入要删除的学生的学号:"); scanf("%s",&id); puts(""); getchar(); code=id1(id); if (code==-1) { printf("学生不存在!\n"); } else { printf("你要删除的学生信息为:\n"); personal(code); printf("确定?(Y/N)"); if (getchar()=='Y') { for (i=code;i<j-1;i++) { students[i]=students[i+1]; } j--; } getchar(); } printf("是否继续?(Y/N)"); if (getchar()=='N') { break; } } } void read() { FILE *fp; int i; if ((fp=fopen("c:\\Database.txt","rb"))==NULL) { printf("不能打开文件!\n"); return; } if (fread(&j,sizeof(int),1,fp)!=1) { j=-1; } else { for(i=0;i<j;i++) { fread(&students[i],sizeof(struct Student),1,fp); } } fclose(fp); } void write() { FILE *fp; int i; if ((fp=fopen("c:\\Database.txt","wb"))==NULL) { printf("不能打开文件!\n"); return; } if (fwrite(&j,sizeof(int),1,fp)!=1) { printf("写入文件错误!\n"); } for (i=0;i<j;i++) { if (fwrite(&students[i],sizeof(struct Student),1,fp)!=1) { printf("写入文件错误!\n"); } } fclose(fp); } int main() { int option; read(); while(1) { printf("\n------ 学生成绩管理系统------\n"); printf("1. 增加学生记录\n"); printf("2. 修改学生记录\n"); printf("3. 删除学生记录\n"); printf("4. 按姓名查询学生记录\n"); printf("5. 按学号查询学生记录\n"); printf("6. 按平均成绩排序\n"); printf("7. 退出\n"); printf("请选择(1-7):"); scanf("%d",&option); getchar(); switch(option) { case 1: input(); break; case 2: modify(); break; case 3: delete(); break; case 4: namesearch(); break; case 5: idsearch(); case 6: sort(); display(); break; case 7: exit(0); break; } write(); } } 作业要求用链表做 可是我不会链表,求大神帮忙修改下
关于HUFFMAN利用数组压缩的算法问题
整体代码如下,具体关于问题在最下方, struct head { unsigned char b; /*the charactor*/ long count; /*the frequency*/ long parent,lch,rch; /*make a tree*/ char bits[256]; /*the haffuman code*/ } header[512],tmp; void compress() { clock_t start,end; char filename[255],outputfile[255],buf[512]; int fn = 0, sz = 0, sz1 = 0; double x = 0; unsigned char c; long i,j,m,n,f; long min1,pt1,flength; FILE *ifp,*ofp; printf("源文件名:"); gets_s(filename); ifp=fopen(filename,"rb"); if(ifp==NULL) { printf("源文件打开失败!\n"); return; } fn = _fileno(ifp); /*取得文件指针的底层流式文件号*/ sz = _filelength(fn);/*根据文件号取得文件大小*/ printf("文件大小为:%d B.\n", sz); sz1 = sz; printf("压缩后文件名:"); gets_s(outputfile); start=clock(); /* 计时开始 */ ofp=fopen(outputfile,"wb"); if(ofp==NULL) { printf("压缩文件打开失败!\n"); return; } flength=0; while(!feof(ifp)) { fread(&c,1,1,ifp);//读数据 header[c].count++; //字符重复出现频率+1 flength++; //字符出现原文件长度+1 } flength--; header[c].count--;//减一平衡位数 for(i=0;i<512;i++) { if(header[i].count!=0) header[i].b=(unsigned char)i; /*将每个哈夫曼码值及其对应的ASCII码存放在一维数组header[i]中, 且编码表中的下标和ASCII码满足顺序存放关系*/ else header[i].b=0; header[i].parent=-1; //对结点进行初始化 header[i].lch=header[i].rch=-1; } for(i=0;i<256;i++)//根据频率(权值)大小,对结点进行排序,选择较小的结点进树 { for(j=i+1;j<256;j++) { if(header[i].count<header[j].count) { tmp=header[i]; header[i]=header[j]; header[j]=tmp; } } } for(i=0;i<256;i++) if(header[i].count==0) break; n=i; m=2*n-1; //外部叶子结点数为n个时,内部结点数为n-1,整个哈夫曼树的需要的结点数为2*n-1. for(i=n;i<m;i++)//构建哈夫曼树 { min1=999999999; for(j=0;j<i;j++) { if(header[j].parent!=-1) continue;//parent!=-1说明该结点已存在哈夫曼树中,跳出循环重新选择新结点*/ if(min1>header[j].count) { pt1=j; min1=header[j].count;//找到最小值 continue; } } header[i].count=header[pt1].count; header[pt1].parent=i; //依据parent域值(结点层数)确定树中结点之间的关系 header[i].lch=pt1;//计算左分支权值大小 min1=999999999; for(j=0;j<i;j++) { if(header[j].parent!=-1) continue; if(min1>header[j].count) { pt1=j; min1=header[j].count; continue; } } header[i].count+=header[pt1].count; header[i].rch=pt1;//计算右分支权值大小 header[pt1].parent=i; } for(i=0;i<n;i++) //哈夫曼无重复前缀编码 { f=i; header[i].bits[0]=0;//根结点编码0 while(header[f].parent!=-1) { j=f; f=header[f].parent; if(header[f].lch==j) //置左分支编码0 { j=strlen(header[i].bits);//扫描长度 memmove(header[i].bits+1,header[i].bits,j+1);//由header复制j+ 1个到前者 //依次存储连接“0”“1”编码 header[i].bits[0]='0'; } else//置右分支编码1 { j=strlen(header[i].bits);//计算字符长度? memmove(header[i].bits+1,header[i].bits,j+1); header[i].bits[0]='1'; } } } fseek(ifp,0,SEEK_SET);//从文件开始位置向前移动0字节,即定位到文件开始位置 fwrite(&flength,sizeof(int),1,ofp);/*用来将数据写入文件流中,参数flength指向欲写入的数据地址, 总共写入的字符数以参数size*int来决定,返回实际写入的int数目1*/ fseek(ofp,8,SEEK_SET); buf[0]=0; //定义缓冲区,它的二进制表示00000000 f=0; pt1=8; /*假设原文件第一个字符是"A",8位2进制为01000001,编码后为0110识别编码第一个'0', 那么我们就可以将其左移一位,看起来没什么变化。下一个是'1',应该|1,结果00000001 同理4位都做完,应该是00000110,由于字节中的8位并没有全部用完,我们应该继续读下一个字符, 根据编码表继续拼完剩下的4位,如果字符的编码不足4位,还要继续读一个字符, 如果字符编码超过4位,那么我们将把剩下的位信息拼接到一个新的字节里*/ while(!feof(ifp)) { c=fgetc(ifp); f++; for(i=0;i<n;i++) { if(c==header[i].b) break; } strcat(buf,header[i].bits); j=strlen(buf); c=0; while(j>=8) //对哈夫曼编码位操作进行压缩存储 { for(i=0;i<8;i++) { if(buf[i]=='1') c=(c<<1)|1; else c=c<<1; } fwrite(&c,1,1,ofp); pt1++; //统计压缩后文件的长度 strcpy(buf,buf+8);//一个字节一个字节拼接 j=strlen(buf); } if(f==flength) break; } if(j>0) //对哈夫曼编码位操作进行压缩存储 { strcat(buf,"00000000"); for(i=0;i<8;i++) { if(buf[i]=='1') c=(c<<1)|1; else c=c<<1; } fwrite(&c,1,1,ofp); pt1++; } fseek(ofp,4,SEEK_SET); fwrite(&pt1,sizeof(long),1,ofp); fseek(ofp,pt1,SEEK_SET); fwrite(&n,sizeof(long),1,ofp); for(i=0;i<n;i++) { fwrite(&(header[i].b),1,1,ofp); c=strlen(header[i].bits); fwrite(&c,1,1,ofp); j=strlen(header[i].bits); if(j%8!=0) //若存储的位数不是8的倍数,则补0 { for(f=j%8;f<8;f++) strcat(header[i].bits,"0"); } while(header[i].bits[0]!=0) { c=0; for(j=0;j<8;j++) //字符的有效存储不超过8位,则对有效位数左移实现两字符编码的连接 { if(header[i].bits[j]=='1') c=(c<<1)|1; //|1不改变原位置上的“0”“1”值 else c=c<<1; } strcpy(header[i].bits,header[i].bits+8);// 把字符的编码按原先存储顺序连接 fwrite(&c,1,1,ofp); } } fclose(ifp); printf("压缩成功!\n"); end=clock(); /* 计时结束 */ fn = _fileno(ofp); /*取得文件指针的底层流式文件号*/ sz = _filelength(fn);/*根据文件号取得文件大小*/ printf("压缩后文件大小为:%d B.\n", sz); x = (sz / sz1)*1.0; printf("压缩率为:%d B.\n", x); fclose(ofp); printf("压缩用时%f秒\n",(double)(end - start) / CLOCKS_PER_SEC); return; } // 整体代码如上,请问下 关于找到最小值以后 header[i].count=header[pt1].count; header[pt1].parent=i; //依据parent域值(结点层数)确定树中结点之间的关系 header[i].lch=pt1;//计算左分支权值大小 哈夫曼生成的节点权重不应该两者之和么,这个对于双亲的赋值不是很懂,这种利用数组进行排序以后的这个操作不是很明白,这个i好像是顺序,但不是累加,怎么剔除以后去和剩下的节点比较啊。原来搞不明白这里怎么赋值的
PL0编译器调用procedure无限循环
如题,自己参照网上的例子做了一个C语言的PL0编译器,能跑通,但是遇到调用procedure的时候,就会一直循环无限调用,查错查了好久,还是没有找到,希望有大神能为我解答一下!谢谢~ 代码如下,有点长。。 #include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> using namespace std; #define MAXERR 20//最多错误次数 #define AL 12//标识符最大长度 #define NORW 14//保留字个数 #define NUMMAX 14//最大数字位数 #define TXMAX 100//符号表容量 #define AMAX 2048//地址上界 #define CXMAX 200//最多的虚拟机代码数 #define stacksize 500//运行时数据栈元素最多为500个 #define symnum 32 #define fctnum 8 enum symbol //符号 { nul, ident, number, pluss, minuss, times, slash, oddsym, eql, neq, lss, leq, gtr, geq, lparen, rparen, comma, semicolon, period, becomes, beginsym, endsym, ifsym, thensym, elsesym, whilesym, writesym, readsym, dosym, callsym, constsym, varsym, procsym, }; enum object //符号表类型 { constant, variable, procedure, }; enum fct //虚拟机指令 { LIT, OPR, LOD, STO, CAL, INT, JMP, JPC, }; struct instruction //虚拟机代码结构 { enum fct f;//虚拟机指令 int l;//引用层与声明层层次差 int a;//根据f的不同而不同 }; FILE * fin; FILE * fout; FILE * fv;//虚拟机代码 FILE * fo;//源代码 FILE * fr;//代码运行结果 FILE * ft;//符号表 char fname[AL]; char ch;//存放当前字符 int cc, ll;//getch计数器,cc表示ch的位 int cx;//虚拟机代码指针 int num;//当前数字 int err;//错误计数器 char a[AL+1];//临时符号 char id[AL+1];//当前ident char line[81];//行缓冲区 char word[NORW][AL];//保留字 enum symbol sym;//当前符号 enum symbol wsym[NORW];//保留字对应符号值 enum symbol ssym[256];//单字符符号值 struct instruction code[CXMAX];//存放虚拟机代码的数组 char mnemonic[fctnum][5];//虚拟机代码指令名称 bool declbegsys[symnum];//表示声明开始的符号集合 bool statbegsys[symnum];//表示语句开始的符号集合 bool facbegsys[symnum];//表示因子开始的符号集合 struct tablestruct //符号表结构 { char name[AL];//名字 enum object kind;//类型 int val;//数值 int level;//所处层 int addr;//地址 int size;//需要分配的数据区空间 }; struct tablestruct table[TXMAX];//符号表 void init(); int inset(int e, bool* s); int addset(bool* sr, bool* s1, bool* s2, int n); int subset(bool* sr, bool* s1, bool* s2, int n); int mulset(bool* sr, bool* s1, bool* s2, int n); void error(int n); void getsym(); void getch(); void gen(enum fct x, int y, int z); void test(bool* s1, bool* s2, int n); void block(int lev, int tx, bool* fsys); void enter(enum object k, int* ptx, int lev, int* pdx); int position(char* idt, int tx); void constdeclaration(int* ptx, int lev, int* pdx); void vardeclaration(int* ptx, int lev, int* pdx); void listcode(int cx0); void statement(bool* fsys, int* ptx, int lev); void expression(bool* fsys, int* ptx, int lev); void term(bool* fsys, int* ptx, int lev); void factor(bool* fsys, int* ptx, int lev); void condition(bool* fsys, int* ptx, int lev); void interpret(); int base(int l, int* s, int b); void init() { int i; for(i=0; i<255; i++) //单字符符号 { ssym[i] = nul; } ssym['+'] = pluss; ssym['-'] = minuss; ssym['*'] = times; ssym['/'] = slash; ssym['('] = lparen; ssym[')'] = rparen; ssym['='] = eql; ssym[','] = comma; ssym['.'] = period; ssym[';'] = semicolon; //保留字名字 strcpy(&(word[0][0]), "begin"); strcpy(&(word[1][0]), "call"); strcpy(&(word[2][0]), "const"); strcpy(&(word[3][0]), "do"); strcpy(&(word[4][0]), "else"); strcpy(&(word[5][0]), "end"); strcpy(&(word[6][0]), "if"); strcpy(&(word[7][0]), "odd"); strcpy(&(word[8][0]), "procedure"); strcpy(&(word[9][0]), "read"); strcpy(&(word[10][0]), "then"); strcpy(&(word[11][0]), "var"); strcpy(&(word[12][0]), "while"); strcpy(&(word[13][0]), "write"); //保留字符号 wsym[0] = beginsym; wsym[1] = callsym; wsym[2] = constsym; wsym[3] = dosym; wsym[4] = elsesym; wsym[5] = endsym; wsym[6] = ifsym; wsym[7] = oddsym; wsym[8] = procsym; wsym[9] = readsym; wsym[10] = thensym; wsym[11] = varsym; wsym[12] = whilesym; wsym[13] = writesym; //指令名称 strcpy(&(mnemonic[LIT][0]), "LIT"); strcpy(&(mnemonic[OPR][0]), "OPR"); strcpy(&(mnemonic[LOD][0]), "LOD"); strcpy(&(mnemonic[STO][0]), "STO"); strcpy(&(mnemonic[CAL][0]), "CAL"); strcpy(&(mnemonic[INT][0]), "INT"); strcpy(&(mnemonic[JMP][0]), "JMP"); strcpy(&(mnemonic[JPC][0]), "JPC"); //符号集 for(i=0; i<symnum; i++) { declbegsys[i] = false; statbegsys[i] = false; facbegsys[i] = false; } //声明开始符号集 declbegsys[constsym] = true; declbegsys[varsym] = true; declbegsys[procsym] = true; //语句开始符号集 statbegsys[beginsym] = true; statbegsys[callsym] = true; statbegsys[ifsym] = true; statbegsys[whilesym] = true; //因子开始符号集 facbegsys[ident] = true; facbegsys[number] = true; facbegsys[lparen] = true; } /* *用数组实现集合的集合运算 */ int inset(int e, bool* s) { return s[e]; } int addset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n ;i++) { sr[i] = s1[i] || s2[i]; } return 0; } int subset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n; i++) { sr[i] = s1[i] && (!s2[i]); } return 0; } int mulset(bool* sr, bool* s1, bool* s2, int n) { int i; for(i=0; i<n; i++) { sr[i] = s1[i] && s2[i]; } return 0; } //error处理:输出报错位置以及错误编号 void error(int n) { cc--;//出错时当前符号已经读完,cc-1 //printf("错误编号:%d\n",n); cout<<"错误编号:"<<n<<endl; fprintf(fo, "错误编号:%d\n", n); err++; if(err > MAXERR) { exit(1); } } //读取字符 void getch() { if(cc == ll)//判断缓冲区中是否有字符,若无字符,则读入下一行字符到缓冲区中 { if(feof(fin)) { cout<<"程序不完整"<<endl; exit(1); } ll = 0; cc = 0; printf("%d ", cx); fprintf(fo, "%d ", cx); ch = ' '; while(ch != 10)//读取一行字符到缓冲区 { //fscanf(fin,"%c",&ch) if(EOF == fscanf(fin, "%c", &ch)) { line[ll] = 0; break; } printf("%c", ch); //cout<<ch; fprintf(fo, "%c", ch); line[ll] = ch; ll++; } } ch = line[cc]; cc++; } //词法分析 void getsym() { int i, j, k; while(ch==' ' || ch==10 || ch==9)//过滤掉空格、换行符 { getch(); } if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z')) { i = 0; do{ if(i < AL) { a[i] = ch; i++; } getch(); } while((ch>='a' && ch<='z') || (ch>='A' && ch<='Z') || (ch>='0' && ch<='9')); a[i] = 0; strcpy(id, a); /* for(j = 0; j < 13; j++) { if(strcmp(id, word[i]) == 0) break; } */ //改为用二分法查找保留字 j = 0; k = NORW - 1; do { i=(j + k) / 2; if(strcmp(id, word[i])<=0) { k = i - 1; } if(strcmp(id, word[i])>=0) { j = i + 1; } } while(j <= k); if(j - 1 > k)//单词为保留字 { sym = wsym[i]; } else//单词为标识符 { sym = ident; } } else { if(ch>='0' && ch<='9')//单词为数字 { i = 0; num = 0; sym = number; do { num = 10 * num + ch - '0'; i++; getch(); } while(ch>='0' && ch<='9'); //获取数字的值 i--; if(i > NUMMAX)//数字位数太大 { error(30); } } else { if(ch == ':')//检测赋值符号 { getch(); if(ch == '=') { sym = becomes; getch(); } else { sym = nul;//不能识别的符号 } } else { if(ch == '<')//检测小于或小于等于符号以及不等号 { getch(); if(ch == '=') { sym = leq; getch(); } else if(ch=='>')//检测不等号 { sym = neq;//构成不等号<> getch(); } else { sym = lss; } } else { if(ch == '>')//检测大于或大于等于符号 { getch(); if(ch == '=') { sym = geq; getch(); } else { sym = gtr; } } else { sym = ssym[ch];//当符号不满足上述条件时,全部按照单字符号处理 if(sym != period) { getch(); } } } } } } } //生成P-code即虚拟机代码 void gen(enum fct x, int y, int z ) { if (cx >= CXMAX) { cout<<"虚拟机代码长度过长!"<<endl; exit(1); } if ( z >= AMAX) { cout<<"地址偏移越界!"<<endl; exit(1); } code[cx].f = x; code[cx].l = y; code[cx].a = z; cx++; } //测速当前符号单词是否合法 void test(bool* s1, bool* s2, int n) { if(!inset(sym, s1)) { error(n);//当检测不通过时,不停获取符号,直到它属于S1或S2 while((!inset(sym, s1)) && (!inset(sym, s2))) { getsym(); } } } //分程序分析处理 void block(int lev, int tx, bool* fsys) { int i; int dx;//名字分配到的相对地址 int tx0;//保留初始tx int cx0;//保留初始cx bool nxtlev[symnum]; dx = 3;//分别存放SL,DL和返回地址 tx0 = tx;//本层标识符初始位置 table[tx].addr = cx;//当前层代码开始位置 gen(JMP, 0, 0);//生成跳转指令 do{ if(sym == constsym)//常量声明符号,处理常量声明 { getsym(); do{ constdeclaration(&tx, lev, &dx); while(sym == comma)//逗号,继续读取 { getsym(); constdeclaration(&tx, lev, &dx); } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉逗号或者分号 } }while(sym == ident); } if(sym == varsym)//变量声名符号,处理变量声名 { getsym(); do{ vardeclaration(&tx, lev, &dx); while(sym == comma)//逗号,继续读取 { getsym(); vardeclaration(&tx, lev, &dx); } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉逗号或者分号 } }while(sym == ident); } while(sym == procsym)//过程声名符号,处理过程声名 { getsym(); if(sym == ident) { enter(procedure, &tx, lev, &dx);//过程名字 getsym(); } else { error(4);//procedure后应为标识符 } if(sym == semicolon)//分号,结束读取 { getsym(); } else { error(5);//漏掉分号 } memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[semicolon]=true; block(lev+1, tx, nxtlev);//递归 if(sym == semicolon) { getsym(); memcpy(nxtlev, statbegsys, sizeof(bool)* symnum); nxtlev[ident]=true; nxtlev[procsym]=true; test(nxtlev, fsys, 6); } else { error(5);//漏掉分号 } } memcpy(nxtlev, statbegsys, sizeof(bool)*symnum); nxtlev[ident]=true; //nxtlev[period]=true; test(nxtlev, declbegsys, 7); } while(inset(sym, declbegsys));//直到没有声明符号 code[table[tx0].addr].a = cx;//开始生成当前过程代码 table[tx0].addr = cx;//当前过程代码地址 table[tx0].size = dx;//dx为当前过程数据的size cx0 = cx; gen(INT, 0, dx);//生成分配内存代码 //输出符号表 for(i = 1; i <= tx; i++) { switch(table[i].kind) { case constant: printf("%d const %s", i, table[i].name); printf("val=%d\n", table[i].val); fprintf(ft, "%d const %s", i, table[i].name); fprintf(ft, "val=%d\n", table[i].val); break; case variable: printf("%d var %s", i, table[i].name); printf("lev=%d addr=%d\n", table[i].level, table[i].addr); fprintf(ft, "%d var %s", i, table[i].name); fprintf(ft, "lev=%d addr=%d\n", table[i].level, table[i].addr); break; case procedure: printf("%d proc %s", i, table[i].name); printf("lev=%d addr=%d size=%d\n", table[i].level,table[i].addr, table[i].size); fprintf(ft, "%d proc %s", i, table[i].name); fprintf(ft, "lev=%d adr=%d size=%d \n", table[i].level,table[i].addr, table[i].size); break; } } printf("\n"); fprintf(ft, "\n"); //语句后跟分号或end memcpy(nxtlev, fsys, sizeof(bool)* symnum);//每个后跟符号集和都包含上层后跟符号集和,以便补救 nxtlev[semicolon] = true; nxtlev[endsym] = true; statement(nxtlev, &tx, lev); gen(OPR, 0, 0); //每个过程出口都要使用的释放数据段命令 memset(nxtlev, 0, sizeof(bool)* symnum); //分程序没有补救集合 test(fsys, nxtlev, 8);//检测后跟符号正确性 listcode(cx0);//输出代码 } //登录符号表 void enter (enum object k, int *ptx, int lev, int *pdx) { (*ptx)++; strcpy(table[(*ptx)].name, id);//符号表记录标识符的名字 table[(*ptx)].kind = k; switch(k) { case constant://常量 if (num > AMAX) { error(31);//过界报错 num = 0; } table[(*ptx)].val = num;//记录常数值 break; case variable://变量 table[(*ptx)].level = lev; table[(*ptx)].addr = (*pdx); (*pdx)++; break; case procedure://过程 table[(*ptx)].level = lev; break; } } //查找标识符在符号表的位置 int position(char* idt, int tx) { int i; strcpy(table[0].name, idt); i = tx; while(strcmp(table[i].name, idt) != 0) { i--; } return i; } //常量定义处理 void constdeclaration(int* ptx, int lev,int* pdx) { if(sym == ident) { getsym(); if((sym == eql) || (sym == becomes)) { if(sym == becomes) { error(1);//应该是=而不是:= } getsym(); if(sym == number) { enter(constant, ptx, lev, pdx);//填写符号表 getsym(); } else { error(2);//=后应为数 } } else { error(3);//标识符后应为= } } else { error(4);//const后应为标识符 } } //变量声明处理 void vardeclaration(int* ptx ,int lev, int* pdx) { if(sym == ident) { enter(variable, ptx, lev, pdx);//填写符号表 getsym(); } else { error(4);//var后应为标识符 } } //列出P-code指令清单 void listcode(int cx0) { int i; printf("\n"); for(i=cx0; i<cx; i++) { printf("%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l,code[i].a); fprintf(fv,"%d %s %d %d\n", i, mnemonic[code[i].f], code[i].l, code[i].a); } } //语句部分分析处理 void statement(bool* fsys, int * ptx, int lev) { int i, cx1, cx2; bool nxtlev[symnum]; if(sym == ident)//按照赋值语句处理 { i = position(id, *ptx);//查找标识符在符号表中的位置 if(i == 0) { error(11);//标识符未说明 } else { if((table[i].kind != variable)) { error(12);//不可向常量或过程赋值 i = 0; } else { getsym(); if(sym == becomes) { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); expression(nxtlev, ptx, lev); if(i != 0) { gen(STO, lev-table[i].level, table[i].addr); } } else { error(13);//应为赋值运算符:= } } } } else { if(sym == readsym)//按照read语句处理 { getsym(); if(sym != lparen) { error(40);//应为左括号 } else { do{ getsym(); if(sym == ident) { i = position(id, *ptx);//查找要读的变量 } else { i = 0; } if(i == 0) { error(35);//read括号中标识符未声明 } else { gen(OPR, 0, 15);//生成输入指令 gen(STO, lev-table[i]. level, table[i].addr);//将栈顶内容存到变量中 } getsym(); }while(sym == comma);//读多个变量 } if(sym!=rparen) { error(33);//应为右括号 while(!inset(sym, fsys))//出错补救,直到收到上层函数的后跟符号 { getsym(); } } else { getsym(); } } else { if(sym==writesym)//按照write语句处理 { getsym(); if(sym != lparen) { error(40);//应为左括号 } else { do{ getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[rparen] = true; nxtlev[comma] = true;//write后符号为)或, expression(nxtlev, ptx, lev);//调用表达式处理 gen(OPR, 0, 13);//生成输出指令,输出栈顶的值 gen(OPR, 0, 14);//换行 }while(sym == comma);//输出多个 if(sym != rparen) { error(33);//应为右括号 } else { getsym(); } } } else { if(sym == callsym)//按照call语句处理 { getsym(); if(sym != ident) { error(14);//call后应为标识符 } else { i=position(id, *ptx); if(i == 0) { error(11); //过程未声明 } else { if(table[i].kind == procedure) { gen(CAL, lev-table[i].level, table[i].addr);//生成call指令 } else { error(15);//不可调用常量或变量 } } getsym(); } } else { if(sym == ifsym)//按照if语句处理 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[thensym] = true; nxtlev[dosym] = true;//if后符号为then或do condition(nxtlev, ptx, lev);//调用条件处理 if(sym == thensym) { getsym(); } else { error(16);//应为then } cx1 = cx;//当前指令地址 gen(JPC, 0, 0);//生成条件跳转指令 statement(fsys, ptx, lev);//处理then下面的语句 if(sym==elsesym)//处理else语句 { getsym(); cx2 = cx; code[cx1].a=cx+1;//cx+1为then语句执行后的else语句的位置 gen(JMP, 0, 0); statement(fsys, ptx, lev); code[cx2].a = cx;//cx为else后语句执行完的位置 } else { code[cx1].a = cx;//cx为then后面语句执行 完的位置,它正是前面未定的跳转地址*/ } } else { if(sym==beginsym)//按照复合语句处理 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[semicolon]=true; nxtlev[endsym]=true;//begin后符号为:或end statement(nxtlev, ptx, lev);//处理begin和end之间的语句 while((inset(sym, statbegsys)) || (sym == semicolon)) { if(sym = semicolon) { getsym(); } else { error(10);//语句之间没有分号 } statement(nxtlev, ptx, lev); }//循环处理 if(sym == endsym) { getsym(); } else { error(17);//应为分号或end } } else { if(sym == whilesym)//按照while语句处理 { cx1 = cx;//判断条件操作位置 getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[dosym]=true;//while后符号为do condition(nxtlev, ptx, lev);//调用条件处理 cx2 = cx;//循环体的结束的下一个位置 gen(JPC, 0, 0);//生成条件跳转 if(sym == dosym) { getsym(); } else { error(18);//应为do } statement(fsys, ptx, lev); gen(JMP, 0, cx1);//重新判断条件 code[cx2].a = cx; } } } } } } } memset(nxtlev, 0, sizeof(bool)* symnum);//语句结束无补救集合 test(fsys, nxtlev, 19);//检测语句结束的正确性 } //表达式分析处理 void expression(bool* fsys, int* ptx, int lev) { enum symbol sign;//正负号 bool nxtlev[symnum]; if((sym == pluss) || (sym == minuss))//开头的正负号 { sign = sym; getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 if(sign == minuss) { gen(OPR, 0, 1);//如果开头为负号,生成取负指令 } } else { memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 } while((sym == pluss) || (sym == minuss)) { sign = sym; getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[pluss] = true; nxtlev[minuss] = true; term(nxtlev, ptx, lev);//对项进行处理 if(sign == pluss) { gen(OPR, 0, 2);//加法 } else { gen(OPR, 0, 3);//减法 } } } //项分析处理 void term(bool*fsys, int *ptx, int lev) { enum symbol sign;//乘除法符号 bool nxtlev[symnum]; memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[times] = true; nxtlev[slash] = true; factor(nxtlev, ptx, lev);//对因子进行处理 while((sym == times) || (sym == slash)) { sign = sym; getsym(); factor(nxtlev, ptx, lev); if(sign == times) { gen(OPR, 0, 4);//乘法 } else { gen(OPR, 0, 5);//除法 } } } //因子分析处理 void factor(bool* fsys, int* ptx, int lev) { int i; bool nxtlev[symnum]; test(facbegsys, fsys, 24);//检测因子开始符号 while(inset(sym, facbegsys))//循环处理因子 { if(sym == ident)//因子为常量或者变量 { i = position(id, *ptx);//查找标识符位置 if(i == 0) { error(11);//未声明标识符 } else { switch(table[i].kind)//不同形式标识符 { case constant: gen(LIT, 0, table[i].val);//常量入栈 break; case variable: gen(LOD, lev-table[i].level, table[i].addr);//变量入栈 break; case procedure: error(21);//表达式内不能有过程标识符 break; } } getsym(); } else { if(sym == number) //因子为数字的时候 { if(num > AMAX) { error(31);//过界报错 num = 0; } gen(LIT, 0, num); getsym(); } else { if(sym == lparen)//因子为表达式的时候 { getsym(); memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[rparen] = true; expression(nxtlev, ptx, lev); if(sym == rparen) { getsym(); } else { error(22);//没有右括号 } } //test(fsys, facbegsys, 23);//一个因子处理完毕,遇到的单词应在fsys集合中 ,如果不是,报错并找到下一个因子的开始,使语法分析继续运行 } } memset(nxtlev, 0, sizeof(bool) * symnum); nxtlev[lparen] = true; test(fsys, facbegsys, 23);//一个因子处理完毕,遇到的单词应在fsys集合中 ,如果不是,报错并找到下一个因子的开始,使语法分析继续运行 } } //条件分析处理 void condition(bool* fsys, int* ptx, int lev) { enum symbol sign; bool nxtlev[symnum]; if(sym == oddsym) { getsym(); expression(fsys, ptx, lev); gen(OPR, 0, 6); } else//处理分析逻辑表达式 { memcpy(nxtlev, fsys, sizeof(bool)* symnum); nxtlev[eql]=true; nxtlev[neq]=true; nxtlev[lss]=true; nxtlev[leq]=true; nxtlev[gtr]=true; nxtlev[geq]=true; expression(nxtlev, ptx, lev); if((sym!=eql)&&(sym!=neq)&&(sym!=lss)&&(sym!=leq)&&(sym!=gtr)&&(sym!=geq)) { error(20);//应为关系运算符 } else { sign = sym; getsym(); expression(fsys, ptx, lev); switch(sign) { case eql: gen(OPR, 0, 7); break; case neq: gen(OPR, 0, 8); break; case lss: gen(OPR, 0, 9); break; case gtr: gen(OPR, 0, 10); break; case leq: gen(OPR, 0, 11); break; case geq: gen(OPR, 0, 12); break; } } } } //P-code解释执行程序 void interpret() { int p = 0;//指令指针 int b = 1;//指令基址 int t = 0;//栈顶指针 struct instruction i;//存放当前指令 int s[stacksize];//栈 cout<<"执行PL0:"<<endl; fprintf(fr, "执行PL0:\n"); s[0] = 0; s[1] = 0; s[2] = 0; s[3] = 0; do{ i = code[p];//读当前指令 p++; switch(i.f) { case LIT://将a的值取到栈顶 t++; s[t]=i.a; break; case OPR://数字逻辑运算 switch(i.a) { case 0://函数调用后返回 t = b - 1; p = s[t+3]; b = s[t+2]; break; case 1://取反 s[t] = -s[t]; break; case 2://栈顶两个元素相加 t--; s[t] = s[t] + s[t+1]; break; case 3://栈顶两个元素相减 t--; s[t] = s[t] - s[t+1]; break; case 4://栈顶两个元素相乘 t--; s[t] = s[t] * s[t+1]; break; case 5://栈顶两个元素相除 t--; s[t] = s[t] / s[t+1]; break; case 6://栈顶元素奇偶判断 s[t] = s[t] % 2; break; case 7://栈顶两个元素是否相等 t--; s[t] = (s[t] == s[t+1]); break; case 8://栈顶两个元素是否不等 t--; s[t] = (s[t] != s[t+1]); break; case 9://小于 t--; s[t] = (s[t] < s[t+1]); break; case 10://大于 t--; s[t] = (s[t] > s[t+1]); break; case 11://小于等于 t--; s[t] = (s[t] <= s[t+1]); break; case 12://大于等于 t--; s[t] = (s[t] >= s[t+1]); break; case 13://输出栈顶值 printf("%d", s[t]); fprintf(fr, "%d", s[t]); t--; break; case 14://输出换行符 printf("\n"); fprintf(fr, "\n"); break; case 15://读入 t++; printf("输入:"); fprintf(fr, "输入:"); scanf("%d", &(s[t])); fprintf(fr, "%d\n", s[t]); break; } break; case LOD://取相对当前过程的数据基地址为a的内存的值到栈顶 t++; s[t] = s[base(i.l, s, b) + i.a]; break; case STO://栈顶的值存到相对当前过程的数据基地址为a的内存 s[base(i.l, s, b) + i.a] = s[t]; t--; break; case CAL://调用子程序 s[t+1] = base(i.l, s,b); s[t+2] = b; s[t+3] = p; b = t + 1; p = i.a; break; case INT://分配内存 t += i.a; break; case JMP://直接跳转 p=i.a; break; case JPC://条件跳转 if(s[t] == 0) { p = i.a; } t--; break; } }while(p != 0); printf("PL0结束\n"); fprintf(fr, "PL0结束\n"); } //通过静态链求出数据区基地址 int base(int l,int* s, int b) { int b1; b1 = b; while(l > 0) { b1 = s[b1]; l--; } return b1; } int main() { bool nxtlev[symnum]; cout<<"*****PL0编译器*****"<<endl; cout<<"输出文件中,fv为虚拟机代码,fo为源代码,fr为运行结果,ft为符号表"<<endl; cout<<"请输入pl0文件:"<<endl; scanf("%s", fname); fin = fopen(fname, "r"); if(fin == NULL) { cout<<"无法打开文件!" <<endl; exit(1); } if(fgetc(fin) == EOF) { cout<<"文件为空!" <<endl; exit(1); } rewind(fin); fo = fopen("fo.txt", "w"); init(); err = 0; cc = ll = cx = 0; ch=' '; getsym(); fv = fopen("fv.txt", "w"); ft = fopen("ft.txt", "w"); addset(nxtlev, declbegsys, statbegsys, symnum); nxtlev[period]=true; block(0, 0, nxtlev);//调用编译程序 fclose(fv); fclose(fo); fclose(ft); fclose(fin); printf("\n"); if(sym != period) { error(9);//应为句号 } if(err == 0) { cout<<"*****************************"<<endl; fr = fopen("fr.txt", "w"); interpret(); fclose(fr); } else { printf("程序出错!"); } fclose(fin); printf("\n"); getchar(); }
诡异的问题,求帮忙!
好像是包含头文件的时候出现了问题,但是半天没有找到。请大家看一下。 总共三个文件:main.cpp md5.cpp md5.h main.cpp: ``` #include<iostream> #include<stdio.h> #include<string> #include"md5.h" using namespace std; int main(){ char filename[200]; //文件名 while(1){ printf("Input file:"); gets(filename); //用get函数,避免scanf以空格分割数据, if (filename[0]==34) filename[strlen(filename)-1]=0,strcpy(filename,filename+1); //支持文件拖曳,但会多出双引号,这里是处理多余的双引号 if (!strcmp(filename,"exit")) exit(0); //输入exit退出 string s=md5(filename); } } ``` md5.h: ``` #include"md5.cpp" string md5(char[] filename); ``` md5.cpp: ``` #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) #define RL(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) //x向左循环移y位 #define PP(x) (x<<24)|((x<<8)&0xff0000)|((x>>8)&0xff00)|(x>>24) //将x高低位互换,例如PP(aabbccdd)=ddccbbaa #define FF(a, b, c, d, x, s, ac) a = b + (RL((a + F(b,c,d) + x + ac),s)) #define GG(a, b, c, d, x, s, ac) a = b + (RL((a + G(b,c,d) + x + ac),s)) #define HH(a, b, c, d, x, s, ac) a = b + (RL((a + H(b,c,d) + x + ac),s)) #define II(a, b, c, d, x, s, ac) a = b + (RL((a + I(b,c,d) + x + ac),s)) unsigned A,B,C,D,a,b,c,d,i,len,flen[2],x[16]; //i临时变量,len文件长,flen[2]为64位二进制表示的文件初始长度 FILE *fp; void amd5(){ //MD5核心算法,供64轮 a=A,b=B,c=C,d=D; /**//* Round 1 */ FF (a, b, c, d, x[ 0], 7, 0xd76aa478); /**//* 1 */ FF (d, a, b, c, x[ 1], 12, 0xe8c7b756); /**//* 2 */ FF (c, d, a, b, x[ 2], 17, 0x242070db); /**//* 3 */ FF (b, c, d, a, x[ 3], 22, 0xc1bdceee); /**//* 4 */ FF (a, b, c, d, x[ 4], 7, 0xf57c0faf); /**//* 5 */ FF (d, a, b, c, x[ 5], 12, 0x4787c62a); /**//* 6 */ FF (c, d, a, b, x[ 6], 17, 0xa8304613); /**//* 7 */ FF (b, c, d, a, x[ 7], 22, 0xfd469501); /**//* 8 */ FF (a, b, c, d, x[ 8], 7, 0x698098d8); /**//* 9 */ FF (d, a, b, c, x[ 9], 12, 0x8b44f7af); /**//* 10 */ FF (c, d, a, b, x[10], 17, 0xffff5bb1); /**//* 11 */ FF (b, c, d, a, x[11], 22, 0x895cd7be); /**//* 12 */ FF (a, b, c, d, x[12], 7, 0x6b901122); /**//* 13 */ FF (d, a, b, c, x[13], 12, 0xfd987193); /**//* 14 */ FF (c, d, a, b, x[14], 17, 0xa679438e); /**//* 15 */ FF (b, c, d, a, x[15], 22, 0x49b40821); /**//* 16 */ /**//* Round 2 */ GG (a, b, c, d, x[ 1], 5, 0xf61e2562); /**//* 17 */ GG (d, a, b, c, x[ 6], 9, 0xc040b340); /**//* 18 */ GG (c, d, a, b, x[11], 14, 0x265e5a51); /**//* 19 */ GG (b, c, d, a, x[ 0], 20, 0xe9b6c7aa); /**//* 20 */ GG (a, b, c, d, x[ 5], 5, 0xd62f105d); /**//* 21 */ GG (d, a, b, c, x[10], 9, 0x02441453); /**//* 22 */ GG (c, d, a, b, x[15], 14, 0xd8a1e681); /**//* 23 */ GG (b, c, d, a, x[ 4], 20, 0xe7d3fbc8); /**//* 24 */ GG (a, b, c, d, x[ 9], 5, 0x21e1cde6); /**//* 25 */ GG (d, a, b, c, x[14], 9, 0xc33707d6); /**//* 26 */ GG (c, d, a, b, x[ 3], 14, 0xf4d50d87); /**//* 27 */ GG (b, c, d, a, x[ 8], 20, 0x455a14ed); /**//* 28 */ GG (a, b, c, d, x[13], 5, 0xa9e3e905); /**//* 29 */ GG (d, a, b, c, x[ 2], 9, 0xfcefa3f8); /**//* 30 */ GG (c, d, a, b, x[ 7], 14, 0x676f02d9); /**//* 31 */ GG (b, c, d, a, x[12], 20, 0x8d2a4c8a); /**//* 32 */ /**//* Round 3 */ HH (a, b, c, d, x[ 5], 4, 0xfffa3942); /**//* 33 */ HH (d, a, b, c, x[ 8], 11, 0x8771f681); /**//* 34 */ HH (c, d, a, b, x[11], 16, 0x6d9d6122); /**//* 35 */ HH (b, c, d, a, x[14], 23, 0xfde5380c); /**//* 36 */ HH (a, b, c, d, x[ 1], 4, 0xa4beea44); /**//* 37 */ HH (d, a, b, c, x[ 4], 11, 0x4bdecfa9); /**//* 38 */ HH (c, d, a, b, x[ 7], 16, 0xf6bb4b60); /**//* 39 */ HH (b, c, d, a, x[10], 23, 0xbebfbc70); /**//* 40 */ HH (a, b, c, d, x[13], 4, 0x289b7ec6); /**//* 41 */ HH (d, a, b, c, x[ 0], 11, 0xeaa127fa); /**//* 42 */ HH (c, d, a, b, x[ 3], 16, 0xd4ef3085); /**//* 43 */ HH (b, c, d, a, x[ 6], 23, 0x04881d05); /**//* 44 */ HH (a, b, c, d, x[ 9], 4, 0xd9d4d039); /**//* 45 */ HH (d, a, b, c, x[12], 11, 0xe6db99e5); /**//* 46 */ HH (c, d, a, b, x[15], 16, 0x1fa27cf8); /**//* 47 */ HH (b, c, d, a, x[ 2], 23, 0xc4ac5665); /**//* 48 */ /**//* Round 4 */ II (a, b, c, d, x[ 0], 6, 0xf4292244); /**//* 49 */ II (d, a, b, c, x[ 7], 10, 0x432aff97); /**//* 50 */ II (c, d, a, b, x[14], 15, 0xab9423a7); /**//* 51 */ II (b, c, d, a, x[ 5], 21, 0xfc93a039); /**//* 52 */ II (a, b, c, d, x[12], 6, 0x655b59c3); /**//* 53 */ II (d, a, b, c, x[ 3], 10, 0x8f0ccc92); /**//* 54 */ II (c, d, a, b, x[10], 15, 0xffeff47d); /**//* 55 */ II (b, c, d, a, x[ 1], 21, 0x85845dd1); /**//* 56 */ II (a, b, c, d, x[ 8], 6, 0x6fa87e4f); /**//* 57 */ II (d, a, b, c, x[15], 10, 0xfe2ce6e0); /**//* 58 */ II (c, d, a, b, x[ 6], 15, 0xa3014314); /**//* 59 */ II (b, c, d, a, x[13], 21, 0x4e0811a1); /**//* 60 */ II (a, b, c, d, x[ 4], 6, 0xf7537e82); /**//* 61 */ II (d, a, b, c, x[11], 10, 0xbd3af235); /**//* 62 */ II (c, d, a, b, x[ 2], 15, 0x2ad7d2bb); /**//* 63 */ II (b, c, d, a, x[ 9], 21, 0xeb86d391); /**//* 64 */ A += a; B += b; C += c; D += d; } string md5(char[] filename){ if (!(fp=fopen(filename,"rb"))) {printf("Can not open this file!\n");} //以二进制打开文件 fseek(fp, 0, SEEK_END); //文件指针转到文件末尾 if((len=ftell(fp))==-1) {printf("Sorry! Can not calculate files which larger than 2 GB!\n");fclose(fp);} //ftell函数返回long,最大为2GB,超出返回-1 rewind(fp); //文件指针复位到文件头 A=0x67452301,B=0xefcdab89,C=0x98badcfe,D=0x10325476; //初始化链接变量 flen[1]=len/0x20000000; //flen单位是bit flen[0]=(len%0x20000000)*8; memset(x,0,64); //初始化x数组为0 fread(&x,4,16,fp); //以4字节为一组,读取16组数据 for(i=0;i<len/64;i++){ //循环运算直至文件结束 amd5(); memset(x,0,64); fread(&x,4,16,fp); } ((char*)x)[len%64]=128; //文件结束补1,补0操作,128二进制即10000000 if(len%64>55) amd5(),memset(x,0,64); memcpy(x+14,flen,8); //文件末尾加入原文件的bit长度 amd5(); fclose(fp); //printf("MD5 Code:%08x%08x%08x%08x\n",PP(A),PP(B),PP(C),PP(D)); 高低位逆反输出 char str1[8]; sprintf(str1,"%08x",PP(A)); char *s1=str1; char str2[8]; sprintf(str2,"%08x",PP(B)); char *s2=str2; char str3[8]; sprintf(str3,"%08x",PP(C)); char *s3=str3; char str4[8]; sprintf(str4,"%08x",PP(D)); char *s4=str4; strcat(str1,str2); strcat(str1,str3); strcat(str1,str4); //cout<<str1<<endl; string s=str1; return s; } ``` 问题: f:\md5.cpp(98) : error C2146: syntax error : missing ';' before identifier 'md5' f:\md5.cpp(98) : error C2501: 'string' : missing storage-class or type specifiers f:\md5.cpp(98) : fatal error C1004: unexpected end of file found
网络编程Create socket failed!
要求是接收解析ICMPecho请求报文, 用命令行PraseICMP.exe log_file.txt 的形式执行。 ``` // ParsePacket.cpp : 定义控制台应用程序的入口点。 // //#define _WINSOCK_DEPRECATED_NO_WARNINGS #include <stdio.h> #include <winsock2.h> #include <ws2tcpip.h> #pragma comment(lib,"ws2_32.lib") #define _WINSOCK_DEPRECATED_NO_WARNINGS /* ICMP 首部 -- RFC 792 */ struct icmp_hdr { unsigned char type; /* 类型 */ unsigned char code; /* 代码 */ unsigned short checksum; /* 校验和 */ unsigned short id; /* 标识符 */ unsigned short seq; /* 序列号 */ /* 这之后的不是标准 ICMP 首部, 用于记录时间 */ unsigned long timestamp; }; //定义IP头部结构 typedef struct _IP_HEADER { union { BYTE Version; //版本(前4位) BYTE HdrLen; //IP头部长度(后4位) }; BYTE ServiceType; //服务类型 WORD TotalLen; //总长度 WORD ID; //标识 union { WORD Flags; //标志u(前3位) WORD FragOff; //分段偏移(后13位) }; BYTE TimeToLive; //生命期 BYTE Protocol; //协议 WORD HdrChksum; //头校验和 DWORD SrcAddr; //源地址 DWORD DstAddr; //目的地址 BYTE Options; //选项 }IP_HEADER; #define IO_RCVALL _WSAIOW(IOC_VENDOR,1) #define BUFFER_SIZE 65535 //解析IP包的头部长度 void getIHL(BYTE b, BYTE &length) { length = (b & 0x0f) * 4; } //解析ICMP类型 char* geticmptype(char type) { switch (type) { case 0: return "查询报文----应答"; case 3: return "差错报告报文----目的不可达"; case 4: return "控制报文----源抑制"; case 5: return "控制报文----路由重定向"; case 8: return "查询报文----回送请求"; case 10: return "查询报文----路由器请求"; case 11: return "差错报告报文----超时"; case 12: return "差错报告报文----参数出错"; case 13: return "查询报文----时间戳请求"; case 14: return "查询报文----时间戳应答"; case 17: return "查询报文----掩码请求"; case 18: return "查询报文----掩码应答"; case 19: return "差错报告报文----通告"; default: return "Unknown"; } } void ipparse(FILE* file, char* buffer) { int i,j; int iphead; IP_HEADER ip = *(IP_HEADER*)buffer; iphead=(ip.Version & 0x0f)<<2; icmp_hdr icmp_hd = *(icmp_hdr*)(buffer+iphead); fseek(file, 0, SEEK_END); if(ip.Protocol == 1 && icmp_hd.type==8) { printf("\n------ICMP eacho请求报文前50B------\n"); for(i=0;i<5;i++) { for(j=0;j<10;j++) { printf("%x%x ",(unsigned char)buffer[10*i+j]>>4,buffer[10*i+j]&0x0f); } printf("\n"); } fprintf(file, "------解析ICMP eacho请求报文------\n"); //解析IP包的源IP地址 fprintf(file, "SrcAddr: %s\n", inet_ntoa(*(in_addr*)&ip.SrcAddr)); //解析IP包的目的IP地址 fprintf(file, "DstAdrr: %s\n", inet_ntoa(*(in_addr*)&ip.DstAddr)); //解析ICMP类型 fprintf(file, "Type: %s\n",geticmptype(icmp_hd.type)); //解析ICMP代码 fprintf(file, "Code: %d\n",icmp_hd.code); //解析ICMP校验和 fprintf(file, "Sum: 0x%x\n",ntohs((unsigned int)icmp_hd.checksum)); //解析ICMP标识符 fprintf(file, "ID: %d\n",ntohs(icmp_hd.id)); //解析ICMP序列号 fprintf(file, "Seq: %d\n",ntohs(icmp_hd.seq)); } } int main(int argc, char* argv[]) { //检查输入的命令格式 if (argc != 2) { printf("Please input command:ParseICMP.exe log_file.txt\n"); return 0; } //打开输出日志文件 FILE* file; if ((file = fopen(argv[1], "wb+")) == NULL) { printf("Fail to open file %s!", argv[1]); return 0; } //初始化Socket环境 WSADATA wsData; if (WSAStartup(MAKEWORD(2, 2), &wsData) != 0) { printf("WSAStartup failed!"); return 0; } //建立原始Socket SOCKET sock; if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_IP)) == INVALID_SOCKET) { printf("Create socket failed!"); return 0; } //设置IP头部操作选项,flag设置为ture BOOL flag = true; if (setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag)) == SOCKET_ERROR) { printf("Setsockopt failed!"); return 0; } //获取本地主机名 char hostName[128]; if (gethostname(hostName, 100) == SOCKET_ERROR) { printf("Gethostbyname failed!"); return 0; } //获取本地主机IP地址 hostent* pHostIP; if ((pHostIP = gethostbyname(hostName)) == NULL) { printf("Gethostbyname failed!"); return 0; } //填充SOCKADDR_IN结构 sockaddr_in addr_in, cliadd; addr_in.sin_addr = *(in_addr*)pHostIP->h_addr_list[0]; addr_in.sin_family = AF_INET; addr_in.sin_port = htons(5050); //把原始Socket绑定到本地网卡 if (bind(sock, (PSOCKADDR)&addr_in, sizeof(addr_in)) == SOCKET_ERROR) { printf("Bind failed!"); return 0; } int ilen = sizeof(cliadd); //设置SOCK_RAW为SIO_RCVALL,接收所有数据包 DWORD dwValue = 1; DWORD dwBufferLen[10]; DWORD dwBufferInLen = 1; DWORD dwBytesReturned = 0; if (WSAIoctl(sock, IO_RCVALL, &dwBufferInLen, sizeof(dwBufferInLen), &dwBufferLen, sizeof(dwBufferLen), &dwBytesReturned, NULL, NULL) == SOCKET_ERROR) { printf("Ioctlsocket failed!"); return 0; } //监听经过本机的IP包 char buffer[BUFFER_SIZE]; printf("Listening on local host...\n"); while (true) { // int size = recv(sock, buffer, BUFFER_SIZE, 0); int size = recvfrom(sock, buffer, BUFFER_SIZE, 0 , (struct sockaddr*)&cliadd, &ilen); if (size > 0) { ipparse(stdout, buffer); //ipparse(file, buffer); } } fclose(file); return 0; } ```
初学C语言,折腾了好久,请大大们指导下。结贴
刚申请账号,原来都是看各位老师回答,是不是刚申请的没有积分或者C币奖赏 希望老师们能指点一二 谢谢 程序用途 HDDのSMART情報が格納されたバイナリファイル(HDD_SMART_INFO.dat)をキャラクタに変換後、csvファイルとして出力する CSVをもとにデータを解析し、故障しそうなHDDを事前に見つける際に使用するツール。 程序功能 cmd命令 下输入 不指定功能情况下 .*dat test.csv 当前路径全dat文件 读取 test.csv输出 test.dat test.csv 单一dat文件指定 读取 test.csv输出 功能指定情况下 -OR .*dat test.csv 当前路径全dat文件 读取 按功能指定 test.csv输出 -OR test.dat test.csv 单一dat文件指定 读取 按功能指定test.csv输出 根据当前路径 检索路径下所有.dat文件 包括路径下文件夹内存在.dat文件的情况下检索到底 到没有文件夹位为止获取所有dat文件 .dat文件用专门软件打开后内容大体为 01 0B 00 64 64 10 00 00 00 00 00 00 02 05 00 88 88 36 5E 00 00 00 00 00 . . . 以第一行为例 01 为 AttributeID uchar 1字节 0B 00 为AttributeFlag ushort 2字节 64 为CurrentValue uchar 1字节 64 为WorstValue uchar 1字节 10 为ThresholdValue uchar 1字节 00 00 00 00 00 00 为RawValue uchar[6] 6字节 三种功能设定 -OR Raw数据输出 -OV Value数据输出 -RC Raw数据反序输出 再次谢谢 ``` ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // // SMART変換ツール : // HDDのSMART情報が格納されたバイナリファイル(HDD_SMART_INFO.dat)を // キャラクタに変換後、csvファイルとして出力する // CSVをもとにデータを解析し、故障しそうなHDDを事前に見つける際に使用するツール // ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #include <stdafx.h> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<Windows.h> #include<malloc.h> ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //オプション // デフォルトでは //   -OR:Rawデータだけ出力 // -OV:Valueだけ出力 //    -RC:Rawデータを以下のように並び替えて出力 // 0123456789AB ⇒ AB8967452301 /***オプションの設定***/ #define S_OR "-OR" #define S_OV "-OV" #define S_RC "-RC" #define OUTPUT_ORDATA 1 #define OUTPUT_OVDATA 2 #define OUTPUT_RCDATA 3 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /***SMARTデータ最大数***/ #define SMART_DATA_MAX 64 #define NORMAL_END 0 #define ABNORMAL_END 1 /***構造体の定義***/ struct SMART_INFO { unsigned char AttributeID; unsigned short AttributeFlag; unsigned char CurrentValue; unsigned char WorstValue; unsigned char ThresholdValue; unsigned char RawValue[6]; }; struct SMART_ALL_DATA { SMART_INFO stSmartInfo[SMART_DATA_MAX]; char FileNames[_MAX_PATH]; }; /***関数宣言***/ int GetParamData( int argc,_TCHAR* argv[],char *cpOutFileName, char *cpFileName,char *cpSearchPath ,int *iOption ); int FileSearch( int *iCount , char*cpSearchPath, SMART_ALL_DATA *stSmartAllInfo); int File_r( char *cpSearchPath, SMART_ALL_DATA *stSmartAllInfo, int iFileNo ); int FileOut( char *cpOutFileName, SMART_ALL_DATA *stSmartInfo,int iCount, int iOption ); //////////////////////////////////////////////////////////////////////////////////////////////////////// // 関数名:main // 機能 :メイン処理 // 引数 :argc : 引数の個数 // argv[] : 引数の値(.datファイル名と.csvファイル名を取得用) // // //////////////////////////////////////////////////////////////////////////////////////////////////////// int _tmain( int argc,_TCHAR* argv[] ) { //.datファイル複数の場合、検索パス用 char Search_Path[_MAX_PATH]={0}; //.datファイルをオープンの場合、フルパス+.datファイル名用 char Filename[_MAX_PATH]={0}; //出力csvファイル名を格納用 char cOutFileName[_MAX_PATH]={0}; //オプション格納用 int iOption=0; //.datファイル個数を記録用 int iCount=0; //構造体を宣言 SMART_ALL_DATA *stSmartAllData = NULL; //関数の真偽判断 int iResult = FALSE; //引数の判断   if(argc<3) { printf( "Input Error.\n" ); printf( "Please input some words such as \"-Option FileName.dat FileName.csv\".\n" ); return ABNORMAL_END; } //引数解析 iResult = GetParamData( argc, argv, cOutFileName, Filename,Search_Path, &iOption ); if( iResult!= 0 ) { //単一ファイル指定用 char *cpFileDat = ".dat"; //複数ファイル指定用 char *cp_AllDat = "*.dat"; //if( 引数のパスに'*'があるか? ) if ( strstr( Filename,cp_AllDat ) != NULL) { // '*'がある場合 // ファイル検索(個数を取得処理) FileSearch( &iCount,Search_Path ,NULL ); if (iCount == 0 ) { printf("Can not search any DatFiles.\n"); return ABNORMAL_END; } // 構造体を定義 stSmartAllData = ( SMART_ALL_DATA* )malloc( iCount * sizeof(SMART_ALL_DATA) ); //メモリ確保 if( stSmartAllData == NULL ) { printf( "Memory allocation failed.\n" ); return ABNORMAL_END; } //初期化 memset( stSmartAllData, '\0' , ( iCount * sizeof(SMART_ALL_DATA ) ) ); // ファイル検索処理(リード処理を行う) iCount = 0; iResult = FileSearch( &iCount, Search_Path ,stSmartAllData ); } else { if ( strstr( Filename,cpFileDat ) != NULL) { // '*'がない場合 // ファイル個数は1個 iCount = 1; // 構造体を定義 stSmartAllData = ( SMART_ALL_DATA* )malloc( iCount * sizeof( SMART_ALL_DATA ) ); //メモリ確保 if( stSmartAllData == NULL ) { printf( "Memory application failed.\n" ); return ABNORMAL_END; } //初期化 memset( stSmartAllData, '\0' , ( iCount * sizeof(SMART_ALL_DATA ) ) ); iCount = 0; //リード処理を実行 iResult = File_r( Filename, stSmartAllData, iCount++ ); //ファイルオープン失敗の場合 ファイル名を出力 if( iResult == FALSE ) { printf( "Can not to open %s.\n" ,Filename); printf( "Please make sure the FileName and FullPath.\n"); } } //DATファイルではない場合 else { printf("Input Error.\n"); printf( "Please input some words such as \"-Option FileName.dat FileName.csv\".\n" ); return ABNORMAL_END; } } if( iResult== TRUE ) { //csvファイルを出力 FileOut( cOutFileName, stSmartAllData, iCount, iOption ); } //mallocを解放する。 free(stSmartAllData); } return NORMAL_END; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // 関数名 : GetParamData // 機能 : 引数の解析処理 // 引数 : argc : 引数の個数 // argv[] : 引数の値(.datファイル名と.csvファイル名を取得用) //  cpOutFileName : csvファイル名  // cpFileName : .datファイルをオープンの場合、フルパス+.datファイル名用 // cpSearchPath : .datファイル複数の場合、検索パス用 //  iOption : オプション格納用 //////////////////////////////////////////////////////////////////////////////////////////////////////// int GetParamData( int argc,_TCHAR* argv[], char *cpOutFileName,char *cpFileName, char*cpSearchPath ,int *iOption ) { //戻り値設定 int iResult = FALSE; //argv[Dat_Name]格納 && argv[Csv_Name]格納 int Dat_Name,Csv_Name; Dat_Name=(argc==3?1:2); Csv_Name=(argc==3?2:3); //取得の引数によって、オプションの判断 if(strcmp( argv[1], S_OR ) == 0) { //"-OR"を取得する場合 *iOption = OUTPUT_ORDATA; } else if(strcmp( argv[1], S_OV ) == 0) { //"-OV"を取得する場合 *iOption = OUTPUT_OVDATA; } else if(strcmp( argv[1], S_RC ) == 0) { //"-RC"を取得する場合 *iOption = OUTPUT_RCDATA; } //パス分解する用 char szPath[_MAX_PATH]; char szDrive[_MAX_DRIVE]; char szDir[_MAX_DIR]; char szFileName[_MAX_FNAME]; char szExt[_MAX_EXT]; DWORD dwRet; //初期化 memset( szPath, NULL, sizeof( szPath ) ); memset( szDrive, NULL, sizeof(szDrive ) ); memset( szDir, NULL, sizeof( szDir ) ); memset( szExt, NULL, sizeof( szExt ) ); dwRet = 0; //実行中のプロセスフルパスを取得する。 dwRet = GetModuleFileName(NULL, szPath, sizeof( szPath ) ); //エラー処理 if( dwRet == 0 ) { int Errorcode; Errorcode=GetLastError(); printf("Error code %d :Get CurrentDirecory Error.\n",Errorcode); return iResult; } //フルパス名を分割する _splitpath_s( szPath, szDrive, szDir, szFileName, szExt ); //.csvファイいるを取得し、cpOutFileNameに格納 memset( cpOutFileName, NULL, _MAX_PATH ); strcpy_s( cpOutFileName, _MAX_PATH, argv[Csv_Name] ); //検索パスを取得処理  strcat_s( cpSearchPath, _MAX_PATH, szDrive ); strcat_s( cpSearchPath, _MAX_PATH, szDir ); //.datファイルをオープンの場合、フルパス+.datファイル名用を取得処理 strcat_s( cpFileName, _MAX_PATH, szDrive ); strcat_s( cpFileName, _MAX_PATH, szDir ); strcat_s( cpFileName, _MAX_PATH, argv[Dat_Name] ); return TRUE; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // 関数名 : FileSearch // 機能 : .datファイル複数の場合、検索処理 // 引数 : iCount : ファイル個数記録用 // cpSearchPath : 検索パス // //  stSmartAllInfo : リードするデータを保存用  // // //////////////////////////////////////////////////////////////////////////////////////////////////////// int FileSearch( int *iCount,char *cpSearchPath,SMART_ALL_DATA *stSmartAllInfo ) { // 戻り値格納用 int iResult = FALSE; //検索パス用 char cppSearchPath[_MAX_PATH]={0}; //検索パスをコピー strcpy_s( cppSearchPath,cpSearchPath ); //API関数を呼び出し、検索処理する WIN32_FIND_DATA FindFileData; HANDLE hFind; strcat_s( cppSearchPath,_MAX_PATH,"\\*" ); hFind=FindFirstFile( cppSearchPath,&FindFileData ); if( INVALID_HANDLE_VALUE == hFind ) { return FALSE; } while( TRUE ) { if( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if( FindFileData.cFileName[0] != '.' ) { //フォルダは存在する場合 char szFile[_MAX_PATH] = {0}; strcpy_s( szFile,cpSearchPath ); strcat_s( szFile,"\\" ); strcat_s( szFile,FindFileData.cFileName ); //再帰する iResult = FileSearch( iCount,szFile,stSmartAllInfo ); } } else { //取得のファイ名 '.'以降の文字列を取得 cpstrdatに格納 char *cpstrdat=strrchr( FindFileData.cFileName,'.' ); //検索のファイル型の判断 .datファイルの場合 リード処理 if(strcmp( ".dat",cpstrdat) == 0 ) { if( stSmartAllInfo != NULL ) { char cppFiledatpath[_MAX_PATH] = {0}; strcpy_s( cppFiledatpath,cpSearchPath ); strcat_s( cppFiledatpath,"\\" ); strcat_s( cppFiledatpath,FindFileData.cFileName ); int iReadlost = FALSE; //リード処理を実行 iReadlost = File_r( cppFiledatpath, stSmartAllInfo, *iCount ); //***ファイルオープン失敗の場合 ファイル名を出力 if( iReadlost == FALSE ) { printf( "Can not to open %s.\n", FindFileData ); printf( "Please make sure the FileName and FullPath.\n"); } else { iResult = TRUE; } } //ファイル読み込み数を+1 *iCount = *iCount + 1; } } //ファイル内の場合、Break if( !FindNextFile( hFind, &FindFileData ) ) break; } return iResult; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // 関数名 : File_r // 機能 : オープンした.datファイルを読む込み処理 // 引数 : cpSearchPath : フルパス+.datファイル名用 // iFileNo : ファイル個数用 // //  stSmartAllInfo : リードするデータを保存用  // // //////////////////////////////////////////////////////////////////////////////////////////////////////// int File_r( char *cpSearchPath, SMART_ALL_DATA *stSmartAllInfo, int iFileNo ) { FILE *fp = NULL; //一ファイルリードループ用 int iDataCnt = 0; //ファイルオープン fopen_s( &fp,cpSearchPath,"rb" ); //エラー判断 if( fp == NULL ) { return FALSE; } //ファイル名を格納 strcpy_s( stSmartAllInfo[iFileNo].FileNames ,_MAX_PATH,cpSearchPath ); //ファイル終端までループ while( !feof(fp) ) { //AttributeID~RawValueまで、一行のデータを読み込む、ファイル終端までループ fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].AttributeID, 1, 1, fp ); fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].AttributeFlag, 1, 2, fp ); fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].CurrentValue, 1, 1, fp ); fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].WorstValue, 1, 1, fp ); fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].ThresholdValue, 1, 1, fp ); fread( &stSmartAllInfo[iFileNo].stSmartInfo[iDataCnt].RawValue, 1, 6, fp ); //行数記録 iDataCnt++; } fclose( fp ); return TRUE; } //////////////////////////////////////////////////////////////////////////////////////////////////////// // 関数名 : FileOut // 機能 : データを出力処理 // 引数 : cpOutFileName : 出力ファイル名用 // iCount : ファイル個数用 // iOption : オプション判断用 //  stSmartAllInfo : データを書き込み用 // //////////////////////////////////////////////////////////////////////////////////////////////////////// int FileOut( char *cpOutFileName, SMART_ALL_DATA *stSmartAllInfo, int iCount, int iOption ) { FILE *fp = NULL; //ファイル個数用 int iFileCnt = 0; //行数ループ用 int iDataCnt = 0; //ファイルオープン fopen_s( &fp, cpOutFileName, "wb" ); //オープンエラー判断 if( fp == NULL ) { printf( " Can not to open %s.\n " ,cpOutFileName); return FALSE; } //ライトループ for( iFileCnt = 0; iFileCnt < iCount; iFileCnt++ ) { fprintf( fp,"%s,",stSmartAllInfo[iFileCnt].FileNames ); for( iDataCnt = 0; iDataCnt < SMART_DATA_MAX; iDataCnt++ ) { //AttributeID "0"場合は出力しないこと if( stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeID !=0 ) { //オプション ORの場合:RAWデータだけ出力する if( iOption == OUTPUT_ORDATA ) { fprintf( fp,"%02x%02x%02x%02x%02x%02x," , stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] ); } //オプション OVの場合:valueデータだけ出力する else if( iOption == OUTPUT_OVDATA ) { fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].CurrentValue); fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].WorstValue); fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].ThresholdValue); fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] ); } //オプション RCの場合:Rawデータを逆序列出力出力する  else if( iOption == OUTPUT_RCDATA ) { fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0] ); } // 全データ出力 else { fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeID ); fprintf(fp,"%04x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].AttributeFlag ); fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].CurrentValue ); fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].WorstValue ); fprintf(fp,"%02x,",stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].ThresholdValue ); fprintf(fp,"%02x%02x%02x%02x%02x%02x,", stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[0], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[1], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[2], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[3], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[4], stSmartAllInfo[iFileCnt].stSmartInfo[iDataCnt].RawValue[5] ); } } } //1個ファイル出力後 改行する. fprintf(fp,"\r\n"); } //ファイルクローズ fclose( fp ); return TRUE; } ``` VS2008下编译通过。
终于明白阿里百度这样的大公司,为什么面试经常拿ThreadLocal考验求职者了
点击上面↑「爱开发」关注我们每晚10点,捕获技术思考和创业资源洞察什么是ThreadLocalThreadLocal是一个本地线程副本变量工具类,各个线程都拥有一份线程私有的数
程序员必须掌握的核心算法有哪些?
由于我之前一直强调数据结构以及算法学习的重要性,所以就有一些读者经常问我,数据结构与算法应该要学习到哪个程度呢?,说实话,这个问题我不知道要怎么回答你,主要取决于你想学习到哪些程度,不过针对这个问题,我稍微总结一下我学过的算法知识点,以及我觉得值得学习的算法。这些算法与数据结构的学习大多数是零散的,并没有一本把他们全部覆盖的书籍。下面是我觉得值得学习的一些算法以及数据结构,当然,我也会整理一些看过...
《奇巧淫技》系列-python!!每天早上八点自动发送天气预报邮件到QQ邮箱
此博客仅为我业余记录文章所用,发布到此,仅供网友阅读参考,如有侵权,请通知我,我会删掉。 补充 有不少读者留言说本文章没有用,因为天气预报直接打开手机就可以收到了,为何要多此一举发送到邮箱呢!!!那我在这里只能说:因为你没用,所以你没用!!! 这里主要介绍的是思路,不是天气预报!不是天气预报!!不是天气预报!!!天气预报只是用于举例。请各位不要再刚了!!! 下面是我会用到的两个场景: 每日下
死磕YOLO系列,YOLOv1 的大脑、躯干和手脚
YOLO 是我非常喜欢的目标检测算法,堪称工业级的目标检测,能够达到实时的要求,它帮我解决了许多实际问题。 这就是 YOLO 的目标检测效果。它定位了图像中物体的位置,当然,也能预测物体的类别。 之前我有写博文介绍过它,但是每次重新读它的论文,我都有新的收获,为此我准备写一个系列的文章来详尽分析它。这是第一篇,从它的起始 YOLOv1 讲起。 YOLOv1 的论文地址:https://www.c...
知乎高赞:中国有什么拿得出手的开源软件产品?(整理自本人原创回答)
知乎高赞:中国有什么拿得出手的开源软件产品? 在知乎上,有个问题问“中国有什么拿得出手的开源软件产品(在 GitHub 等社区受欢迎度较好的)?” 事实上,还不少呢~ 本人于2019.7.6进行了较为全面的回答,对这些受欢迎的 Github 开源项目分类整理如下: 分布式计算、云平台相关工具类 1.SkyWalking,作者吴晟、刘浩杨 等等 仓库地址: apache/skywalking 更...
20行Python代码爬取王者荣耀全英雄皮肤
引言 王者荣耀大家都玩过吧,没玩过的也应该听说过,作为时下最火的手机MOBA游戏,咳咳,好像跑题了。我们今天的重点是爬取王者荣耀所有英雄的所有皮肤,而且仅仅使用20行Python代码即可完成。 准备工作 爬取皮肤本身并不难,难点在于分析,我们首先得得到皮肤图片的url地址,话不多说,我们马上来到王者荣耀的官网: 我们点击英雄资料,然后随意地选择一位英雄,接着F12打开调试台,找到英雄原皮肤的图片...
简明易理解的@SpringBootApplication注解源码解析(包含面试提问)
欢迎关注文章系列 ,关注我 《提升能力,涨薪可待》 《面试知识,工作可待》 《实战演练,拒绝996》 欢迎关注我博客,原创技术文章第一时间推出 也欢迎关注公 众 号【Ccww笔记】,同时推出 如果此文对你有帮助、喜欢的话,那就点个赞呗,点个关注呗! 《提升能力,涨薪可待篇》- @SpringBootApplication注解源码解析 一、@SpringBootApplication 的作用是什...
西游记团队中如果需要裁掉一个人,会先裁掉谁?
2019年互联网寒冬,大批企业开始裁员,下图是网上流传的一张截图: 裁员不可避免,那如何才能做到不管大环境如何变化,自身不受影响呢? 我们先来看一个有意思的故事,如果西游记取经团队需要裁员一名,会裁掉谁呢,为什么? 西游记团队组成: 1.唐僧 作为团队teamleader,有很坚韧的品性和极高的原则性,不达目的不罢休,遇到任何问题,都没有退缩过,又很得上司支持和赏识(直接得到唐太宗的任命,既给袈...
Python语言高频重点汇总
Python语言高频重点汇总 GitHub面试宝典仓库 回到首页 目录: Python语言高频重点汇总 目录: 1. 函数-传参 2. 元类 3. @staticmethod和@classmethod两个装饰器 4. 类属性和实例属性 5. Python的自省 6. 列表、集合、字典推导式 7. Python中单下划线和双下划线 8. 格式化字符串中的%和format 9. 迭代器和生成器 10...
究竟你适不适合买Mac?
我清晰的记得,刚买的macbook pro回到家,开机后第一件事情,就是上了淘宝网,花了500元钱,找了一个上门维修电脑的师傅,上门给我装了一个windows系统。。。。。。 表砍我。。。 当时买mac的初衷,只是想要个固态硬盘的笔记本,用来运行一些复杂的扑克软件。而看了当时所有的SSD笔记本后,最终决定,还是买个好(xiong)看(da)的。 已经有好几个朋友问我mba怎么样了,所以今天尽量客观
程序员一般通过什么途径接私活?
二哥,你好,我想知道一般程序猿都如何接私活,我也想接,能告诉我一些方法吗? 上面是一个读者“烦不烦”问我的一个问题。其实不止是“烦不烦”,还有很多读者问过我类似这样的问题。 我接的私活不算多,挣到的钱也没有多少,加起来不到 20W。说实话,这个数目说出来我是有点心虚的,毕竟太少了,大家轻喷。但我想,恰好配得上“一般程序员”这个称号啊。毕竟苍蝇再小也是肉,我也算是有经验的人了。 唾弃接私活、做外
ES6基础-ES6的扩展
进行对字符串扩展,正则扩展,数值扩展,函数扩展,对象扩展,数组扩展。 开发环境准备: 编辑器(VS Code, Atom,Sublime)或者IDE(Webstorm) 浏览器最新的Chrome 字符串的扩展: 模板字符串,部分新的方法,新的unicode表示和遍历方法: 部分新的字符串方法 padStart,padEnd,repeat,startsWith,endsWith,includes 字...
Python爬虫爬取淘宝,京东商品信息
小编是一个理科生,不善长说一些废话。简单介绍下原理然后直接上代码。 使用的工具(Python+pycharm2019.3+selenium+xpath+chromedriver)其中要使用pycharm也可以私聊我selenium是一个框架可以通过pip下载 pip install selenium -i https://pypi.tuna.tsinghua.edu.cn/simple/ 
阿里程序员写了一个新手都写不出的低级bug,被骂惨了。
你知道的越多,你不知道的越多 点赞再看,养成习惯 本文 GitHub https://github.com/JavaFamily 已收录,有一线大厂面试点思维导图,也整理了很多我的文档,欢迎Star和完善,大家面试可以参照考点复习,希望我们一起有点东西。 前前言 为啥今天有个前前言呢? 因为你们的丙丙啊,昨天有牌面了哟,直接被微信官方推荐,知乎推荐,也就仅仅是还行吧(心里乐开花)
Java工作4年来应聘要16K最后没要,细节如下。。。
前奏: 今天2B哥和大家分享一位前几天面试的一位应聘者,工作4年26岁,统招本科。 以下就是他的简历和面试情况。 基本情况: 专业技能: 1、&nbsp;熟悉Sping了解SpringMVC、SpringBoot、Mybatis等框架、了解SpringCloud微服务 2、&nbsp;熟悉常用项目管理工具:SVN、GIT、MAVEN、Jenkins 3、&nbsp;熟悉Nginx、tomca
Python爬虫精简步骤1 获取数据
爬虫的工作分为四步: 1.获取数据。爬虫程序会根据我们提供的网址,向服务器发起请求,然后返回数据。 2.解析数据。爬虫程序会把服务器返回的数据解析成我们能读懂的格式。 3.提取数据。爬虫程序再从中提取出我们需要的数据。 4.储存数据。爬虫程序把这些有用的数据保存起来,便于你日后的使用和分析。 这一篇的内容就是:获取数据。 首先,我们将会利用一个强大的库——requests来获取数据。 在电脑上安装
作为一个程序员,CPU的这些硬核知识你必须会!
CPU对每个程序员来说,是个既熟悉又陌生的东西? 如果你只知道CPU是中央处理器的话,那可能对你并没有什么用,那么作为程序员的我们,必须要搞懂的就是CPU这家伙是如何运行的,尤其要搞懂它里面的寄存器是怎么一回事,因为这将让你从底层明白程序的运行机制。 随我一起,来好好认识下CPU这货吧 把CPU掰开来看 对于CPU来说,我们首先就要搞明白它是怎么回事,也就是它的内部构造,当然,CPU那么牛的一个东
破14亿,Python分析我国存在哪些人口危机!
2020年1月17日,国家统计局发布了2019年国民经济报告,报告中指出我国人口突破14亿。 猪哥的朋友圈被14亿人口刷屏,但是很多人并没有看到我国复杂的人口问题:老龄化、男女比例失衡、生育率下降、人口红利下降等。 今天我们就来分析一下我们国家的人口数据吧! 更多有趣分析教程,扫描下方二维码关注vx公号「裸睡的猪」 即可查看! 一、背景 1.人口突破14亿 2020年1月17日,国家统计局发布
web前端javascript+jquery知识点总结
Javascript javascript 在前端网页中占有非常重要的地位,可以用于验证表单,制作特效等功能,它是一种描述语言,也是一种基于对象(Object)和事件驱动并具有安全性的脚本语言 ,语法同java类似,是一种解释性语言,边执行边解释。 JavaScript的组成: ECMAScipt 用于描述: 语法,变量和数据类型,运算符,逻辑控制语句,关键字保留字,对象。 浏览器对象模型(Br
Qt实践录:开篇
本系列文章介绍笔者的Qt实践之路。
在家远程办公效率低?那你一定要收好这个「在家办公」神器!
相信大家都已经收到国务院延长春节假期的消息,接下来,在家远程办公可能将会持续一段时间。 但是问题来了。远程办公不是人在电脑前就当坐班了,相反,对于沟通效率,文件协作,以及信息安全都有着极高的要求。有着非常多的挑战,比如: 1在异地互相不见面的会议上,如何提高沟通效率? 2文件之间的来往反馈如何做到及时性?如何保证信息安全? 3如何规划安排每天工作,以及如何进行成果验收? ......
作为一个程序员,内存和磁盘的这些事情,你不得不知道啊!!!
截止目前,我已经分享了如下几篇文章: 一个程序在计算机中是如何运行的?超级干货!!! 作为一个程序员,CPU的这些硬核知识你必须会! 作为一个程序员,内存的这些硬核知识你必须懂! 这些知识可以说是我们之前都不太重视的基础知识,可能大家在上大学的时候都学习过了,但是嘞,当时由于老师讲解的没那么有趣,又加上这些知识本身就比较枯燥,所以嘞,大家当初几乎等于没学。 再说啦,学习这些,也看不出来有什么用啊!
这个世界上人真的分三六九等,你信吗?
偶然间,在知乎上看到一个问题 一时间,勾起了我深深的回忆。 以前在厂里打过两次工,做过家教,干过辅导班,做过中介。零下几度的晚上,贴过广告,满脸、满手地长冻疮。   再回首那段岁月,虽然苦,但让我学会了坚持和忍耐。让我明白了,在这个世界上,无论环境多么的恶劣,只要心存希望,星星之火,亦可燎原。   下文是原回答,希望能对你能有所启发。   如果我说,这个世界上人真的分三六九等,
为什么听过很多道理,依然过不好这一生?
记录学习笔记是一个重要的习惯,不希望学习过的东西成为过眼云烟。做总结的同时也是一次复盘思考的过程。 本文是根据阅读得到 App上《万维钢·精英日课》部分文章后所做的一点笔记和思考。学习是一个系统的过程,思维模型的建立需要相对完整的学习和思考过程。以下观点是在碎片化阅读后总结的一点心得总结。
B 站上有哪些很好的学习资源?
哇说起B站,在小九眼里就是宝藏般的存在,放年假宅在家时一天刷6、7个小时不在话下,更别提今年的跨年晚会,我简直是跪着看完的!! 最早大家聚在在B站是为了追番,再后来我在上面刷欧美新歌和漂亮小姐姐的舞蹈视频,最近两年我和周围的朋友们已经把B站当作学习教室了,而且学习成本还免费,真是个励志的好平台ヽ(.◕ฺˇд ˇ◕ฺ;)ノ 下面我们就来盘点一下B站上优质的学习资源: 综合类 Oeasy: 综合
雷火神山直播超两亿,Web播放器事件监听是怎么实现的?
Web播放器解决了在手机浏览器和PC浏览器上播放音视频数据的问题,让视音频内容可以不依赖用户安装App,就能进行播放以及在社交平台进行传播。在视频业务大数据平台中,播放数据的统计分析非常重要,所以Web播放器在使用过程中,需要对其内部的数据进行收集并上报至服务端,此时,就需要对发生在其内部的一些播放行为进行事件监听。 那么Web播放器事件监听是怎么实现的呢? 01 监听事件明细表 名
3万字总结,Mysql优化之精髓
本文知识点较多,篇幅较长,请耐心学习 MySQL已经成为时下关系型数据库产品的中坚力量,备受互联网大厂的青睐,出门面试想进BAT,想拿高工资,不会点MySQL优化知识,拿offer的成功率会大大下降。 为什么要优化 系统的吞吐量瓶颈往往出现在数据库的访问速度上 随着应用程序的运行,数据库的中的数据会越来越多,处理时间会相应变慢 数据是存放在磁盘上的,读写速度无法和内存相比 如何优化 设计
一条链接即可让黑客跟踪你的位置! | Seeker工具使用
搬运自:冰崖的部落阁(icecliffsnet) 严正声明:本文仅限于技术讨论,严禁用于其他用途。 请遵守相对应法律规则,禁止用作违法途径,出事后果自负! 上次写的防社工文章里边提到的gps定位信息(如何防止自己被社工或人肉) 除了主动收集他人位置信息以外,我们还可以进行被动收集 (没有技术含量) Seeker作为一款高精度地理位置跟踪工具,同时也是社交工程学(社会工程学)爱好者...
作为程序员的我,大学四年一直自学,全靠这些实用工具和学习网站!
我本人因为高中沉迷于爱情,导致学业荒废,后来高考,毫无疑问进入了一所普普通通的大学,实在惭愧...... 我又是那么好强,现在学历不行,没办法改变的事情了,所以,进入大学开始,我就下定决心,一定要让自己掌握更多的技能,尤其选择了计算机这个行业,一定要多学习技术。 在进入大学学习不久后,我就认清了一个现实:我这个大学的整体教学质量和学习风气,真的一言难尽,懂的人自然知道怎么回事? 怎么办?我该如何更好的提升
前端JS初级面试题二 (。•ˇ‸ˇ•。)老铁们!快来瞧瞧自己都会了么
1. 传统事件绑定和符合W3C标准的事件绑定有什么区别? 传统事件绑定 &lt;div onclick=""&gt;123&lt;/div&gt; div1.onclick = function(){}; &lt;button onmouseover=""&gt;&lt;/button&gt; 注意: 如果给同一个元素绑定了两次或多次相同类型的事件,那么后面的绑定会覆盖前面的绑定 (不支持DOM事...
Python学习笔记(语法篇)
本篇博客大部分内容摘自埃里克·马瑟斯所著的《Python编程:从入门到实战》(入门类书籍),采用举例的方式进行知识点提要 关于Python学习书籍推荐文章 《学习Python必备的8本书》 Python语法特点: 通过缩进进行语句组织 不需要变量或参数的声明 冒号 1 变量和简单数据结构 1.1 变量命名 只能包含字母、数字和下划线,且不能以数字打头。 1.2 字符串 在Python中,用引号...
[Pyhon疫情大数据分析] 一.腾讯实时数据爬取、Matplotlib和Seaborn可视化分析全国各地区、某省各城市、新增趋势
思来想去,虽然很忙,但还是挤时间针对这次肺炎疫情写个Python大数据分析系列博客,包括网络爬虫、可视化分析、GIS地图显示、情感分析、舆情分析、主题挖掘、威胁情报溯源、知识图谱、预测预警及AI和NLP应用等。第一篇文章将分享腾讯疫情实时数据抓取,获取全国各地和贵州省各地区的实时数据,并将数据存储至本地,最后调用Maplotlib和Seaborn绘制中国各地区、贵州省各城市、新增人数的图形。希望这篇可视化分析文章对您有所帮助!
相关热词 c# 数组类型 泛型约束 c#的赛狗日程序 c# 传递数组 可变参数 c# 生成存储过程 c# list 补集 c#获得所有窗体 c# 当前秒数转成年月日 c#中的枚举 c# 计算校验和 连续随机数不重复c#
立即提问