Question: 【新手求助】关于C读取txt文档存入数组的问题~

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>  typedef struct info {     char ip[16];     char mac[32];     int cnt;     int len;     char mac_vendor[32]; } INFO_OBJ, *INFO_HANDLE;  int main() {     FILE* fp;     if (NULL == (fp = fopen("host.txt", "r"))) {         printf("error\n");         exit(1);     }      char line[BUFSIZ];      info wf;     int cnt = 0;      while (fgets(line, BUFSIZ, fp)) {          char* pch = strtok(line, " ");         if ((pch != NULL) && isdigit(pch[0])) {  // 检查是否是 ip (数字开头)             strncpy(wf.ip, pch, 16 - 1);              pch = strtok(NULL, " ");             strncpy(wf.mac, pch, 32 - 1);              pch = strtok(NULL, " ");             wf.cnt =  atoi(pch);              pch = strtok(NULL, " ");             wf.len =  atoi(pch);              pch = strtok(NULL, "\n"); // 删除最后的换行             while (!isalpha(*pch++)) // 跳到第一个字母上面                 ;             strncpy(wf.mac_vendor, pch, 32 - 1);              printf("a[%d]|%s|%s|%d|%d|%s|\n",                    cnt++, wf.ip, wf.mac,                    wf.cnt, wf.len, wf.mac_vendor);         }     }      fclose(fp);     return 0; }   这样应该可以了

引用 15 楼 zjq9931 的回复:来晚了。。。不完呐~~~~~

引用 14 楼 hongwenjun 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h>  typedef struct info {     char ip[16];     char mac[32];     int cnt;     int len;     char mac_vendor[32]; } INFO_OBJ, *INFO_HANDLE;  int main() {     FILE* fp;     if (NULL == (fp = fopen("host.txt", "r"))) {         printf("error\n");         exit(1);     }      char line[BUFSIZ];      info wf;     int cnt = 0;      while (fgets(line, BUFSIZ, fp)) {          char* pch = strtok(line, " ");         if ((pch != NULL) && isdigit(pch[0])) {  // 检查是否是 ip (数字开头)             strncpy(wf.ip, pch, 16);              pch = strtok(NULL, " ");             strncpy(wf.mac, pch, 32);              pch = strtok(NULL, " ");             wf.cnt =  atoi(pch);              pch = strtok(NULL, " ");             wf.len =  atoi(pch);              pch = strtok(NULL, " ");  // 这里因为使用 " " 把最后一个隔断了，可以按其他的再改改             strncpy(wf.mac_vendor, pch, 32);              printf("a[%d]|%s|%s|%d|%d|%s|\n",                    cnt++, wf.ip, wf.mac,                    wf.cnt, wf.len, wf.mac_vendor);         }     }      fclose(fp);     return 0; }  真的谢谢您！~~~

来晚了。。。

引用 12 楼 cfjtaishan 的回复:[quote=引用 8 楼 aabcg129 的回复:] [quote=引用 7 楼 cfjtaishan 的回复:] #include <stdio.h> #include <stdlib.h>  typedef struct info{     char ip[16];     char mac[32];     int cnt;     int len;     char mac_vendor[32]; }INFO_OBJ, *INFO_HANDLE;  #define MAX_SIZE    100  INFO_OBJ info_list[MAX_SIZE];  int main() {     FILE *fp;     int i = 0, ret = -1;     //if(!(fp = fopen("host.txt", "r"))) {     if(!(fp = fopen("1.txt", "r"))) {         printf("error\n");         exit(1);     }     char title[200];     fgets(title, 200, fp);     printf("%s", title);     fgets(title, 200, fp);     printf("%s", title);     ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     while(EOF != ret) {         printf("%-15s\t%s\t%d\t%d\t%s\n",                 info_list[i].ip,                 info_list[i].mac,                 info_list[i].cnt,                 info_list[i].len,                 info_list[i].mac_vendor               );         i++;         ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     }      printf("total num = %d\n", i);     fclose(fp);      return 0; } 参考一下吧，根据文件的格式选择对应的读写接口谢谢！！！真的谢谢您~可是如何显示成 a[0] |_____________________|          a[1] |_____________________|           a[2] |_____________________|         a[3] |_____________________|           a[4] |_____________________|        a[5] |_____________________|           a[6] |_____________________|      a[7] |_____________________|         a[8] |_____________________|          a[9] |_____________________|  这样的呢，有数组标识这样的~表示领导看了这个后以为还不是存为数组，只是又读了一遍txt~[/quote] 额，这个总不能把所有问题都做好，楼主交一下作业就完事吧。输出格式，你在printf中改一下即可。 自己吸收一下，在基础上改一改，不然自己怎么进步呢； 是不是用数组，不是看输出的，代码里会说明的。[/quote]好的~~~谢谢大大~~~！

引用 8 楼 aabcg129 的回复:[quote=引用 7 楼 cfjtaishan 的回复:] #include <stdio.h> #include <stdlib.h>  typedef struct info{     char ip[16];     char mac[32];     int cnt;     int len;     char mac_vendor[32]; }INFO_OBJ, *INFO_HANDLE;  #define MAX_SIZE    100  INFO_OBJ info_list[MAX_SIZE];  int main() {     FILE *fp;     int i = 0, ret = -1;     //if(!(fp = fopen("host.txt", "r"))) {     if(!(fp = fopen("1.txt", "r"))) {         printf("error\n");         exit(1);     }     char title[200];     fgets(title, 200, fp);     printf("%s", title);     fgets(title, 200, fp);     printf("%s", title);     ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     while(EOF != ret) {         printf("%-15s\t%s\t%d\t%d\t%s\n",                 info_list[i].ip,                 info_list[i].mac,                 info_list[i].cnt,                 info_list[i].len,                 info_list[i].mac_vendor               );         i++;         ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     }      printf("total num = %d\n", i);     fclose(fp);      return 0; } 参考一下吧，根据文件的格式选择对应的读写接口谢谢！！！真的谢谢您~可是如何显示成 a[0] |_____________________|          a[1] |_____________________|           a[2] |_____________________|         a[3] |_____________________|           a[4] |_____________________|        a[5] |_____________________|           a[6] |_____________________|      a[7] |_____________________|         a[8] |_____________________|          a[9] |_____________________|  这样的呢，有数组标识这样的~表示领导看了这个后以为还不是存为数组，只是又读了一遍txt~[/quote] 额，这个总不能把所有问题都做好，楼主交一下作业就完事吧。输出格式，你在printf中改一下即可。 自己吸收一下，在基础上改一改，不然自己怎么进步呢； 是不是用数组，不是看输出的，代码里会说明的。

引用 9 楼 hongwenjun 的回复:#include <stdio.h> #include <stdlib.h> #include <string.h> int main() {     FILE* fp;     if (NULL == (fp = fopen("host.txt", "r"))) {         printf("error\n");         exit(1);     }      char line[BUFSIZ];     while (fgets(line, BUFSIZ, fp)) {          char*  pch = strtok(line, " ");         while (pch != NULL) {             printf("%s\t", pch);             pch = strtok(NULL, " ");          }     }      fclose(fp);      return 0; }    还要再改改谢谢大佬~~~~很感谢呐！！！可是运行结果有点错行，而且没有显示数组标识~~~请问这个如何解决~~？

引用 7 楼 cfjtaishan 的回复:#include <stdio.h> #include <stdlib.h>  typedef struct info{     char ip[16];     char mac[32];     int cnt;     int len;     char mac_vendor[32]; }INFO_OBJ, *INFO_HANDLE;  #define MAX_SIZE    100  INFO_OBJ info_list[MAX_SIZE];  int main() {     FILE *fp;     int i = 0, ret = -1;     //if(!(fp = fopen("host.txt", "r"))) {     if(!(fp = fopen("1.txt", "r"))) {         printf("error\n");         exit(1);     }     char title[200];     fgets(title, 200, fp);     printf("%s", title);     fgets(title, 200, fp);     printf("%s", title);     ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     while(EOF != ret) {         printf("%-15s\t%s\t%d\t%d\t%s\n",                 info_list[i].ip,                 info_list[i].mac,                 info_list[i].cnt,                 info_list[i].len,                 info_list[i].mac_vendor               );         i++;         ret = fscanf(fp, "%s %s %d %d %[^\n]\n",                  info_list[i].ip,                  info_list[i].mac,                  &info_list[i].cnt,                  &info_list[i].len,                  info_list[i].mac_vendor);     }      printf("total num = %d\n", i);     fclose(fp);      return 0; } 参考一下吧，根据文件的格式选择对应的读写接口谢谢！！！真的谢谢您~可是如何显示成 a[0] |_____________________|          a[1] |_____________________|           a[2] |_____________________|         a[3] |_____________________|           a[4] |_____________________|        a[5] |_____________________|           a[6] |_____________________|      a[7] |_____________________|         a[8] |_____________________|          a[9] |_____________________|  这样的呢，有数组标识这样的~表示领导看了这个后以为还不是存为数组，只是又读了一遍txt~

引用 4 楼 yuzengyuan 的回复:小手一抖，经验到手0.0     大佬能帮忙解决一下么~~~~

小手一抖，经验到手

引用 2 楼 hongwenjun 的回复:使用 fgets 每次读取一行处理     while (fgets(line, BUFSIZ, input)) {         read_rmc = read_gprmc(line, rmc);          if (read_rmc) {       。。。。。。。         }     }首先谢谢大大~~~但是....可以有完整的代码吗~刚学C才三天，我串不起来~

// 读取一行GPRMC数据，判断是否是GPRMC数据行 bool read_gprmc(const char* line, gprmc_format& rmc) {      char line_buf[BUFSIZ];     strncpy(line_buf, line, BUFSIZ);      int chksum = 0;      if ('$' != line_buf[0]) {         print_error(1);         return false;;      } else {          char* pch = strrchr(line_buf, '*');         if (pch != NULL) {             *pch = '\0';             rmc.mode = *(pch - 1);             pch++;             rmc.chksum = strtol(pch, &pch, 16);             // printf("%X\n", chksum);              if (rmc.chksum != checksum(line_buf + 1)) {                 print_error(2);                 return false;;             }         } else {             print_error(3);             return false;;         }           if (strstr(line_buf, ",,"))             multi_replace(line_buf, ",,", ",|,");          pch = strtok(line_buf, ",");         if ((pch != NULL) && !strcmp(pch, "$GPRMC")) {             // printf("%s\n", pch);    //GPRMC              pch = strtok(NULL, ",");             rmc.rcv_time = atof(pch);              pch = strtok(NULL, ",");             rmc.status = *pch;              pch = strtok(NULL, ",");             rmc.lat = atof(pch);              pch = strtok(NULL, ",");             rmc.lat_direct  = *pch;              pch = strtok(NULL, ",");             rmc.lon = atof(pch);              pch = strtok(NULL, ",");             rmc.lon_direct = *pch;              pch = strtok(NULL, ",");             rmc.speed  = atof(pch);              pch = strtok(NULL, ",");             rmc.cog  = atof(pch);              pch = strtok(NULL, ",");             rmc.date  = atoi(pch);              // 一般空             rmc.mag_variation   = 0;             rmc.mag_var_direct  = 'W';              rmc.mode = rmc.mode; // 之前已经读到          } else {             print_error(4);             return false;;          }      }      return true; }


Question: 关于整数分解打印以及整数千分位分解打印的问题

//以三位分组，你自己举一反三 int n=43546,m,k; while(n>0) { k=n;//暂存循环结束的原数 n=n/1000; m=k-n*1000;//每次的最低三位 }

引用 6 楼 bupt2017211230 的回复:非常谢谢大家的回复，但其实我们考试时并不可以使用任何数组，子函数，递归等 只能用基础的迭代还有穷举算法。。。可能在我学了这些知识后就能更好的理解你们的程序了。 考试还能要求这些，那太死板了。解决问题，那种方法好就用那种方法呗。前提是自己能理解和运用

仅供参考：char * comma(__int64 num) {     static char commades[80];     static char commasrc[80];      sprintf(commasrc,"%I64d",num);     int L=strlen(commasrc);     register int j=0;     register int k=0;     for (int i=L-1;i>=0;i--) {         commades[j]=commasrc[i];         k++;         j++;         if ((k%3)==0 && i>0) {             commades[j]=',';             j++;         }     }     commades[j]=0;     strrev(commades);     return commades; }

#include <stdio.h> #include <math.h>  void show_digit(int num); void show_digit_as_bit(int num, int bit); int main(int argc, char** argv) { #if 1      int num;      while (scanf("%d", &num) > 0 && num > 0) {         show_digit(num);         printf("\n");         show_digit_as_bit(num, 3);         printf("\n");     }  #else     int i,longest,n,bn,t;     i,longest=0;     t=1;     scanf("%d",&bn);     n=bn;     while(n/10!=0)     {         n=n/10;         i++;     }     longest=i+1;     n=bn;     i=0;     while(n/10!=0)     {         while(i<longest-1)         {             n=n/10;             i++;             if(n/10==0)             {                 printf("%d ",n);             }         }         i=0;          while(i<longest-1)         {             t=10*t;             i=i+1;         }         longest=longest-1;         bn=bn%t;         n=bn;         i=0;         t=1;      }     printf("%d\n",n); #endif     return 0; }   void show_digit(int num) {     if (num > 0)         show_digit(num / 10);     if (num <= 0)         return;     printf("%d ", num % 10); }  void show_digit_as_bit(int num, int bit) {     printf("****%d\n", num);     int n = pow(10, bit);     if (num > 0)         show_digit_as_bit(num / n, bit);     if (num <= 0)         return;      printf("%d ", num % n); }  参考一下吧，其实用一个函数就可以实现你的两个功能；  void show_digit_as_bit(int num, int bit) {     printf("****%d\n", num);     int n = pow(10, bit);     if (num > 0)         show_digit_as_bit(num / n, bit);     if (num <= 0)         return;      printf("%d ", num % n); } 实现第一个功能，只需要调用函数是第二个参数传1，实现第二个功能传3；即  #include <stdio.h> #include <math.h>  void show_digit(int num); void show_digit_as_bit(int num, int bit); int main(int argc, char** argv) {     int num;      while (scanf("%d", &num) > 0 && num > 0) {         show_digit_as_bit(num, 1);         printf("\n");         show_digit_as_bit(num, 3);         printf("\n");     }     return 0; }   void show_digit(int num) {     if (num > 0)         show_digit(num / 10);     if (num <= 0)         return;     printf("%d ", num % 10); }  void show_digit_as_bit(int num, int bit) {     int n = pow(10, bit);     if (num > 0)         show_digit_as_bit(num / n, bit);     if (num <= 0)         return;      printf("%d ", num % n); } 参考一下吧，递归方法

引用 1楼user-4 的回复:为什么提交不通过，时间太慢？没看怎么看你写的代码，1234567这个数，千分位分解，先%1000，得到567，再/1000得到1234，1234%1000，得到234，再/1000得到1，1%1000得到1，1/1000小于0退出循环。最后=0退出循环，打错了。

引用 1 楼 user-4 的回复:为什么提交不通过，时间太慢？没看怎么看你写的代码，1234567这个数，千分位分解，先%1000，得到567，再/1000得到1234，1234%1000，得到234，再/1000得到1，1%1000得到1，1/1000小于0退出循环。 1.不是时间的问题 2.后来我又尝试了几个数例，发现数字中含有0就会使结果出现问题，我程序本身应该就某种情况没考虑到，或者根本有错误... 3.至于什么错误我还没来得及细看，要上课了先溜了，谢谢你啦


Question: 大神们求教

引用 8 楼 hdt 的回复:你是要11进制数？？ int a = (55-44)%11???

直接在printf里写。。。囧！

???? 能否说明白一点

你是要11进制数？？ int a = (55-44)%11???

我的语文需要去补习了

问题描述不清，55-44怎么会等于-11和0

先弄明白55-44怎么能得-11（注意前面有-）； 建议楼主把需求详细描述一下，不然颠覆计算机计算规律恐怕不行呢

感觉楼主好厉害的样子


Question: 【新手求教~！】还是关于文本读取的问题~~

仅供参考：//NAME: essaie bla bla //DIMENSION: 8 //DATA //1  14  15 //2  11  10 //3  6   4 //4  7   13 //5  9   21 //6  19  3 //7  1   5 //8  8   8 //EOF // // 文本文件中可能还含有其他内容，但是需要用到的内容即以上  //比如data.txt: //NAME: essaie bla bla //其它内容 //DIMENSION: 8 //其它内容 //DATA //其它内容 //1  14  15 //其它内容 //2  11  10 //其它内容 //3  6   4 //其它内容 //4  7   13 //其它内容 //5  9   21 //其它内容 //6  19  3 //其它内容 //7  1   5 //其它内容 //8  8   8 //其它内容 //EOF  // 目标是要获取NAME后字串，DIMENSION后数值，以及DATA以下的数值 // 其中NAME就是随便个字句，DIMENSION是城市数量，DATA以下是城市编号，X坐标，Y坐标 // 所有的这些将赋值给一个事先定义好的结构 #include <stdio.h> #include <string.h> #define MAXCPL   80   //每行最大字符数 #define MAXCITY  100  //每组数据中DATA最多项数，DIMENSION的最大值 #define MAXNAMEL 32   //NAME最大长度 struct S {     char NAME[MAXNAMEL+1];     int  DIMENSION;     struct D {         int NO;         int X;         int Y;     } DATA[MAXCITY]; } s; FILE *f; int st,n,i; char ln[MAXCPL]; int main() {     f=fopen("data.txt","r");     if (NULL==f) {         printf("Can not open file data.txt!\n");         return 1;     }     st=0;     n=0;     while (1) {         if (NULL==fgets(ln,MAXCPL,f)) break;         if (st==0) {             if (1==sscanf(ln,"NAME: %31[^\n]",s.NAME)) st=1;         } else if (st==1) {             if (1==sscanf(ln,"DIMENSION: %d",&s.DIMENSION)) st=2;         } else if (st==2) {             if (0==strcmp(ln,"DATA\n")) st=3;         } else if (st==3) {             if (3==sscanf(ln,"%d%d%d",&s.DATA[n].NO,&s.DATA[n].X,&s.DATA[n].Y)) {                 n++;                 if (n>=MAXCITY || n>=s.DIMENSION) break;             }         }     }     fclose(f);     printf("s.NAME=[%s]\n",s.NAME);     printf("s.DIMENSION=%d\n",s.DIMENSION);     for (i=0;i<n;i++) {         printf("s.DATA[%d].NO,X,Y=%d,%d,%d\n",i,s.DATA[i].NO,s.DATA[i].X,s.DATA[i].Y);     }     return 0; } //s.NAME=[essaie bla bla] //s.DIMENSION=8 //s.DATA[0].NO,X,Y=1,14,15 //s.DATA[1].NO,X,Y=2,11,10 //s.DATA[2].NO,X,Y=3,6,4 //s.DATA[3].NO,X,Y=4,7,13 //s.DATA[4].NO,X,Y=5,9,21 //s.DATA[5].NO,X,Y=6,19,3 //s.DATA[6].NO,X,Y=7,1,5 //s.DATA[7].NO,X,Y=8,8,8

引用 9 楼 hongwenjun 的回复:#include <stdio.h> #include <string.h>  int main() {     FILE* pFile;     char* pch;     char str [255] = {0};      pFile = fopen("tel.csv" , "r");     if (pFile == NULL) {         perror("Error opening file");         return -1;     }     fgets(str , 255 , pFile);     while (! feof(pFile)) {         pch = strtok(str, ",\n");         while (pch != NULL) {             printf("%s\t", pch);             pch = strtok(NULL, ",\n");         }         printf("\n");         fgets(str , 255 , pFile);  // 这样写法 解决BUG，不会输出最后一行的名字      }     fclose(pFile);     return 0; } /* 输出结果 姓名    办电    宅电    手机    虚拟网 卢小珍  34521111        88903453        13537902123     332123 童云龙  34521113        88927528        13503793985     373985 童万贞  34521112        34523377        13803778530     338530  */   数据文件 tel.csv 姓名,办电,宅电,手机,虚拟网 卢小珍,34521111,88903453,13537902123,332123 童云龙,34521113,88927528,13503793985,373985 童万贞,34521112,34523377,13803778530,338530 卢小珍,34521111,88903453,13537902123,332123 这个没看明白哦，姓名得是一个字段里面的，分别读取其中的卢小珍，童云龙，读姓名时不用读出来办电和手机的。。。这个是直接读取全部的内容咯

引用 8 楼 zjq9931 的回复:[quote=引用 7 楼 aabcg129 的回复:] [quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   } [/quote]  fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针，指针+1就是字段的内容。 结合一些字符串操作函数，就可以取出每个字段。[/quote] fgetc换成fgets 编译就报错了[Error] cannot convert 'FILE* {aka _iobuf*}' to 'char*' for argument '1' to 'char* fgets(char*, int, FILE*)' 然后各个字段怎么就能实现分开读取的情况，还请指教~有代码最好理解了

引用 4 楼 aabcg129 的回复:[quote=引用 1 楼 u011648839 的回复:] 不能用数组就用char*直接写死啊，就不能修改了 读的时候就一个字符一个字符比较呗，每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了  主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了[/quote] 不能用数组的是没办法的 任何信息只要是连续的有序的同类的，都可以看做数组，并不是非得char a[10]才叫数组 只要你在内存里把张三这两个字排列出来，我就可以说这是一个数组

引用 7 楼 aabcg129 的回复:[quote=引用 5 楼 zjq9931 的回复:] [quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   } [/quote]  fgetc换成fgets可以一次读取一行。 一行一行操作就容易理解一下。 每个字段的分割符用'\t'来分割。 strstr函数可以返回\t位置的指针，指针+1就是字段的内容。 结合一些字符串操作函数，就可以取出每个字段。

引用 5 楼 zjq9931 的回复:[quote=引用 4 楼 aabcg129 的回复:] 主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。[/quote]嗯呢，谢谢大佬。。。不过现在只写了打开txt文档的代码，后面功能实现就不会了~ #include <stdio.h>   #include <stdlib.h>   int main()   {       FILE *fp;       if(NULL == (fp = fopen("host.txt", "r")))       {           printf("error\n");           exit(1);       }          char ch;       while(EOF != (ch=fgetc(fp)))       {           printf("%c", ch);       }          fclose(fp);           return 0;   }

引用 3 楼 cfjtaishan 的回复:这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写

引用 4 楼 aabcg129 的回复:主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了 先把自己写的代码拿上来，给你改改是可以的。

引用 1 楼 u011648839 的回复:不能用数组就用char*直接写死啊，就不能修改了 读的时候就一个字符一个字符比较呗，每个断句后加个自定义的标志比如\2读到了就表示改下一个信息了  主要不能写死。。 T T 因为还会刷新文档内容，每次要覆盖一下的。。。。想不出来办法了

平台关系很大啊，如果有类似于getline这样的函数，就一行一行读，然后套用相同的规则去解析出各字段。 当然如果没有也没关系，读到\n就是一行嘛

引用 20 楼 zhao4zhong1 的回复:[quote=引用 19 楼 hzy_76 的回复:] 上面有朋友给出fsanf的方法，应该可行，不过format中的\n应该不要，即这样写：  fscanf("%s %d %s %s %s", name, &age, sex, tel, address);  你必须把所有列都一次性读出来，只是某些列不用来显示罢了，此时文件指针会自动往后移。 无意义并且无规则的行，可以用读行的函数读出来后不处理，使文件指针后移。 不要的列可以在%后面加*跳过。[/quote]受教了！

受教了，谢谢！

引用 19 楼 hzy_76 的回复:上面有朋友给出fsanf的方法，应该可行，不过format中的\n应该不要，即这样写：  fscanf("%s %d %s %s %s", name, &age, sex, tel, address);  你必须把所有列都一次性读出来，只是某些列不用来显示罢了，此时文件指针会自动往后移。 无意义并且无规则的行，可以用读行的函数读出来后不处理，使文件指针后移。 不要的列可以在%后面加*跳过。

//#include <stdio.h> #include <stdlib.h> #include <memory.h> int main(void) { FILE *fp = NULL; char buf[1024] = {0}; int count = 0; int row = 0; int ch = 0; fp = fopen("host.txt", "r"); if (fp == NULL) { printf("Cann't open the file!\n"); exit(1); } else { while (1) { printf("Input a row you want to read: \n"); scanf("%d", &row);  fflush(stdin); while (!feof(fp)) { fgets(buf, 1024, fp); count++; if (row == count) { printf("%s", buf); } memset(buf, 0, sizeof(buf)); } count = 0; rewind(fp); printf("go on? [y/n]: "); scanf("%c", &ch); fflush(stdin); if (ch == 'y' || ch == 'Y') { continue; } else { break; } } fclose(fp); } return 0; } 刚在网上看到或者读任意一行的代码~但还是不知道如何把name字段下的东西放进一个组里~啊啊啊啊啊~哪位大神能写个代码啊啊啊啊~抓狂ing ~img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/50.gif][/img]

引用 16 楼 cfjtaishan 的回复:[quote=引用 6 楼 aabcg129 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里，这个数据建议用malloc/realloc申请空间，因为读文件不知道文件有多少个人的信息； 用户输入age时，你就循环遍历数组，一个个比较，若相等直接输出下表即可。因为数组下表就是在文件内的第几行（数组下表是从0开始）[/quote] 太高深了~实在不明白~不过还是谢谢您~

引用 6 楼 aabcg129 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] 这个问题不是特别难吧;不能使用数组是啥个意思？ 我定义一个数组（结构体），然后读文件到内存（申请的数组就在内存里），这样通过遍历内存里的数据可以得到对应的某行末列的数值;   struct person_info {     char name[32];     int age;     char sex[6];     char tel[16];     char address[32]; };   读得时候建议使用fscanf,因为文件数据很有规则； struct person_info info; fscanf("%s %d %s %s %s\n", info.name, &info.age, info.sex, info.tel, info.address); 方法可以参考一下；有问题可以继续提出来。 谢谢大佬~应该是可以用数组的，不能用数组的话我也不知道怎么写，当时老师说的有些快，应该是听错了需求。。。。现在仅仅会fopen整个txt 现在读取是没问题，就是在选项那一块不懂，怎么做就可以实现输入age 再输入行数，然后定位到年龄，这一块不知道怎么写[/quote] 你先将文件内容读到一个数组里，这个数据建议用malloc/realloc申请空间，因为读文件不知道文件有多少个人的信息； 用户输入age时，你就循环遍历数组，一个个比较，若相等直接输出下表即可。因为数组下表就是在文件内的第几行（数组下表是从0开始）


Question: C语言实现从大到小的数据排序问题

#include <stdio.h> int main() { 	int a[10]; 	int i,j,k; 	printf("input 10 numbers :\n"); 	for(i=0;i<10;i++) 		scanf("%d",&a[i]); 	printf("\n"); 		for(j=0;j<9;j++) 			for(i=0;i<9-j;i++) 				if(a[i]>a[i+1]) 				{ 					k=a[i];a[i]=a[i+1];a[i+1]=k; 				} 				printf("the sorted number :\n"); 				for(i=0;i<10;i++) 					printf("%d\n",a[i]); 				printf("\n"); 				return 0; }

#include <stdio.h> #include <stdlib.h>  void sort(int x[],int n); /*函数要先声明后使用*/ int main() {     int i,a[10];     printf("please enter 10 interger numbers:");     for (i = 0; i < 10; i++)         scanf("%d",&a[i]);     sort(a,10);   /* 函数调用去掉void*/     for(i=0;i<10;i++)     {         printf("%d\n",a[i]);     }     return 0; } void sort(int x[],int n) {     int i,j,k;     for(i=0;i<n;i++)     {         for(j=i+1;j<n;j++)         {             if(x[i] < x[j])             {                 k = x[i];                 x[i] = x[j];                 x[j] = k;             }         }     } }  参考一下吧；问题详见注释； 排序算法没问题，主要是在函数调用和声明上～


Question: C语言数组和指针的变换，求大神解决

建议提供一下str的定义。因为改表达式应该怎么赋值，是&str[i]，还是str[i]跟str的类型有很大关系； 若str是字符类型的指针数组，那么这样赋值char *tmp = str[i];是没问题的。 若str是字符数组，那么需要char *tmp = &str[i]; 或char *tmp = str + i;

引用 4 楼 qq_41093250 的回复:[quote=引用 2 楼 Intel0011 的回复:] 如果定义char *str[10]; 则char *tmp = str[i]; OK 如果定义char str[10]; 则char *tmp = &str[i]; OK 能不能详细说一下为啥啊[/quote] 如果定义char *str[10]; 则str数组有10个元素，每个元素的类型是char *，所以str[i]的类型也是char * 因此char *tmp = str[i];可以通过编译，类型相同  如果定义char str[10]; 则str数组有10个元素，每个元素的类型是char，所以str[i]的类型也是char 因此char tmp = str[i];可以通过编译，类型相同  教程的基本概念而已，加油

引用 2 楼 Intel0011 的回复:如果定义char *str[10]; 则char *tmp = str[i]; OK 如果定义char str[10]; 则char *tmp = &str[i]; OK 能不能详细说一下为啥啊

char *tmp = str[i];是相当于直接指针的初始化值 如果是:char *tmp;            //声明变量是指针变量 tmp=&str[i]                           //初始化指针的，指针的内容为地址，所以赋值为地址

str[i]的类型是char*指针,不然编译不通过的


Question: 关于动态分配内存的结构体数组 数据输入时内存错误的问题

关于自己是否适合编程的很简单的测试： 在报纸或杂志上随便找一段约1000字的文章，在Word中输入一遍。输完后再参考下面答案：  A里面有10处以上文字或标点错误 B里面没有文字或标点错误并敢为此跟人打赌 C里面没有文字或标点错误并且字体和排版完全与原稿一致 D打印在半透明的纸上和原稿重叠在一起检查一模一样，且自我感觉很有成就感  A不适合编程（理由：打字准确度偏低、粗心大意） B初级程序员（理由：打字准确度很高、认真细致、自信、理解全角半角概念） C高级程序员（理由：在B的基础上理解字体和排版也是电脑打印的重要因素、但相比D还不够偏执、精益求精、结果可验证） D软件项目经理（理由：能针对项目给出令人信服的细致到极点的需求说明和典型测试用例。用户几乎挑不出毛病。专业！）  如果想从A变成B的话，到我的资源http://download.csdn.net/detail/zhao4zhong1/4084259里面下载“适合程序员的键盘练习”

printf("请输入新学员姓名\n"); scanf("%s,a[count].name"); 这个地方需要改一下，注意双引号的位置； printf("请输入新学员姓名\n");     scanf("%s", a[count].name);  同理这条语句的双引号注意位置： printf("%d\n",a[i].score);  另外程序有越界的问题，malloc申请了2个学生信息的空间，但是循环后又加了1个，所以第三是越界；

编译了一下,错误是double free,很明显是free出错了,addAStudent函数无法改变实参a,导致free两次


Question: 有一个关于栈的问题，还有就是Tc2.0怎么使用单步跟踪，求大佬教教

引用 7 楼 Rewen 的回复:一个是step in , 一个是 step over. 遇到函数调用时，step in 进入函数内部；step over不进入函数内部。

一个是step in , 一个是 step over.

老师，按F7或F8键单步跟踪，F7，F8我试过了，感觉二者没有什么区别呢，求指教。

在DosBox下使用TC2 按F7或F8键单步跟踪。

因为是指针，定义的e.seat是野指针，所以必须给其分配有效的空间。 如果不想每次都分配，那么直接定义成结构体变量。这样定义e的时候也会对seat分配sizeof(Postype)的空间；

我是看到tc2.0来的，这个软件比csdn上多数人的年龄都要大了吧 菜单上有单步执行的快捷键可以查看吧

为什么要用TC2.0？

我这个结构的堆栈，堆栈元素里面有一个一级指针，主函数里面只声明了一个SElemType类型的e，所以每次Push时，都需要先对e.seat分配空间，不然Pop的e的seat就会出错，请问除了每次分配，还有其他的办法吗？    因为 seat   是  Postype*类型  存放结构体的指针， 不分配内存，结构体中的数据指针存放溢出 若不分配内存   定义为Postype seat;


Question: 小数转指数的问题

浮点数格式 http://bbs.csdn.net/topics/390676437

这个100.1=1.001*2^2 不就是小数点向左移动吗，它不代表乘以4，1.001*2^2=100.1 小数点向右移动变成100.1，为什么？二进制相乘啊，1.001*2^2=1.001*100.0,你试试算算是不是100.1，二进制相乘而已！

楼主的1.001 * 2^2这儿的1.001是十进制还是二进制，这个要确定好了。 另外，C语言里是不能用10^2，表示10 * 10;在C语言里^是异或运算符；所以 100.1=1.001*10^2 这句只是数学上的可行；在C语言里^不是幂； 100.1=1.001*2^2  这句是否成立，建议注意一下相等的环境（是10进制还是二进制）

所谓语言，并不是直接就是物体的本身。只不过是对物体一个描述，如果深究的话，他的文字确实有欠严禁。 就拿你的例子来说,尾数我就不在这里考虑了 100（二进制）=1(二进制)×（100（二进制））=1(二进制)X2（十进制）X2（十进制）

引用 1 楼 hdt 的回复:二进制100.1转成十进制是多少？？？ 二进制100不就是4吗？ 后面的尾数，请自己考虑 帮我看下这个吧，图片里说任何一个数都可以表示成1.xxxxxx*2^n 这样的形式，55.234也能表示成1.几的指数形式吗

引用 2 楼 fafagb 的回复:[quote=引用 1 楼 hdt 的回复:] 二进制100.1转成十进制是多少？？？ 二进制100不就是4吗？ 后面的尾数，请自己考虑  100.1=1.001*100=1.001*10^2  100.1=1.001*100=1.001*2^2  你的意思是4的2进制是100*2^2的结果是1.001*100，为什么要用100*2^2这种写法？[/quote]

引用 1 楼 hdt 的回复:二进制100.1转成十进制是多少？？？ 二进制100不就是4吗？ 后面的尾数，请自己考虑  100.1=1.001*100=1.001*10^2  100.1=1.001*100=1.001*2^2  你的意思是4的2进制是100*2^2的结果是1.001*100，为什么要用100*2^2这种写法？


Question: max=(a>b)?a:b;用法困惑

简单点，写代码的方式简单点……#include <stdio.h> #include <stdlib.h>  #define LOOP_UPPER_LIMIT 500  int print(int n) { 	return printf("%d\n", n); }  int main(int argc, char *argv[]) { 	int count = 0; 	do { 		print(count); 	} while (count++ < LOOP_UPPER_LIMIT); 	while (count-- > 0) { 		print(count); 	} 	return 0; }

count = ((count++) > (count)) ? count++ : count;展开成 if...else... 句式： if (count++ > count) { 	count = count++; } else { 	count = count; }不觉得写法很奇葩吗？count++ > count 这个该如何比较？

#include<stdio.h> main() {     int count=0;     while(count<=500)     {         count=((count++)>(count))?count++:count;         printf("%d\n", count);         while(count==500)         {             while(count>=0)             {                 count=((count--)<(count))?count--:count;                 printf("%d\n", count);             }         }     } } 去掉取地址符&  注意count=((count++)>(count))?count++:count; 不建议这么写，可以考虑分开写；

count=((count++)>(count))?count++:count; 你是多不信任编译器啊,自加完事还要检验下,就不怕检验结果也是错的? 看来只有赵四老师能救这孩子了

print为什么要取地址呢 把取地址去掉先

http://blog.miskcoo.com/2014/07/cxx11-sequenced-before-and-evaluation-order 不过看代码，不只求值顺序，楼主似乎连i++的语义（是自加之前的值）都没搞懂。

不要使用 while (条件) 更不要使用 while (组合条件) 要使用 while (1) {  if (条件1) break;  //...  if (条件2) continue;  //...  if (条件3) return;  //... } 因为前两种写法在语言表达意思的层面上有二义性，只有第三种才忠实反映了程序流的实际情况。 典型如： 下面两段的语义都是当文件未结束时读字符 while (!feof(f)) {  a=fgetc(f);  //...  b=fgetc(f);//可能此时已经feof了！  //... } 而这样写就没有问题： while (1) {  a=fgetc(f);  if (feof(f)) break;  //...  b=fgetc(f);  if (feof(f)) break;  //... } 类似的例子还可以举很多。


Question: 浮点数在内存中的显示问题

小数点不占位置的。

小数点不占内存，浮点数的表示格式已经决定了小数点的位置

引用 3 楼 fafagb 的回复:[quote=引用 1 楼 zhao4zhong1 的回复:] 浮点数格式 http://bbs.csdn.net/topics/390676437 老是帮我看下这个吧，图片里说任何一个数都可以表示成1.xxxxxx*2^n 这样的形式，55.234也能表示成1.几的指数形式吗，如果不能，那最高位是不是就不能省略[/quote]使用1楼链接中的代码观察55.234用float和double表示时分别对应二进制的1.×××乘2的×××次方。

引用 1 楼 zhao4zhong1 的回复:浮点数格式 http://bbs.csdn.net/topics/390676437 老是帮我看下这个吧，图片里说任何一个数都可以表示成1.xxxxxx*2^n 这样的形式，55.234也能表示成1.几的指数形式吗，如果不能，那最高位是不是就不能省略


Question: 迷宫问题（栈）

请问我用的TC2.0，我只会断点发，单步跟踪怎么使用呢？

单步跟踪程序运行，很容易分析得到原因，其次出错是因为(SElemType*)realloc(S->base, (S->stacksize + STACKINCREMENT) * sizeof(SElemType));这里使用了未初始化的S->base

仅供参考：/**  * @Title  老鼠走迷宫的拓展探究  * @Author 孙琨  * @Date   2013-11-16  * @At     XUST  * @All Copyright by 孙琨  *  */  #include <iostream> using namespace std;  int maze[9][9] = { // 初始化迷宫，英文maze为“迷宫”     {2,2,2,2,2,2,2,2,2},     {2,0,0,0,0,0,0,0,2},     {2,0,2,2,0,2,2,0,2},     {2,0,2,0,0,2,0,0,2},     {2,0,2,0,2,0,2,0,2},     {2,0,0,0,0,0,2,0,2},     {2,2,0,2,2,0,2,2,2},     {2,0,0,0,0,0,0,0,2},     {2,2,2,2,2,2,2,2,2} };  int startI = 1,startJ = 1; // 入口行列坐标 int endI = 7,endJ = 7;     // 出口行列坐标  void visit(int i,int j)  // 自动搜寻路径 {     int m,n;      maze[i][j] = 1;      if((i == endI) && (j == endJ))     {         cout << endl << "显示路径:" << endl;         for(m=0; m<9; m++)         {             for(n=0; n<9; n++)             {                 if(maze[m][n] == 2)                     cout << "■";                 else if(maze[m][n] == 1)                     cout << "♀";                 else                     cout << "  ";             }             cout << endl;         }     }      if(maze[i][j+1] == 0)         visit(i,j+1);     if(maze[i+1][j] == 0)         visit(i+1,j);     if(maze[i][j-1] == 0)         visit(i,j-1);     if(maze[i-1][j] == 0)         visit(i-1,j);      maze[i][j] = 0;  }  int main(void) {     int i,j;      cout << "显示迷宫: " << endl;     for(i=0; i<9; i++)     {         for(j=0; j<9; j++)         {             if(maze[i][j] == 2)                 cout << "■" ;             else                 cout << "  " ;         }         cout << endl;     }      visit(startI,startJ);      return 0; }


Question: 小型图书馆管理系统中插入操作，如何做到重复输入用户？

引用 3 楼 wyxxxx_ 的回复:whlie(flag=='Y'||flag=='y'){            s=(struct books_list*)malloc(sizeof(struct books_list));	            printf("\n  请输入图书登入号；");  		   getchar();  		   scanf("%s",s->loginnum);             printf("\n  请输入图书书名；");  		   getchar(); 		   scanf("%s",s->bookname);  		   printf("\n  请输入图书作者名；");  		   getchar(); 		   scanf("%s",s->author);  		   printf("\n  请输入图书出版社；");  		   getchar(); 		   scanf("%s",s->publisher);  		   printf("\n  请输入图书出版时间；");  		   getchar(); 		   scanf("%s",s->pbtime);  		   printf("\n  请输入图书分类号；");  		   getchar(); 		   scanf("%s",s->classfy);  		   printf("\n  请输入图书价格；");  		   getchar(); 		   scanf("%f",&s->price);  		   printf("\n"); 		   p->next=s;/*将新加的字节添加进链表*/ 		   p=s;/*p指向尾结点，向后移*/ 		   s->next=NULL; 		   printf("一一一一添加成功!一一一一");  		   printf("\n  继续添加？(Y/N):"); 		   fflush(stdin);  		   scanf(" %c",&flag); 		   printf("\n"); 		   if(flag=='N'||flag=='n'){ 		   break; 		   }            save(head);/*保存数据至文件*/ 		   return;     }    去掉；后，显示下面的错误，请问怎么改？ [Error] 'whlie' was not declared in this scope [Error] expected ';' before '{' token 单词拼写错误； while 不是whlie，所以注意下～

whlie是什么语言的关键词？？ c，c++，java等等 只有while，没有whlie

代码中有些冗余code，比如：  if(flag=='N'||flag=='n')         {             break;         } else if (flag=='Y'||flag=='y')         {             continue;         } 这个else if是不需要的，因为这个判断已经在while循环条件中做判断了。所以，可以去掉else if  代码无效语句，fflush(stdin);不应定在有些系统上有效，所以用getchar();替换fflush //fflush(stdin);         getchar();

while后面多一个分号；如果加了分号，后面的大括号就不是循环体了哦；  whlie(flag=='Y'||flag=='y'); 这三条错误信息都是因为这个分号导致的；


Question: 关于printf 与scanf 空格的问题

Format Specification Fields: scanf and wscanf Functions A format specification has the following form:  % [width] [{h | l | I64 | L}]type  The format argument specifies the interpretation of the input and can contain one or more of the following:   White-space characters: blank (' '); tab ('\t'); or newline ('\n'). A white-space character causes scanf to read, but not store, all consecutive white-space characters in the input up to the next non–white-space character. One white-space character in the format matches any number (including 0) and combination of white-space characters in the input.   Non–white-space characters, except for the percent sign (%). A non–white-space character causes scanf to read, but not store, a matching non–white-space character. If the next character in stdin does not match, scanf terminates.   Format specifications, introduced by the percent sign (%). A format specification causes scanf to read and convert characters in the input into values of a specified type. The value is assigned to an argument in the argument list.  The format is read from left to right. Characters outside format specifications are expected to match the sequence of characters in stdin; the matching characters in stdin are scanned but not stored. If a character in stdin conflicts with the format specification, scanf terminates, and the character is left in stdin as if it had not been read.  When the first format specification is encountered, the value of the first input field is converted according to this specification and stored in the location that is specified by the first argument. The second format specification causes the second input field to be converted and stored in the second argument, and so on through the end of the format string.  An input field is defined as all characters up to the first white-space character (space, tab, or newline), or up to the first character that cannot be converted according to the format specification, or until the field width (if specified) is reached. If there are too many arguments for the given specifications, the extra arguments are evaluated but ignored. The results are unpredictable if there are not enough arguments for the format specification.  Each field of the format specification is a single character or a number signifying a particular format option. The type character, which appears after the last optional format field, determines whether the input field is interpreted as a character, a string, or a number.   The simplest format specification contains only the percent sign and a type character (for example, %s). If a percent sign (%) is followed by a character that has no meaning as a format-control character, that character and the following characters (up to the next percent sign) are treated as an ordinary sequence of characters, that is, a sequence of characters that must match the input. For example, to specify that a percent-sign character is to be input, use %%.  An asterisk (*) following the percent sign suppresses assignment of the next input field, which is interpreted as a field of the specified type. The field is scanned but not stored.

在每个最后不带\n的printf后面加fflush(stdout); 在每个不想受接收缓冲区旧内容影响的scanf前面加rewind(stdin); 另外请检查scanf的返回值。 //请今后要用 char c; scanf("%c",&c); //时，都改为 char s[2]; char c; scanf("%1s",s); c=s[0]; //自动跳过一个或多个空格或Tab字符或回车换行，读取下一个字符。

'\n'代表空格，所以你要先输入数字，再输入一个字符，也就是再次输入一个值

去掉scanf中的'\n'，然后编译运行一下，就是一个值了。 scanf输入时，除了输入对应%d, 还要输入去匹配'\n'


Question: c语言中的数组初始化

谢谢，学习了！

运算需要在栈操作，即需要在函数内； 可以在函数外定义变量，定义的变量是全局的，定义的全局变量，默认会给初始化0；即如果不是显示的初始化，那么系统也会给全局的变量初始化位0； 不过，仅仅是初始化；但是初始化后的赋值就不行，需要在函数里才行；


Question: makefile能否实现自动去编译需要的lib

引用 2 楼 cfjtaishan 的回复:makefile是可以，既然a.cpp要用到B.so，倒不如每次都去编译一次。 这样可以做到，感谢！！！

引用 2 楼 cfjtaishan 的回复:makefile是可以，既然a.cpp要用到B.so，倒不如每次都去编译一次。 编译之后注意要将B.so放到a.cpp能够找到的位置。

makefile是可以，既然a.cpp要用到B.so，倒不如每次都去编译一次。

应该可以，Makefile不是有个依赖关系吗：   B.so: ... 	make -C /usr/B all: a.c,b.c,B.so 	...   我猜测的，没试过，你试试看。


Question: 利用线索二叉树进行查找树中的某个结点，求大神们看看，在线等急急急

引用 2 楼 paschen的回复:t->lchild = (*s)->data 这种赋值将导致错误，右边是char类型，左边是tree*类型，完全不同的两种类型 非常感谢！那应该该怎么改？

崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。

这个可以了  #include "stdio.h"     #include "stdlib.h" #include "memory.h" #define  FALSE 0 #define  TRUE  1 typedef struct tree   {      	char data;     	struct tree *lchild;     	struct tree *rchild; 	char s;  }*Ptree;     Ptree createTree()   //树的建立   {     	char ch;     	Ptree t;     	ch=getchar();  //输入二叉树数据  	if( ch == ' ' || ch == '\n' || ch == '\r' || ch == '\0')  //判断二叉树是否为空   	{ 		t=NULL; 	} 	else    	{     		t=(Ptree)malloc(sizeof(tree));  //二叉树的生成   		memset(t, 0, sizeof(tree)); 		t->data=ch;     		t->lchild=createTree(); // 这里递归调用会导致输入大量的空格才能结束 		t->rchild=createTree(); // 这里递归调用会导致输入大量的空格才能结束 	} 	return t; }      void preOrder(Ptree t)  //先序遍历    {     	if(t)     	{       		printf("%c",t->data);     		preOrder(t->lchild);     		preOrder(t->rchild);     	}     }      void intOrder(Ptree t)  //中序遍历     {     	if(t)     	{     		intOrder(t->lchild);     		printf("%c",t->data);     		intOrder(t->rchild);     	}     }      void postOrder(Ptree t)  //后序遍历     {     	if(t)     	{        		postOrder(t->lchild);     		postOrder(t->rchild);    		printf("%c",t->data);     	}     }      int Find(Ptree s, char chFind)  { 	if(s->data == chFind)  	{ 		return TRUE; 	} 	else if (Find(s->lchild, chFind))  	{ 		return TRUE; 	} 	else  	{ 		return Find(s->rchild, chFind); 	} }   int main()     {   	Ptree t; 	char chFind; 	printf("先序创建二叉树,用空格代表虚结点：\n");   	t=createTree();    	printf("前序遍历\n");   	preOrder(t) ;   	printf("\n");   	printf("中序遍历：\n");   	intOrder(t);   	printf("\n");   	printf("后序遍历：\n");     	postOrder(t);     	printf("\n"); 	printf("请输入要查找的结点:\n"); 	while(1)  // 防止前面输入的空格，结束符过多引起查找非法字符 	{ 		chFind=getchar (); 		if (chFind != ' ' && chFind != '\r' && chFind != '\n' && chFind !='\0')  		{ 			printf("查找 %c\n", chFind); 			break; 		} 	} 	 	if (Find(t, chFind))  	{ 		printf("找到\n"); 	} 	else  	{ 		printf("未找到\n"); 	} 	system("pause");   }

问题列表如下： 问题1：createTree()函数内： t=(Ptree)malloc(sizeof(struct tree));  //malloc struct tree 这儿应该申请struct tree，而不是Ptree，因为Ptree是指针； 问题2：find函数内，t是局部变量并且没有初始化，属于野指针，因此不能操作t->data， t->lchild等 二叉树的根指针应该通过参数传进来；另外，find函数返回bool类型，但是调用时没有意义，没有使用返回值。 是不是还没完全写完的程序？！  问题3：main函数里，s是Ptree类型，而getchar();是返回char类型；  #include <stdio.h> #include <stdlib.h> #define  FALSE 0 #define  TRUE  1 typedef struct tree {      char data;     struct tree *lchild;     struct tree *rchild;     char s;  }*Ptree;  Ptree createTree()   //树的建立 {     char ch;     Ptree t;     ch=getchar();  //输入二叉树数据      if(ch == ' ')  //判断二叉树是否为空         t = NULL;     else     {         t=(Ptree)malloc(sizeof(struct tree));  //malloc struct tree         t->data = ch;         t->lchild=createTree();         t->rchild=createTree();     }     return t; }  void preOrder(Ptree t)  //先序遍历 {     if(t)     {         printf("%c",t->data);         preOrder(t->lchild);         preOrder(t->rchild);     } }  void intOrder(Ptree t)  //中序遍历 {     if(t)     {         intOrder(t->lchild);         printf("%c",t->data);         intOrder(t->rchild);     } }  void postOrder(Ptree t)  //后序遍历 {     if(t)     {         postOrder(t->lchild);         postOrder(t->rchild);         printf("%c",t->data);     } }  int Find(Ptree t, char s) {     if (!t)         return FALSE;     else if (t->data == s)         return TRUE;     else {         return Find(t->lchild, s);         return Find(t->rchild, s);     } }   int main() {     char s;     Ptree t;     printf("先序创建二叉树,用空格代表虚结点：\n");     t=createTree();     printf("前序遍历\n");     preOrder(t) ;     printf("\n");     printf("中序遍历：\n");     intOrder(t);     printf("\n");     printf("后序遍历：\n");     postOrder(t);     printf("\n");     printf("请输入要查找的结点:\n");     s = getchar ();     int ret = Find(t, s);     if (ret)         printf("Yes!\n");     else         printf("No\n");     system("pause");     return 0; }  参考一下吧

希望大神看看，求指导


Question: 小白请教。。运行错误  run error  看不出来

引用 4 楼 cfjtaishan 的回复:scanf("%d", &evenNum); scanf的参数不对；  #include<stdio.h> int main(void) {     int evenNum,i,j,k,m;     //define even number and two numbers from it     printf("please input a even number from 2~2000000000:");     scanf("%d", &evenNum);        for(i=2;i<evenNum;i++)     {         for(j=2;j<i;j++)         {             if(i%j==0) break;             if(i%j!=0)                 printf(" ");         }         break;     }     printf("%d\n",i);     k=evenNum-i;     for(m=2;m<k;m++)     {         if(k%m==0) break;         if(k%m!=0)             printf(" ");     }     printf("%d\n",k);     evenNum=i+k;     if(i<=k)         printf("%d=%d+%d\n",evenNum,i,k);     else         printf("%d=%d+%d\n",evenNum,k,i);     return 0; }  printf中记着加'\n'，不然输出的内容容易混淆；                嗯知道了  谢谢  但程序若k不为质数应该怎样开始重新循环  这个是错的 好像

输入取地址。

scanf("%d",&evenNum);  for循环的break看一下位置。m,k变量的使用，在查看一下。

scanf("%d",&evenNum);

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。


Question: 用while就死循环，用if就没问题，为什么？while和if功能不是一样的吗？各大牛指教一下，新手

因为while里面没有修改x本身的值，在第一个while里面就永远无法退出循环了。。何况你还有递归！

while是循环 执行一次后会再次判断是否符合条件 符合条件继续执行while内 if不是循环只是条件判断 判断一次后符合条件只运行一次 不符合条件直接跳过

#include <stdio.h> #include <unistd.h>  void deczoct(int x) {     if (x > 8) {         deczoct(x/8);     }     printf("%d", x%8); }  int main(void) {     int num;      scanf("%d", &num);      printf("After cout: \n");     deczoct(num);     putchar(10);     return 0; } 参考一下吧  楼主的主要是while循环里没有修改x的值，导致无法停止第二次调用本身。

递归没有结束条件。

哪里一样了啊，一个是循环一个是判断 你记错了吧，while和for还差不多

“给定一个小点的输入，完整单步跟踪(同时按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史)一遍。”是理解递归函数工作原理的不二法门！ 递归函数关注以下几个因素 ·退出条件 ·参数有哪些 ·返回值是什么 ·局部变量有哪些 ·全局变量有哪些 ·何时输出 ·会不会导致堆栈溢出

while是一只判断-if只判断一次

你没有改变x的值  if执行一次就往下执行了 while执行完 条件还满足 继续执行呗


Question: 为什么在字符数组中遇到空格就停止了呢

如果一个字符数组中包含一个以上‘\0’，则遇到第一个\0就输出结束。

用scanf %s遇到空格确实就停了，标准是这样描述的：matches a sequence of non-whitespace characters (a string)，If width specifier is used, matches up to width or until the first whitespace character, whichever appears first. Always stores a null character in addition to the characters matched (so the argument array must have room for at least width+1 characters)，如果你需要读取空格就需要使用其他函数

引用 1 楼 A_short 的回复:把那个空格换成其他的就可以输出   但是空格为什么不行 因为scanf是格式化输入，以空格作为分割多个变量输入；即输入空格表示上一个变量输入的结束；  如果想输入一行然后结束，中间还要可以加若干空格字符；可以考虑使用fgets函数，该函数是遇到换行符（即回车符）结束输入；

引用 7 楼 cfjtaishan 的回复:[quote=引用 2 楼 qq_38204686 的回复:] 空格相当于字符串的结尾 这个结论似乎没有依据 scanf是格式化输入，那么空格是结束上一个变量的输入；[/quote] 字符串的结尾应该是'\0'吧

引用 2 楼 qq_38204686 的回复:空格相当于字符串的结尾 这个结论似乎没有依据 scanf是格式化输入，那么空格是结束上一个变量的输入；

解释：scanf + %s 从标准输入读取一串字符，遇回车或空格结束。这个由scanf库函数的定义决定的。 解决：1.使用gets(str);            2.用while循环getchar(),赋值给数组。ASCII码判断回车结束。

建议使用可以读取空格的函数  详情百度 很多

空格相当于字符串的结尾

把那个空格换成其他的就可以输出   但是空格为什么不行


Question: 关于C语言中getchar()的使用困惑？

原来是自己的逻辑错误了，非常感谢

见注释 #include <stdio.h>  #define IN  1 #define OUT 0  int main() { 	int c, nc, nl, nw, state;  	state = OUT; 	nc = nl = nw = 0; 	while ((c = getchar()) != EOF) 	{ 		++nc; 		if (c == '\n') 			++nl; 		if (c == ' ' || c == '\n' || c == '\t') 			state = OUT;         /* 这里为什么要else呢，应该直接判断state吧 */ 		else if (state == OUT) 		{ 			state = IN; 			++nw; 		} 	}  	printf("nl = %d, nw = %d, nc = %d\n", nl, nw, nc); 	return 0; }

因为从一开始到遇到'\n'||’\t'||' '只有一次；输入完回车符'\n'就输入EOF了。所以只有一个单词；


Question: 字符串中的字符无效问题

s1和s2先进行初始化。  char s1[21] = { '\0' }; char s2[21] = { '\0' };

结贴了吗？似乎上面几个人回答的驴唇不对马嘴啊。。。

字符串没有找到'\0'，这个是字符串的结束标记；字符'0'和'\0'还是有区别的。他们对应的ASCII值分别是0和48  解决办法是  for (index = 0; index <= len1 + len2; index++)     result[index] = '\0';    /*也可以赋值0*/

因为给字符串赋值的是'0',‘0’的ASC码值是48，不是字符串的结束符,字符数组没有结束符当然不能是字符串了。

定义时初始化为{}相当于没有初始化啊

char s1[21] = { '\0' }; char s2[21] = { '\0' };  for （index = 0; index <= len1 + lne2; index++)   result[index] = '0'; //显示字符‘0’，与下面的结束符不同  result[len1 + lne2 + 1] = '\0'; //加上字符串结束符  不加则为分配内存时的垃圾值，系统显示字符串时直到有结束符为止，即使是越界非法访问也必须到结束符为止


Question: Acm二哥种花生c语言版求指导为什么不对

http://blog.csdn.net/zhonghua123/article/details/22721361 建议参考一下别人的; http://blog.csdn.net/lmw21848/article/details/51072918


Question: C语言 不知道哪有问题

输出没有加实参。

引用 3 楼 自信男孩的回复:#include<stdio.h> #include<math.h> #include<string.h>  int max(int arr[10], int len); int min(int arr[10],int len); float ave(int arr[10], int len);  //100 10 -125 -9 90 70 60 300 -250 0 int main() {     int arr[10];     printf("qing shu ru shi ge shu zi:\n");     int i;     for(i=0;i<10;i++)     {         scanf("%d",&arr[i]);     }     printf("max = %d \n",max(arr, 10));     printf("min = %d \n",min(arr, 10));     printf("ave = %lf \n",ave(arr, 10));      return 0; } int max(int arr[10],int len) {     int max = arr[0], i;     for(i = 1;i<len;i++)         if(arr[i]>max)             max=arr[i];     return(max); } int min(int arr[10],int len) {     int min=arr[0], i;     for(i = 1; i < len;i++)         if(arr[i]<min)             min=arr[i];     return(min);  } float ave(int arr[10],int len) {     int sum=0, i;     float ave;      for(i=0;i<10;i++)     {         sum=sum+arr[i];     }     ave = sum * 1.0/10;     return(ave); } 函数定义，声明和调用都有自己的语法规则，建议好好研究一下语法； 能在函数内定义的变量，不建议通过参数传递；否则参数多了影响函数调用的效率，自然影响程序的运行效率，同样是局部变量，在函数内定义可以减少实参的传递;  函数的定义也是需要有章法，通过精心设计出来的函数通用性，可移植性会比较好， 大佬  这个int len 是直接用的吗 不用事先测定一下吗？ 还有那个printf里面的max括号里面的为什么不写len而写10 还有 我试了吧那个声明函数写在main里面也可以运行 求解

引用 3 楼 自信男孩的回复:#include<stdio.h> #include<math.h> #include<string.h>  int max(int arr[10], int len); int min(int arr[10],int len); float ave(int arr[10], int len);  //100 10 -125 -9 90 70 60 300 -250 0 int main() {     int arr[10];     printf("qing shu ru shi ge shu zi:\n");     int i;     for(i=0;i<10;i++)     {         scanf("%d",&arr[i]);     }     printf("max = %d \n",max(arr, 10));     printf("min = %d \n",min(arr, 10));     printf("ave = %lf \n",ave(arr, 10));      return 0; } int max(int arr[10],int len) {     int max = arr[0], i;     for(i = 1;i<len;i++)         if(arr[i]>max)             max=arr[i];     return(max); } int min(int arr[10],int len) {     int min=arr[0], i;     for(i = 1; i < len;i++)         if(arr[i]<min)             min=arr[i];     return(min);  } float ave(int arr[10],int len) {     int sum=0, i;     float ave;      for(i=0;i<10;i++)     {         sum=sum+arr[i];     }     ave = sum * 1.0/10;     return(ave); } 函数定义，声明和调用都有自己的语法规则，建议好好研究一下语法； 能在函数内定义的变量，不建议通过参数传递；否则参数多了影响函数调用的效率，自然影响程序的运行效率，同样是局部变量，在函数内定义可以减少实参的传递;  函数的定义也是需要有章法，通过精心设计出来的函数通用性，可移植性会比较好， 大神 我想问下  这里的len是直接用的吗？ 还有  printf里面的 max（max，10）的 10是什么意思 为什么不是len

下面这三行输出的只是函数的地址，并非函数返回的结果，如果需要返回的结果，你需要在后面加上参数  printf("max = %d \n",max); printf("min = %d \n",min); printf("ave = %lf \n",ave);  其次，max和min建议换个名字，否则可能和标准库听宏重名导致编译失败

你没弄清函数声明定义和调用： 问题： int max(int arr[10],int i,int max); int min(int arr[10],int i,int min); float ave(int arr[10],int i,float ave,float sum);   这三行是函数声明，  应该放在main函数之前  a = max(arr, 0, 0) b = min(arr, 0, 10) c = ave(arr, 0, 0.0, 0.0)   这三行是函数调用。如果函数没有返回值，就不用前面的 a = ，b=，c=  修改： 1.把你那三行函数定义放在main之前。 2.printf("max = %d \n", max(arr, 0, 0));    printf("min = %d \n", min(arr, 0, 10));    printf("ave = %lf \n", ave(arr, 0, 0.0, 0.0)); 3.根据你这三个函数功能来看，不需要这么多变量传入。只需要数组进去。在函数体内部申请变量返回值即可。  看书要仔细。尤其是示例代码。


Question: 求大神指导下为什么在输入之后二叉树不能输出结果

你的程序里要求输入空格终止递归，你输入#，那怎么停止递归呢？！ 要么输入空格，要么改一下程序里的判断：  if (c == '#')     t = NULL;

就是进行不了遍历操作


Question: 新人求助，最简单的printf与scanf

scanf("%s", &ch);应该用z%c输入，第二个scanf时候，会把换行键输入到第二个scanf中

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。

#include <stdio.h>   int main(void) {   int N;   char ch;    printf("&N = %p\n", &N);   printf("&ch = %p\n", &ch);   printf("&ch +1 = %p\n", &ch+1);   puts("Please scanf your character and your character numbers.");   scanf("%d",&N);   getchar();   scanf("%s", &ch);   printf("%d", N);   //challeng(N,'*');   return 0; } 通过地址查看为什么是0； 还有一点，如果你输入的数值较大，比如输入大于255，那么输出的N也不是你输入的，但是也不会是0；

接收ch的时候越界了，覆盖了N的值，如果你只输入一个字符，这个字符串加上结尾的\0一共有两字节，就要写成：char ch[2];  如果你要输入更多的，那还要更大

引用 1 楼 weixin_40926388 的回复:第一个输入后面加个   fflush(stdin);  试试   scanf("%d",&N);  fflush(stdin);  scanf("%s", &ch);  printf("%d", N); fflush(stdin);对于某些系统是无效的，即fflush不能清除stdin里数据； 另外，以%s输入，也无需清除stdin里的数据。  %s输入，即字符串；ch只有一个字节，怎么能存放字符串呢？

#include <stdio.h>   int main(void) {   int N;   char ch;   puts("Please scanf your character and your character numbers.");   scanf("%d",&N);   getchar();   scanf("%c", &ch);   printf("%d", N);   //challeng(N,'*');   return 0; } 应该用%c格式输入； 若以%s，那么会越界；因为字符串要求以'\0'结束，那么输入一个字符后，ch就没有空间存放'\0'了。


Question: CFree5怎么把输出结果保存到文件里面？

引用 6 楼 zhiqiu 的回复:引用 3 楼 zhao4zhong1 的回复:现在的码农竟然99%都不会在cmd窗口中输入cd命令设置当前目录为程序所在目录，输入程序名运行程序了！许久不写代码了，以为IDE工具会提供功能的，已经在命令行下重定向结果了。 推荐阅读《Unix编程艺术》

引用 4 楼 paschen 的回复:重写向到文本文件中，之后在文件中查看 就是没找到在哪设置？这个软件没这个功能吗？

重写向到文本文件中，之后在文件中查看

使用命令重定向操作符可以使用重定向操作符将命令输入和输出数据流从默认位置重定 向到不同的位置。输入或输出数据流的位置即为句柄。  下表将列出可用的句柄。  句柄      句柄的数字代号 描述 STDIN     0              键盘输入 STDOUT    1              输出到命令提示符窗口 STDERR    2              错误输出到命令提示符窗口 UNDEFINED 3-9            这些句柄由应用程序单独定义，并且是各个工具特定的。  数字 0 到 9 代表前 10 个句柄。可以使用命令 Cmd.exe 运行程序并将该程序前 10 个 句柄中的任何一个重定向。要指定想使用的句柄，可在重定向操作符前面键入该句柄的 数字。如果未定义句柄，则默认的 < 重定向输入操作符是 0，而默认的 > 重定向输出 操作符是 1。键入 > 或 < 操作符之后，必须指定要读取或写入数据的位置。可以指定 文件名或另一个现有的句柄。  要指定重定向到现有句柄，请使用与 (&) 字符，后面接要重定向的句柄号 （例如 &句柄#）。例如，下面的命令可以将句柄 2（即 STDERR）重定向到 句柄 1（即 STDOUT）：  2>&1  下表列出了可用于将输入和输出数据流进行重定向的操作符。  重定向操作符 描述 > 将命令输出写入到文件或设备（例如打印机）中，而不是写在命令提示符窗口或句柄中。 < 从文件中而不是从键盘或句柄中读入命令输入。 >> 将命令输出添加到文件末尾而不删除文件中的信息。 >& 将一个句柄的输出写入到另一个句柄的输入中。 <& 从一个句柄读取输入并将其写入到另一个句柄输出中。 | 从一个命令中读取输出并将其写入另一个命令的输入中。也称作管道。  默认情况下，可以从键盘将命令输入（即 STDIN 句柄）发送到 Cmd.exe，然后由 Cmd.exe 将命令输出（即 STDOUT 句柄）发送到命令提示符窗口。  重定向输入 (<) 要将键盘输入重定向到文件或设备，请使用 < 操作符。例如，要从 File.txt 获取 sort 命令的输入，请键入：  sort<file.txt  File.txt 的内容将以字母顺序列表的方式显示在命令提示符窗口中。  < 操作符可以打开具有只读访问的指定文件名。所以，不能使用该操作符向文件中写入 信息。例如，如果以 <&2 启动程序，则所有试图读取句柄 0 的操作都将失败，因为句 柄 2 最初是以只写访问打开的。   注意  0 是 < 重定向输入操作符的默认句柄。 重定向输出 (>) 几乎所有的命令都将输出发送到命令提示符窗口。即使将输出发送到驱动器或打印机的 命令也会在命令提示符窗口显示消息和提示。  要将输出从命令提示符窗口重定向到文件或设备，请使用 > 操作符。可以在许多命令中 使用该操作符。例如，要将 dir 输出重定向到 Dirlist.txt，请键入：  dir>dirlist.txt  如果 Dirlist.txt 不存在，Cmd.exe 将创建该文件。如果 Dirlist.txt 存在，Cmd.exe 将使用 dir 命令的输出替换文件中的信息。  要运行 netsh routing dump 命令，然后将输出发送到 Route.cfg，请键入：  netsh routing dump>c:\route.cfg  > 操作符可以打开具有只写访问属性的指定文件。所以，不能使用该操作符读取文件。 例如，如果使用重定向 >&0 启动程序，则所有试图写入句柄 1 的操作都将失败，因为 句柄 0 最初是以只读访问打开的。   注意  1 是 > 重定向输出操作符的默认句柄。 复制句柄 重定向操作符 & 可以将输出或输入从一个指定句柄复制到另一个指定的句柄。例如， 要将 dir 输出发送到 File.txt 并将错误输出发送到 File.txt，请键入：  dir>c:\file.txt 2>&1  复制句柄时，可以复制该句柄原状态的所有特性。例如，如果一个句柄具有只写访问的 属性，则该句柄的所有副本都具有只写访问属性。不能将一个具有只读访问属性的句柄 复制到另一个具有只写访问属性的句柄。  使用 & 操作符重定向输入和副本 要将重定向输入操作符 (<) 与复制操作符 (&) 一起使用，指定的文件必须已经存在。 如果输入文件存在，Cmd.exe 将以只读方式打开该文件，然后将文件中包含的字符作为 输入发送到此命令（如同从键盘输入一样）。如果指定了句柄，Cmd.exe 将指定的句柄 复制到系统现有的句柄中。  例如，要以句柄 0 输入读取（即 STDIN）的方式打开 File.txt，请键入：  <file.txt  要打开 File.txt，并在内容排序后将输出发送到命令提示符窗口（即 STDOUT），请键入：  sort<file.txt  要查找 File.txt，然后将句柄 1（即 STDOUT）和句柄 2（即 STDERR）重定向到 Search.txt，请键入：  findfile file.txt>search.txt 2<&1  要以句柄 0 输入读取（即 STDIN）的方式复制用户定义句柄 3，请键入：  <&3  使用 & 操作符重定向输出和复制 如果将输出重定向到文件且指定了现有的文件名，Cmd.exe 将以只写方式打开文件并覆 盖该文件内容。如果指定了句柄，Cmd.exe 将文件复制到现有句柄中。  要将用户定义句柄 3 复制到句柄 1，请键入：  >&3  要将包括句柄 2（即 STDERR）的所有输出从 ipconfig 命令重定向到 句柄 1（即 STDOUT），然后将输出重定向到 Output.log，请键入：  ipconfig.exe>>output.log 2>&1  使用 >> 重定向操作符追加输出 要从命令中将输出添加到文件末尾而不丢失文件中已存在的任何信息，请使用两个连续 的大于号（即 >>）。例如，下面的命令可以将由 dir 命令生成的目录列表追加到 Dirlist.txt 文件：  dir>>dirlist.txt  要将 netstat 命令的输出追加到 Tcpinfo.txt 的末尾，请键入：  netstat>>tcpinfo.txt  使用管道操作符 (|) 管道操作符 (|) 可以提取一个命令的输出（默认情况下是 STDOUT），然后将其导入另 一个命令的输入中（默认情况下是 STDIN）。例如，下面的命令将对目录分类：  dir | sort  在本例中，将同时启动两个命令，但随后 sort 命令会暂停，直到它接收到 dir 命令 的输出为止。sort 命令使用 dir 命令的输出作为输入，然后将输出发送到 句柄 1（即 STDOUT）。  合并带重定向操作符的命令 可以通过合并带有其他命令和文件名的筛选器命令创建自定义命令。例如，可以使用以 下命令存储包含“LOG”字符串的文件名:  dir /b | find "LOG" > loglist.txt  dir 命令的输出通过 find 筛选器命令发送。包含字符串 "LOG" 的文件名作为文件名 列表（例如，NetshConfig.log、Logdat.svd 和 Mylog.bat）存储在文件 Loglist.txt 中。  要在相同命令中使用多个筛选器，请使用管道 (|) 分隔筛选器。例如，下面的命令将 搜索 C 盘上的每个目录以查找包含 "LOG" 字符串的文件名，并且在命令提示符窗口中 每次显示一屏：  dir c:\ /s /b | find "LOG" | more  利用管道 (|) 可以将 Cmd.exe 导向为通过 find 筛选器命令发送 dir 命令输出。 find 命令只选择包含字符串 "LOG" 的文件名。more 命令可以显示由 find 命令选择 的文件名（在命令提示符窗口中每次显示一屏）。有关筛选器命令的详细信息，请参阅 使用筛选器。

怎么只看到后面的，看不到前面的？覆盖了吗？如果是设备，可以接串口或用secCRT工具，telnet上去或者串口直接链接。该工具可以保存至文件； 在程序里写文件，也是一种办法，但是会影响程序，但影响不是很大；如果可行，还是考虑使用工具；


Question: C语言问题

数组中括弧里的值

你就想成数组里的值好了

p+i表示p偏移i个单位地址，这个单位跟p的类型有关，这里p是char *，所以即p指针偏移多少个字节，相当于数组下标的作用。

谢谢各位   懂了

A[B] *(A+B) *(B+A) B[A] //以上四行等价  "abc"[1] *("abc"+1) *(1+"abc") 1["abc"] //以上四行等价  A[0] *(A) 0[A] //以上三行等价

i是偏移量，比如(p+i)是指偏移i个sizeof(char)字节，也就是相对于数组首地址偏移i个字节；


Question: 在头文件定义引起重复定义的问题。

const char const * pchar = "aaa";

VS下是没问题的，当然建议你把这些全局变量放到一个CPP文件，其他文件使用再用extern进行声明

用vs编译的时候构造函数有问题，demo();函数改成demo(){};

不科学啊，看起来没问题的。

引用 2 楼 cfjtaishan 的回复:如果只是两个文件，以头文件，一个main.cpp源文件，不会出现这样的错误； 如果还出，建议加上extern 嗯嗯嗯嗯嗯

。。。如果你的代码真是这样，应该是没有错误，至少我这是编译通过了。。。  multiple definition of 问题一般是多个文件包含同一个头文件。。。.


Question: 初学者的问题。

t*t=-(t*t); t*t是不能被赋值的。

12-22+32-42+...-202 ===》 12-（22-32）-（42-52）.。。202 ==》 12+10+10.。。。。

仅供参考：/*--------------------------------------- 函数型计算器(VC++6.0,Win32 Console) 功能： 目前提供了10多个常用数学函数:     ⑴正弦sin     ⑵余弦cos     ⑶正切tan     ⑷开平方sqrt     ⑸反正弦arcsin     ⑹反余弦arccos     ⑺反正切arctan     ⑻常用对数lg     ⑼自然对数ln     ⑽ｅ指数exp     ⑾乘幂函数^     ⑿向上取整ceil     ⒀向下取整floor     ⒁四舍五入取整round 用法： 如果要求2的32次幂，可以打入2^32<回车> 如果要求30度角的正切可键入tan(Pi/6)<回车> 注意不能打入：tan(30)<Enter> 如果要求1.23弧度的正弦，有几种方法都有效： sin(1.23)<Enter> sin 1.23 <Enter> sin1.23  <Enter> 如果验证正余弦的平方和公式,可打入sin(1.23)^2+cos(1.23)^2 <Enter>或sin1.23^2+cos1.23^2 <Enter> 此外两函数表达式连在一起,自动理解为相乘如：sin1.23cos0.77+cos1.23sin0.77就等价于sin(1.23)*cos(0.77)+cos(1.23)*sin(0.77) 当然你还可以依据三角变换，再用sin(1.23+0.77)也即sin2验证一下。 本计算器充分考虑了运算符的优先级因此诸如：2+3*4^2 实际上相当于：2+(3*(4*4)) 另外函数名前面如果是数字,那么自动认为二者相乘. 同理，如果某数的右侧是左括号，则自动认为该数与括弧项之间隐含一乘号。 如：3sin1.2^2+5cos2.1^2 相当于3*sin2(1.2)+5*cos2(2.1) 又如：4(3-2(sqrt5-1)+ln2)+lg5 相当于4*(3-2*(√5 -1)+loge(2))+log10(5) 此外，本计算器提供了圆周率Pi键入字母时不区分大小写,以方便使用。 16进制整数以0x或0X开头。 ----------------------------------------*/ #include <iostream> #include <iomanip> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <stdio.h> #include <string.h> #include <windows.h> using namespace std; const char Tab=0x9; const int  DIGIT=1; const int MAXLEN=16384; char s[MAXLEN],*endss; int pcs=15; double round(double dVal, short iPlaces) {//iPlaces>=0     char s[30];     double dRetval;      sprintf(s,"%.*lf",iPlaces,dVal);     sscanf(s,"%lf",&dRetval);     return (dRetval); } double fun(double x,char op[],int *iop) {     while (op[*iop-1]<32) //本行使得函数嵌套调用时不必加括号,如 arc sin(sin(1.234)) 只需键入arc sin sin 1.234<Enter>         switch (op[*iop-1]) {         case  7: x=sin(x);    (*iop)--;break;         case  8: x=cos(x);    (*iop)--;break;         case  9: x=tan(x);    (*iop)--;break;         case 10: x=sqrt(x);   (*iop)--;break;         case 11: x=asin(x);   (*iop)--;break;         case 12: x=acos(x);   (*iop)--;break;         case 13: x=atan(x);   (*iop)--;break;         case 14: x=log10(x);  (*iop)--;break;         case 15: x=log(x);    (*iop)--;break;         case 16: x=exp(x);    (*iop)--;break;         case 17: x=ceil(x);   (*iop)--;break;         case 18: x=floor(x);  (*iop)--;break;         case 19: x=round(x,0);(*iop)--;break;         }     return x; } double calc(char *expr,char **addr) {     static int deep; //递归深度     static char *fname[]={"sin","cos","tan","sqrt","arcsin","arccos","arctan","lg","ln","exp","ceil","floor","round",NULL};     double ST[10]={0.0}; //数字栈     char op[10]={'+'}; //运算符栈     char c,*rexp,*pp,*pf;     int ist=1,iop=1,last,i,n;     __int64 i64;      if (!deep) {         pp=pf=expr;         do {             c = *pp++;             if (c!=' '&& c!=Tab)                 *pf++ = c;         } while (c!='\0');     }     pp=expr;     if ((c=*pp)=='-'||c=='+') {         op[0] = c;         pp++;     }     last = !DIGIT;     while ((c=*pp)!='\0') {         if (c=='(') {//左圆括弧             deep++;             ST[ist++]=calc(++pp,addr);             deep--;             ST[ist-1]=fun(ST[ist-1],op,&iop);             pp = *addr;             last = DIGIT;             if (*pp == '('||isalpha(*pp) && strnicmp(pp,"Pi",2)) {//目的是：当右圆括弧的右恻为左圆括弧或函数名字时，默认其为乘法                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }         else if (c==')') {//右圆括弧             pp++;             break;         } else if (isalpha(c)) {             if (!strnicmp(pp,"Pi",2)) {                 if (last==DIGIT) {                     cout<< "π左侧遇）" <<endl;exit(1);                 }                 ST[ist++]=3.14159265358979323846264338328;                 ST[ist-1]=fun(ST[ist-1],op,&iop);                 pp += 2;                 last = DIGIT;                 if (!strnicmp(pp,"Pi",2)) {                     cout<< "两个π相连" <<endl;exit(2);                 }                 if (*pp=='(') {                     cout<< "π右侧遇（" <<endl;exit(3);                 }             } else {                 for (i=0; (pf=fname[i])!=NULL; i++)                     if (!strnicmp(pp,pf,strlen(pf))) break;                 if (pf!=NULL) {                     op[iop++] = 07+i;                     pp += strlen(pf);                 } else {                     cout<< "陌生函数名" <<endl;exit(4);                 }             }         } else if (c=='+'||c=='-'||c=='*'||c=='/'||c=='%'||c=='^') {             char cc;             if (last != DIGIT) {                 cout<< "运算符粘连" <<endl;exit(5);             }             pp++;             if (c=='+'||c=='-') {                 do {                     cc = op[--iop];                     --ist;                     switch (cc) {                     case '+':  ST[ist-1] += ST[ist];break;                     case '-':  ST[ist-1] -= ST[ist];break;                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 } while (iop);                 op[iop++] = c;             } else if (c=='*'||c=='/'||c=='%') { operate:        cc = op[iop-1];                 if (cc=='+'||cc=='-') {                     op[iop++] = c;                 } else {                     --ist;                     op[iop-1] = c;                     switch (cc) {                     case '*':  ST[ist-1] *= ST[ist];break;                     case '/':  ST[ist-1] /= ST[ist];break;                     case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;                     case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;                     }                 }             } else {                 cc = op[iop-1];                 if (cc=='^') {                     cout<< "乘幂符连用" <<endl;exit(6);                 }                 op[iop++] = c;             }             last = !DIGIT;         } else {             if (last == DIGIT) {                 cout<< "两数字粘连" <<endl;exit(7);             }             if (pp[0]=='0' && (pp[1]=='x'||pp[1]=='X')) {                 sscanf(pp+2,"%I64x%n",&i64,&n);                 rexp=pp+2+n;                 ST[ist++]=(double)i64;             } else ST[ist++]=strtod(pp,&rexp);             ST[ist-1]=fun(ST[ist-1],op,&iop);             if (pp == rexp) {                 cout<< "非法字符" <<endl;exit(8);             }             pp = rexp;             last = DIGIT;             if (*pp == '('||isalpha(*pp)) {                 op[iop++]='*';                 last = !DIGIT;                 c = op[--iop];                 goto operate ;             }         }     }     *addr=pp;     if (iop>=ist) {         cout<< "表达式有误" <<endl;exit(9);     }     while (iop) {         --ist;         switch (op[--iop]) {         case '+':  ST[ist-1] += ST[ist];break;         case '-':  ST[ist-1] -= ST[ist];break;         case '*':  ST[ist-1] *= ST[ist];break;         case '/':  ST[ist-1] /= ST[ist];break;         case '%':  ST[ist-1] = fmod(ST[ist-1],ST[ist]);break;         case '^':  ST[ist-1] = pow(ST[ist-1],ST[ist]);break;         }     }     return ST[0]; } int main(int argc,char **argv) {     int a;      if (argc<2) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算函数表达式的值。"<<endl<<"支持(),+,-,*,/,%,^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round"<<endl;         while (1) {             cout << "请输入表达式：";             gets(s);             if (s[0]==0) break;//             cout << s <<"=";             cout << setprecision(15) << calc(s,&endss) << endl;         }     } else if (argc==2 && 0==strcmp(argv[1],"/?")) {         if (GetConsoleOutputCP()!=936) system("chcp 936>NUL");//中文代码页         cout << "计算由≥1个命令行参数给出的函数表达式的值。\n"         "最后一个参数是.0～.15表示将计算结果保留小数0～15位\n"         "最后一个参数是x表示将计算结果以16进制正整数格式输出\n"         "支持(),+,-,*,/,%,^^,Pi,sin,cos,tan,sqrt,arcsin,arccos,arctan,lg,ln,exp,ceil,floor,round\n"         "16进制整数以0x或0X开头\n";     } else {         strncpy(s,argv[1],MAXLEN-1);s[MAXLEN-1]=0;         if (argc>2) {             for (a=2;a<argc-1;a++) strncat(s,argv[a],MAXLEN-1);//将空格间隔的各参数连接到s             if (1==sscanf(argv[a],".%d",&pcs) && 0<=pcs && pcs<=15) {//最后一个参数是.0～.15表示将计算结果保留小数0～15位                 printf("%.*lf\n",pcs,calc(s,&endss));             } else if (argv[a][0]=='x'||argv[a][0]=='X') {//最后一个参数是x表示将计算结果以16进制正整数格式输出                 printf("0x%016I64x\n",(__int64)calc(s,&endss));             } else {                 strncat(s,argv[a],MAXLEN-1);                 printf("%.15lg\n",calc(s,&endss));             }         } else {             printf("%.15lg\n",calc(s,&endss));         }     }     return 0; }

#include <stdio.h>  void main() {     int sum = 0,i,t;      for(i = 1; i <= 20; i++)     {         t = i * 10 + 2;         if(i%2 == 0)             t *= -1;         printf("%c%d",  t > 0 ? '+': ' ', t);         sum += t;     }     printf(" = %d\n", sum);      return 0; }

# include<stdio.h>  int main() { 	int sum=0,i,t; 	for(i=1;i<=20;i++) 	{ 		t=i; 		if(t%2==1) 		{ 			t=t*10+2; 			sum+=t; 		} 		else 		{ 			t=t*10+2; 			sum-=t; 		} 	} 	printf("%d\n",sum); }  ********************************* -100 Press any key to continue

#include "stdio.h"  void main() {     int sum=0,i,t;     for(i=1;i<=20;i++)     { 		t = i;     	if(t%2 == 1) 			sum += t*10 + 2; 		else  			sum -= t*10 + 2;     }     printf("%d",sum); }    结果  -100


Question: 想问一下EOF在控制输入的时候到底怎么才对，能否举个例子详细讲解一下

int ch;  while ((ch = getchar()) != EOF)     putchar(ch);  这个例子可以吗？ EOF文件描述符； 标准输入的EOF是通过键盘组合键输入的。 ctrl+d(Linux) or ctrl+z（Windows）


Question: keil开发

RX是什么？另一个线程会设置的变量？为啥不用信号量？

比如sem_wait(X)，在设置RX变量的线程里，RX的TRUE和FALSE分别用sem_post发送不同的信号，这样在sem_wait的地方如果条件暂时不成立就会休眠，比你这样执行循环要少占用多少CPU资源啊！  具体用法请查阅资料，手头没有具体代码。

RX是超声波Echo引脚，TX是Trig脚。如果用信号量，那要怎么写？

while不符合条件才向下执行是为了等待  数码管频率太低了吧

我在网上找的超声波的等待都是这种方式的，不知道有没有其他的

难道用这种方式实现等待？ 这种方式实现等待真是无语了。。


Question: 请教一个函数与指针的问题

引用 17 楼 zhao4zhong1 的回复:void Get_Latest_File_Name(char **p,int len){     char capBuf[128] = {0};     FILE *fp;     sprintf(capBuf,"tail -n1 /home/lei/mnt/leileilei |awk '{print $2}'");     fp = popen(capBuf, "r");     fgets(*p, len, fp);     pclose(fp); } int main() {     char Buf[256];     char *pBuf=(char *)Buf;     Get_Latest_File_Name(&pBuf,256);     printf("%s\n",pBuf);     return 0; }   谢谢赵四老师，可以编过了也和我想要的结果一样。就是水平太低得消化消化。。再次谢谢

学到老活到老，学习到了

引用 11 楼 paschen 的回复:那函数参数要用char**二级指针，如写成char**p  函数中加上 *p = tabBuf;  main中定义char* pBuf，并用&pBuf作为参数调用函数即可   char Get_Latest_File_Name(char **p){         char capBuf[128] = {0};         char tabBuf[128] = {0};         *p = tabBuf;         FILE *fp = NULL;         sprintf(capBuf,"tail -n1 /home/lei/mnt/leileilei |awk '{print $2}'");         fp = popen(capBuf, "r");         fgets(tabBuf, sizeof(tabBuf), fp);         pclose(fp);         //printf("%s\n",tabBuf); }  int main(){         char *pBuf;         char *result;         result = &pBuf;         printf("%s\n",result); }   请您看一眼是这样子吗

引用 13 楼 cfjtaishan 的回复:[quote=引用 4 楼 m0_38117705 的回复:] [quote=引用 1 楼 cfjtaishan 的回复:]  char* Get_Latest_File_Name() {     char capBuf[128] = {0};     static char tabBuf[128] = {0};     FILE *fp = NULL;     sprintf(capBuf,"tail -n1 %s | awk '{print $2}'" MD5FILE);     fp = popen(capBuf, "r");     while(fgets(tabBuf, 34, fp)!=NULL){     }     pclose(fp);     return tabBuf; } 加static是为了影响tabBuf的生命周期，因为加了static之后，tabBuf是静态数组，在数据段上申请空间（而不是在栈上），返回栈上的空间是未定义行为； 也可以定义成指针，但是必须在堆上申请空间，因为堆上的空间生命周期也是从申请开始知道释放结束；即调用malloc和free函数（C++中也可以用new/delete） 使用完之后需要free，在该函数外释放；一般很容易忘释放；  使用static和堆上申请空间两种方法都是可以实现你的需求；但是也是有区别的；  使用static也是我研究了好久的办法，但是给别人看别人讲使用static的话虽然能得到想要的结果，但是并不是特别好，建议指针传参什么的。您能给点建议吗[/quote] 如果这个缓存里的数据相一致保存，那么可以考虑定义全局数组；如果是缓存里的数据只是用一下，可以考虑malloc/free或new/delete 当然也是可以用参数传递的方法，即定义一个形参，指针形式。然后将数据保存到这个指针指向的缓存里。实参可以考虑用一个数组；[/quote]  我试了半天，在网上看的也都看不明白，能麻烦您帮我指出关键部分的代码吗，想要通过参数传递的方法拿到一个值，以用于在main中拼接成新的指令

引用 4 楼 m0_38117705 的回复:[quote=引用 1 楼 cfjtaishan 的回复:]  char* Get_Latest_File_Name() {     char capBuf[128] = {0};     static char tabBuf[128] = {0};     FILE *fp = NULL;     sprintf(capBuf,"tail -n1 %s | awk '{print $2}'" MD5FILE);     fp = popen(capBuf, "r");     while(fgets(tabBuf, 34, fp)!=NULL){     }     pclose(fp);     return tabBuf; } 加static是为了影响tabBuf的生命周期，因为加了static之后，tabBuf是静态数组，在数据段上申请空间（而不是在栈上），返回栈上的空间是未定义行为； 也可以定义成指针，但是必须在堆上申请空间，因为堆上的空间生命周期也是从申请开始知道释放结束；即调用malloc和free函数（C++中也可以用new/delete） 使用完之后需要free，在该函数外释放；一般很容易忘释放；  使用static和堆上申请空间两种方法都是可以实现你的需求；但是也是有区别的；  使用static也是我研究了好久的办法，但是给别人看别人讲使用static的话虽然能得到想要的结果，但是并不是特别好，建议指针传参什么的。您能给点建议吗[/quote] 如果这个缓存里的数据相一致保存，那么可以考虑定义全局数组；如果是缓存里的数据只是用一下，可以考虑malloc/free或new/delete 当然也是可以用参数传递的方法，即定义一个形参，指针形式。然后将数据保存到这个指针指向的缓存里。实参可以考虑用一个数组；

引用 20 楼 zhao4zhong1 的回复:fgets(*p, len, fp);if ('\n'==(*p)[strlen(*p)-1]) (*p)[strlen(*p)-1]=0; 添加红色语句，去掉行末的换行符。  赵四老师好厉害，谢谢您

引用 17 楼 zhao4zhong1 的回复:void Get_Latest_File_Name(char **p,int len){     char capBuf[128] = {0};     FILE *fp;     sprintf(capBuf,"tail -n1 /home/lei/mnt/leileilei |awk '{print $2}'");     fp = popen(capBuf, "r");     fgets(*p, len, fp);     pclose(fp); } int main() {     char Buf[256];     char *pBuf=(char *)Buf;     Get_Latest_File_Name(&pBuf,256);     printf("%s\n",pBuf);     return 0; }        Get_Latest_File_Name(&Latest_File,7);     sprintf(import,"sed -i '/%s/d' %s ",Latest_File,MD5FILE);     printf("%s\n",import);  打印出的结果： sed -i '/1.sql /d' /home/lei/mnt/leileilei    赵四老师，现在又出个问题，如果把7的那个位置设置大了的话会出现多余的换行符，能请问一下怎么解决吗，因为获取到的结果有可能是5位也有可能是6位，所以会有一点小问题造成指令出错

引用 9 楼 paschen 的回复:你函数已经返回了一个指向这个静态数组变量的指针，直接使用这个指针就行  char* Get_Latest_File_Name(在这里设置一个指针什么的){  char capBuf[128] = {0}; static char tabBuf[128] = {0}  对现在是完全可以使用，这个函数可以按照预想的获取到一个字符串。然后在main函数中拼接成一个新的命令。就是教我的人项要我在上边我指出那个位置那里好像是要我做个指针然后在main函数中使用指针拼接。好像是这个意思，新手有好多不懂，解释的不好的地方见谅

你函数已经返回了一个指向这个静态数组变量的指针，直接使用这个指针就行

引用 6 楼 iloveyou418 的回复:函数传参。 比如   int  Cfu(char *a) { 对a赋值 } int  main（） ｛ char a[10]; Cfu（a）; ｝  这样子？  好像是，我研究研究，是个新手，对指针不大敏感。谢谢指教

引用 5 楼 Intel0011 的回复:是这样吗  char tabBuf[128] = {0}; void Get_Latest_File_Name(char* p) {     char capBuf[128] = {0};     FILE *fp = NULL;     sprintf(capBuf,"tail -n1 %s | awk '{print $2}'" MD5FILE);     fp = popen(capBuf, "r");     while(fgets(p, 34, fp)!=NULL){     }     pclose(fp); } Get_Latest_File_Name(tabBuf); //结果在tabBuf中   是是是，应该是这个样子。我调试一下每天给别人看看，万分感谢

引用 1 楼 cfjtaishan 的回复: char* Get_Latest_File_Name() {     char capBuf[128] = {0};     static char tabBuf[128] = {0};     FILE *fp = NULL;     sprintf(capBuf,"tail -n1 %s | awk '{print $2}'" MD5FILE);     fp = popen(capBuf, "r");     while(fgets(tabBuf, 34, fp)!=NULL){     }     pclose(fp);     return tabBuf; } 加static是为了影响tabBuf的生命周期，因为加了static之后，tabBuf是静态数组，在数据段上申请空间（而不是在栈上），返回栈上的空间是未定义行为； 也可以定义成指针，但是必须在堆上申请空间，因为堆上的空间生命周期也是从申请开始知道释放结束；即调用malloc和free函数（C++中也可以用new/delete） 使用完之后需要free，在该函数外释放；一般很容易忘释放；  使用static和堆上申请空间两种方法都是可以实现你的需求；但是也是有区别的；  使用static也是我研究了好久的办法，但是给别人看别人讲使用static的话虽然能得到想要的结果，但是并不是特别好，建议指针传参什么的。您能给点建议吗

引用 2 楼 user-7 的回复:char* Get_Latest_File_Name() { 	char capBuf[128] = { 0 }; 	char *tabBuf = new char[128]; 	FILE *fp = NULL; 	sprintf(capBuf, "tail -n1 %s |awk '{print $2}'" MD5FILE); 	fp = popen(capBuf, "r"); 	while (fgets(tabBuf, 34, fp) != NULL) { 	} 	pclose(fp); 	return tabBuf; } 改成这样就OK了，记得用完delete这个内存 引用 2 楼 user-7 的回复:char* Get_Latest_File_Name() { 	char capBuf[128] = { 0 }; 	char *tabBuf = new char[128]; 	FILE *fp = NULL; 	sprintf(capBuf, "tail -n1 %s |awk '{print $2}'" MD5FILE); 	fp = popen(capBuf, "r"); 	while (fgets(tabBuf, 34, fp) != NULL) { 	} 	pclose(fp); 	return tabBuf; } 改成这样就OK了，记得用完delete这个内存  delete内存是怎么操作呀，是pclose吗还是有其他的神奇操作。 我这个也是奉命行事，别人告诉我用static写虽然可以得到想要的结果，但是不属于主流写法，建议用指针实现，您能给点建议吗


Question: 代码

引用 12 楼 hdt 的回复:[quote=引用 10 楼 qq_25201957 的回复:] 我是从C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src 中去打开puts.c的，并且这种情况下，该.c文件是只读的 甭管它是不是只读，他的代码是如何？如果有代码还不能清楚的了解，建议回炉重修[/quote]  关键就是我不知道怎么看，去找定义找不到,因为是只读模式

引用 10 楼 qq_25201957 的回复:我是从C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\crt\src 中去打开puts.c的，并且这种情况下，该.c文件是只读的 甭管它是不是只读，他的代码是如何？如果有代码还不能清楚的了解，建议回炉重修

那如果是这种情况，我想看方法的标准c代码的实现该怎么去看？？？？？

引用 8 楼 hdt 的回复:[quote=引用 6 楼 hdt 的回复:] [quote=引用 4 楼 qq_25201957的回复:]1.首先我知道是宏， 2.检验参数是否合法，如果string为NULL，会进行什么动作？？？ 如果你用的vs，在哪个宏上面点击右键转到定义[/quote] 看来我抢台词了？？[/quote]  选择不了，f12没用，也不能右键转到定义

引用 6 楼 hdt 的回复:[quote=引用 4 楼 qq_25201957的回复:]1.首先我知道是宏， 2.检验参数是否合法，如果string为NULL，会进行什么动作？？？ 如果你用的vs，在哪个宏上面点击右键转到定义[/quote] 看来我抢台词了？？

VS IDE中，在不明白的符号上点鼠标右键，选转到定义。

引用 4 楼 qq_25201957的回复:1.首先我知道是宏， 2.检验参数是否合法，如果string为NULL，会进行什么动作？？？ 如果你用的vs，在哪个宏上面点击右键转到定义

引用 3 楼 hou09tian 的回复:_VALIDATE_RETURN是宏， _VALIDATE_RETURN( (string != NULL), EINVAL, _TEOF ); 用来检查string是否是NULL _VALIDATE_RETURN( (format != NULL), EINVAL, -1); 用来检查format是否是NULL  检查完成之后执行什么动作喃?

这是宏！！！


Question: 怎样执行生成的可执行程序呢？

执行的方式是没错的，问题可能出在程序启动时，键盘缓冲区还有一个回车符，然后被getchar读到了，误以为已经EOF，所以并没有执行putchar，而是直接返回。

没反应是什么意思？程序运行提示错误了吗？ 程序的逻辑是需要从终端输入数据的。 比如输入abcde 输出abcde linux下使用ctrl+d退出程序，Windows下使用ctrl+z退出程序（其实是退出循环）；


Question: 相同的程序在不同IDE运行结果不一样，

输出的横线部分是在main函数里的CreateHead（h）函数下一行 CreateList函数的最后一行确实多余了，多谢指教

谢谢各位的提醒 首先，编译器是相同的，那几个输出语句是开始我为了测试结果用的，正常的输出结果应该是codeblocks上显示的

建议单步跟踪程序运行，观察变量变化情况，很容易分析得出原因

你的代码和你的输出 不匹配  你的代码里 malloc success  指针 后面没有 ______________ 你的代码里输出了  _____ 你没保存吗

首先如果不是程序问题，编译器不会改变运算顺序； 在不同的编译器上，输出的头结点地址不一样很正常（但是一次执行内输出的地址肯定是一样的，因为都是同一个头结点），因为及时是同一个编译器不同时间执行的结果，头结点的地址值可能也不一样。因为头结点的地址是有系统分配的，即malloc函数；  程序没什么问题，你看到的不同编译器编出来的程序输出地址值不一样这个是很正常的。  #include<stdio.h> #include<stdlib.h>  typedef int elemtype;  typedef struct node{     elemtype data;     struct node* next; }Node;  typedef Node* list;  Node* CreateHead(Node* head); void CreateList(Node* head , elemtype d); void PrintList (Node* head);  int main() {     Node* h = NULL;     h = CreateHead(h);     int m;     while(1){         scanf("%d",&m);         if(m==0)             break;         else{             CreateList(h , m);         }     }     PrintList(h);     return 0; }  list CreateHead(Node* head) {     head = (Node*)malloc(sizeof(Node));     if(!head){         printf("error");         exit(0);     }     head->data = 0;     head->next = NULL;     printf("malloc success\n");     printf("%p\n",head);      return head; }  void CreateList(Node* head , elemtype d ) {     Node *tail = head;     while(tail->next!=NULL){         tail = tail->next;     }     Node *p = NULL;     p = (Node*)malloc(sizeof(Node));     if(!p){         printf("error");     }     p->data = d;     tail->next = p;     p->next = NULL;     //tail = p;    /*这句没有意义，因此属于冗余代码*/ }  void PrintList (Node* head) {     printf("%p\n",head);     Node *p = head->next;     while(p!=NULL){         printf("%d\n",p->data);         p = p->next;     } }

无论什么编译器也不存在改变程序的顺序结构吧。

只是，，，，，想问为何执行顺序不同，相同的编译器... 而且我也知道头节点地址会不同，因为每执行一次程序，头节点就必须要重新申请一次...


Question: 请教一点传参的知识。求大手子解答

可以传文件名进去。

引用 1 楼 user-2 的回复: char* Get_Filex_MD5(int x){ //获取1.sql的md5值   char capBuf[64] = {0};   static char tabBuf[64] = {0};   FILE *fp = NULL;   if (x == 0){     sprintf(capBuf,"md5sum /mnt/hd1/ud.sql");   } else{     sprintf(capBuf, "md5sum /mnt/hd1/%d.sql", x);   }   fp = popen(capBuf, "r");   while((fgets(tabBuf, sizeof(tabBuf), fp))!=NULL){   }   pclose(fp);   return tabBuf; }    真的谢谢您，调试了一下没有问题，也学到了。感激不尽


Question: 为何字符串不能在其中某处赋值‘\0’结束字符串？

字符串是以   ‘\0’  结束的，‘\0’ 前面是字符串，你赋完值后要在后面加上 ‘\0' 才可以，不然识别不了

简单来说就是后面的字符程序都不管了

可以赋值的。 不过这是结尾标志。 当你赋值 0 的话，字符串就在这里被截断了。 所以当你需要截断的话，可以这样设置。 比如，先在某个位置赋值 0，然后 strcpy，然后恢复之。  字符串和字符数组是两个概念。字符串是以 0 为结尾的，而字符数组需要长度的。 BSTR 就可以包含 0 的。

字符数组在栈上，所以可以。 直接用引号是在常量区，改不了。 用malloc是在堆区，也可以改。 ‘\0'结束字符只是个协议，叫做“C风格的字符串”。

orz

其余字符仍然存在于内存中，只是输出这个字符串时或使用大多数字符串API时，程序都只判断到\0位置，后面内容是什么已经无所谓了

#pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！   其实电脑开机后物理内存的每个字节中都有值且都是可读写的，从来不会因为所谓的new、delete或malloc、free而被创建、销毁。区别仅在于操作系统内存管理模块在你读写时是否能发现并是否采取相应动作而已。操作系统管理内存的粒度不是字节而是页，一页通常为4KB。  http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素

字符串不能随意某处赋值，是因为字符串是常量，不可以修改； 字符数组是可读可写，所以可以随意赋值'\0'，赋值之后，%s输出时，后面的字符不输出；因为遇到'\0'就已经停止输出了。 不理解的地方可以搜一下这方面的知识

《深入理解C指针》


Question: 关于fastcall和stdcall

找到原因了 https://stackoverflow.com/questions/13089752/why-should-i-not-use-fastcall-instead-the-standard-cdecl

对，既然是调用约定就是两方的问题

同一个编译器下，完全可以替代。如果不同呢？比如vc，fastcall用到了两个寄存器，但bc，却用了3个 而且你如果查了资料，应该知道win32api,基本是stdcall的，为什么呢？ 想明白这一点，就应该清楚了。

引用 8 楼 FancyMouse 的回复:[quote=引用 7 楼 baidu_20341663 的回复:] 但是为什么放着寄存器传值不用，用栈传值呢？相比于寄存器传值，栈传值速度慢而且占内存 只有寄存器本来不用的时候才快。寄存器在用的时候，你要先保存老数据，再把函数参数拷上去，函数调用完了再要把老数据拷回寄存器，这更慢。32位的时代通用寄存器本来就没几个，不可能因为你这个fastcall而让整个函数不用那两个寄存器的。[/quote]1.fastcall速度快是因为没那么多压栈出栈，少了一些寻址的过程，不是因为mov指令。2.就算是stdcall，也会把数据放到那几个寄存器里，编译器自己会平衡寄存器的使用。不管用不用fastcall那几个寄存器都会使用。所以我还是觉得fastcall可以取代stdcall/

原始社会遗留下来的罢了， 那时候各种不同的语言， 用着各种不同的调用约定， x86 不幸的要兼容几十年前的代码， 就搞出各种飞机 ...

引用 7 楼 baidu_20341663 的回复:但是为什么放着寄存器传值不用，用栈传值呢？相比于寄存器传值，栈传值速度慢而且占内存 只有寄存器本来不用的时候才快。寄存器在用的时候，你要先保存老数据，再把函数参数拷上去，函数调用完了再要把老数据拷回寄存器，这更慢。32位的时代通用寄存器本来就没几个，不可能因为你这个fastcall而让整个函数不用那两个寄存器的。

引用 5 楼 hdt 的回复:引用 4 楼 baidu_20341663 的回复:[quote=引用 3 楼 hdt 的回复:] 不同的编译器的兼容性，如何考虑？几乎所有编译器都支持这3种调用规则吧？ 对，但是对寄存器解释是不一样的 [/quote]但是为什么放着寄存器传值不用，用栈传值呢？相比于寄存器传值，栈传值速度慢而且占内存

调用约定 https://msdn.microsoft.com/zh-cn/magazine/9b372w95.aspx

引用 4 楼 baidu_20341663 的回复:引用 3 楼 hdt 的回复:不同的编译器的兼容性，如何考虑？几乎所有编译器都支持这3种调用规则吧？ 对，但是对寄存器解释是不一样的

不同的编译器的兼容性，如何考虑？

引用 1 楼 Saleayas 的回复:但是不省寄存器啊。 这些都是有历史渊源的。那时候资源紧张，所以在不同的场合才需要不同的约定。 现在 x64 的程序几乎都不需要了。 嵌入式程序不就是资源紧张吗？我只想知道为什么有fastcall了为什么还要有stdcall，为什么fastcall能代替stdcall?


Question: ~的小妙用

一般在做算法题的时候 这种写法比较多 scanf是有返回值的，返回的是成功输入的值的个数 要是读到文件尾就是EOF（=-1）  返回值也是-1 算法题输入常常有这种描述 题目有多组输入，处理文件尾 这种情况一般写法是 while( scanf("%d",n)!= EOF ) 但是你这种方法就是简写了 这里再说一下为什么可以这样写 当读到文件尾的时候scanf的返回值是EOF（=-1） ~是C语言按位取反 -1在计算机里是以补码存放  也就是 -1 = 二进制补码（1111 1111） 对-1按位取反就得到了 二进制补码（0000 0000） 这个值是0 while表达式里面的判断式值为0   就结束循环输入了。

按位取反    。。

几百年没来了

引用 8 楼 iloveyou418 的回复:[quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 iloveyou418 的回复:] 将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。[/quote] 问题是他也没进行赋值操作。。[/quote] scanf就是将输入的数据写到a,b所在内存的空间里。不就是类似赋值操作吗？！

引用 6 楼 lin5161678 的回复:scanf 出错 会返回一个EOF 这个都是不对的。scanf只有在实际读到了EOF才会返回EOF。如果是%d%d但是第二个数字读到字符的时候scanf会返回1，表示正确读入了1个变量。

引用 3 楼 cfjtaishan 的回复:[quote=引用 2 楼 iloveyou418 的回复:] 将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。[/quote] 问题是他也没进行赋值操作。。

引用 2 楼 iloveyou418 的回复:将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 你这个程序可没有对b赋值。。。。你应该是写错了while(~scanf("%d%d",&a,&a)

一个坏习惯  scanf 出错 会返回一个EOF  EOF按照标准规定是 负数  常见实现是 -1 -1 二进制都是 1 ~-1 结果是0 其实想表达 scanf != EOF 这样的意思  但结果依赖实现

不建议使用~按位取反判断scanf的返回值，建议使用 while (scanf("%d%d", &a, &b) == 2)

波浪号是按位取反，即scanf("%d%d", &a, &b);若正确输入，则会返回2，即输入两个数值。2的二进制数表示位0000 0000 0000 0000 0000 0000 0000 0010 取反之后就是1变成0，其他位都变成1； 若输入一个错误，比如输入1 a；那么返回1，取反之后就变成1111 1111 1111 1111 1111 11111 1111 11110

引用 2 楼 iloveyou418 的回复:将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。

对scanf函数的返回值进行取反操作

引用 13 楼 cfjtaishan 的回复:[quote=引用 12 楼 iloveyou418 的回复:] [quote=引用 10 楼 cfjtaishan 的回复:] [quote=引用 8 楼 iloveyou418 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 iloveyou418 的回复:] 将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。[/quote] 问题是他也没进行赋值操作。。[/quote] scanf就是将输入的数据写到a,b所在内存的空间里。不就是类似赋值操作吗？！[/quote] 。。。你先看清楚他的代码呀，我给你复制一下 while(~scanf("%d%d",&a,&a)){[/quote] 这是属于手误吧[/quote] 。。。哼~我不管~

引用 9 楼 FancyMouse 的回复:[quote=引用 6 楼 lin5161678 的回复:] scanf 出错 会返回一个EOF 这个都是不对的。scanf只有在实际读到了EOF才会返回EOF。如果是%d%d但是第二个数字读到字符的时候scanf会返回1，表示正确读入了1个变量。[/quote] scanf 无法读到EOF EOF是scanf执行出错 得到的一个返回值 return EOF; 而不是一个读取到的数据   返回1 这种情况 不属于 scanf 出错 只是匹配失败

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

理解和讨论之前请先学会如何观察！  计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 多用小脑和手，少用大脑、眼睛和嘴，会更快地学会编程！ 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步Debug版对应汇编一行！ 单步Debug版对应汇编千行不如单步Release版对应汇编一行！ 不会单步Release版对应汇编？在你想单步Release版C/C++代码片断的前面临时加一句DebugBreak();重建所有，然后在IDE中运行。（一般人我不告诉他！）  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。

其实就是把你输入的数变成二进制 数然后按位取反

引用 12 楼 iloveyou418 的回复:[quote=引用 10 楼 cfjtaishan 的回复:] [quote=引用 8 楼 iloveyou418 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 iloveyou418 的回复:] 将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。[/quote] 问题是他也没进行赋值操作。。[/quote] scanf就是将输入的数据写到a,b所在内存的空间里。不就是类似赋值操作吗？！[/quote] 。。。你先看清楚他的代码呀，我给你复制一下 while(~scanf("%d%d",&a,&a)){[/quote] 这是属于手误吧

引用 10 楼 cfjtaishan 的回复:[quote=引用 8 楼 iloveyou418 的回复:] [quote=引用 3 楼 cfjtaishan 的回复:] [quote=引用 2 楼 iloveyou418 的回复:] 将scanf函数的返回值取反，等到进行输入就会printf。代码还有点问题     while(~scanf("%d%d",&a,&b) 不然printf会报错，因为b没初始化，也没进行赋值 可以不对b进行初始化，因为scanf就是通过终端输入将输入的数据写到b内存里的。相当于赋值操作；只是和这个初始化是终端输入的。a也是一样的。[/quote] 问题是他也没进行赋值操作。。[/quote] scanf就是将输入的数据写到a,b所在内存的空间里。不就是类似赋值操作吗？！[/quote] 。。。你先看清楚他的代码呀，我给你复制一下 while(~scanf("%d%d",&a,&a)){


Question: linux系统c语言如何实现通过链接下载文件

已经试过了  可以下载文件

引用 6 楼 hongwenjun 的回复:/***************************************************************************  *                                  _   _ ____  _  *  Project                     ___| | | |  _ \| |  *                             / __| | | | |_) | |  *                            | (__| |_| |  _ <| |___  *                             \___|\___/|_| \_\_____|  *  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.  *  * This software is licensed as described in the file COPYING, which  * you should have received as part of this distribution. The terms  * are also available at https://curl.haxx.se/docs/copyright.html.  *  * You may opt to use, copy, modify, merge, publish, distribute and/or sell  * copies of the Software, and permit persons to whom the Software is  * furnished to do so, under the terms of the COPYING file.  *  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY  * KIND, either express or implied.  *  ***************************************************************************/ /* <DESC>  * Download a given URL into a local file named page.out.  * </DESC>  */ #include <stdio.h> #include <stdlib.h>  /*  * 许多在Linux下开发的C程序都需要头文件unistd.h，但VC中没有个头文件，  * 所以用VC编译总是报错。把下面的内容保存为unistd.h，可以解决这个问题。  */ #ifdef _WIN32 #include <io.h> #include <process.h> #else #include<unistd.h> #endif  #include <curl/curl.h>   static size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) {     size_t written = fwrite(ptr, size, nmemb, (FILE*)stream);     return written; }  // 保存URL文件内容到文件 bool url2file(const char* web_url, const char* savefile) {     CURL* curl_handle;     const char* pagefilename = savefile;     FILE* pagefile;       curl_global_init(CURL_GLOBAL_ALL);      /// init the curl session  初始化cURL协议     curl_handle = curl_easy_init();      /// set URL to get here   设置URL到这里     curl_easy_setopt(curl_handle, CURLOPT_URL, web_url);      /// Switch on full protocol/debug output while testing  测试时开启完整的协议/调试输出     curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0L);      /// disable progress meter, set to 0L to enable and disable debug output   禁用进度表，设置为0L启用和禁用调试输出     curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);       /// send all data to this function  所有数据发送给这个函数     curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);      /// open the file   写文件到结果文件     pagefile = fopen(pagefilename, "wb");     if (pagefile) {          /// write the page body to this file handle  写页面文件到保存文件句柄         curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);          /* get it! */         curl_easy_perform(curl_handle);          /* close the header file */         fclose(pagefile);     }      /* cleanup curl stuff */     curl_easy_cleanup(curl_handle);      return true; }这个应该只能下网页吧

引用 2 楼 heronism 的回复:libcurl，可以调用库或编译出来的二进制文件，绝对好用 这个库确实很强大，建议使用这个。

引用 2 楼 heronism 的回复:libcurl，可以调用库或编译出来的二进制文件，绝对好用 你好，有在linux下用过这个库吗，我之前也看到过，但不知道怎么用，我是用在32位的嵌入式平台上，光下哪个版本就摸不着头脑

libcurl，可以调用库或编译出来的二进制文件，绝对好用

引用 7 楼 flashtt 的回复:[quote=引用 6 楼 hongwenjun 的回复:]  https://curl.haxx.se/libcurl/c/url2file.html  } 这个函数好像封装的不错，这是libcurl的函数吗[/quote]  是curl 的示例改的 https://curl.haxx.se/libcurl/c/url2file.html  文件在这里

引用 6 楼 hongwenjun 的回复:/***************************************************************************  *                                  _   _ ____  _  *  Project                     ___| | | |  _ \| |  *                             / __| | | | |_) | |  *                            | (__| |_| |  _ <| |___  *                             \___|\___/|_| \_\_____|  *  * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.  *  * This software is licensed as described in the file COPYING, which  * you should have received as part of this distribution. The terms  * are also available at https://curl.haxx.se/docs/copyright.html.  *  * You may opt to use, copy, modify, merge, publish, distribute and/or sell  * copies of the Software, and permit persons to whom the Software is  * furnished to do so, under the terms of the COPYING file.  *  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY  * KIND, either express or implied.  *  ***************************************************************************/ /* <DESC>  * Download a given URL into a local file named page.out.  * </DESC>  */ #include <stdio.h> #include <stdlib.h>  /*  * 许多在Linux下开发的C程序都需要头文件unistd.h，但VC中没有个头文件，  * 所以用VC编译总是报错。把下面的内容保存为unistd.h，可以解决这个问题。  */ #ifdef _WIN32 #include <io.h> #include <process.h> #else #include<unistd.h> #endif  #include <curl/curl.h>   static size_t write_data(void* ptr, size_t size, size_t nmemb, void* stream) {     size_t written = fwrite(ptr, size, nmemb, (FILE*)stream);     return written; }  // 保存URL文件内容到文件 bool url2file(const char* web_url, const char* savefile) {     CURL* curl_handle;     const char* pagefilename = savefile;     FILE* pagefile;       curl_global_init(CURL_GLOBAL_ALL);      /// init the curl session  初始化cURL协议     curl_handle = curl_easy_init();      /// set URL to get here   设置URL到这里     curl_easy_setopt(curl_handle, CURLOPT_URL, web_url);      /// Switch on full protocol/debug output while testing  测试时开启完整的协议/调试输出     curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, 0L);      /// disable progress meter, set to 0L to enable and disable debug output   禁用进度表，设置为0L启用和禁用调试输出     curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);       /// send all data to this function  所有数据发送给这个函数     curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);      /// open the file   写文件到结果文件     pagefile = fopen(pagefilename, "wb");     if (pagefile) {          /// write the page body to this file handle  写页面文件到保存文件句柄         curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile);          /* get it! */         curl_easy_perform(curl_handle);          /* close the header file */         fclose(pagefile);     }      /* cleanup curl stuff */     curl_easy_cleanup(curl_handle);      return true; } 这个函数好像封装的不错，这是libcurl的函数吗

看看这个怎么样，我记得下载下来里面都是有用法教程的。。http://blog.csdn.net/u012467749/article/details/50740006

试一下system，比如system("ls -l");类似bash执行命令，可以将wget命令放到system函数参数里。


Question: （++i）+（++i）为什么会多一个

第一次 ++i 的时候 i=2了 第二次 ++i 的时候 i=3了 然后两个i相加，这个时候取的值就是改过之后的3， 3+3=6. 感觉有些编译器是不一样的

(++i)+(++i)  i= 2       i=    3   3 + 3

先做括号里面的运算，最后变成3+3

未定义顺序，先执行了两次++i！

这个和编译器相关，不同编译器的结果都可能不同。属于未定义行为，不要再同一行代码中使用多次++

关于C,C++表达式求值顺序 http://blog.csdn.net/fefe82/article/details/37833767，http://bbs.csdn.net/topics/370153775

顺序点问题，未定义行为  关于C,C++表达式求值顺序  http://bbs.csdn.net/topics/370153775

有歧义性，类似这样的问题有很多，跟编译器有关系，不建议深究，也不建议写这样的代码。比如a = i+++i+++i++;

先执行两次++ 再x2


Question: 问题

//C++ Operators //  Operators specify an evaluation to be performed on one of the following: //    One operand (unary operator) //    Two operands (binary operator) //    Three operands (ternary operator) //  The C++ language includes all C operators and adds several new operators. //  Table 1.1 lists the operators available in Microsoft C++. //  Operators follow a strict precedence which defines the evaluation order of //expressions containing these operators.  Operators associate with either the //expression on their left or the expression on their right;    this is called //“associativity.” Operators in the same group have equal precedence and are //evaluated left to right in an expression unless explicitly forced by a pair of //parentheses, ( ). //  Table 1.1 shows the precedence and associativity of C++ operators //  (from highest to lowest precedence). // //Table 1.1   C++ Operator Precedence and Associativity // The highest precedence level is at the top of the table. //+------------------+-----------------------------------------+---------------+ //| Operator         | Name or Meaning                         | Associativity | //+------------------+-----------------------------------------+---------------+ //| ::               | Scope resolution                        | None          | //| ::               | Global                                  | None          | //| [ ]              | Array subscript                         | Left to right | //| ( )              | Function call                           | Left to right | //| ( )              | Conversion                              | None          | //| .                | Member selection (object)               | Left to right | //| ->               | Member selection (pointer)              | Left to right | //| ++               | Postfix increment                       | None          | //| --               | Postfix decrement                       | None          | //| new              | Allocate object                         | None          | //| delete           | Deallocate object                       | None          | //| delete[ ]        | Deallocate object                       | None          | //| ++               | Prefix increment                        | None          | //| --               | Prefix decrement                        | None          | //| *                | Dereference                             | None          | //| &                | Address-of                              | None          | //| +                | Unary plus                              | None          | //| -                | Arithmetic negation (unary)             | None          | //| !                | Logical NOT                             | None          | //| ~                | Bitwise complement                      | None          | //| sizeof           | Size of object                          | None          | //| sizeof ( )       | Size of type                            | None          | //| typeid( )        | type name                               | None          | //| (type)           | Type cast (conversion)                  | Right to left | //| const_cast       | Type cast (conversion)                  | None          | //| dynamic_cast     | Type cast (conversion)                  | None          | //| reinterpret_cast | Type cast (conversion)                  | None          | //| static_cast      | Type cast (conversion)                  | None          | //| .*               | Apply pointer to class member (objects) | Left to right | //| ->*              | Dereference pointer to class member     | Left to right | //| *                | Multiplication                          | Left to right | //| /                | Division                                | Left to right | //| %                | Remainder (modulus)                     | Left to right | //| +                | Addition                                | Left to right | //| -                | Subtraction                             | Left to right | //| <<               | Left shift                              | Left to right | //| >>               | Right shift                             | Left to right | //| <                | Less than                               | Left to right | //| >                | Greater than                            | Left to right | //| <=               | Less than or equal to                   | Left to right | //| >=               | Greater than or equal to                | Left to right | //| ==               | Equality                                | Left to right | //| !=               | Inequality                              | Left to right | //| &                | Bitwise AND                             | Left to right | //| ^                | Bitwise exclusive OR                    | Left to right | //| |                | Bitwise OR                              | Left to right | //| &&               | Logical AND                             | Left to right | //| ||               | Logical OR                              | Left to right | //| e1?e2:e3         | Conditional                             | Right to left | //| =                | Assignment                              | Right to left | //| *=               | Multiplication assignment               | Right to left | //| /=               | Division assignment                     | Right to left | //| %=               | Modulus assignment                      | Right to left | //| +=               | Addition assignment                     | Right to left | //| -=               | Subtraction assignment                  | Right to left | //| <<=              | Left-shift assignment                   | Right to left | //| >>=              | Right-shift assignment                  | Right to left | //| &=               | Bitwise AND assignment                  | Right to left | //| |=               | Bitwise inclusive OR assignment         | Right to left | //| ^=               | Bitwise exclusive OR assignment         | Right to left | //| ,                | Comma                                   | Left to right | //+------------------+-----------------------------------------+---------------+

逻辑运算  ==  赋值    =

=是赋值 ==是判断

=：赋值   比如想让变量a等于a=2; ==判断前后是否相等，如判断0和1是否相等 用1==0，如果相等，结果就是1不相等就是0  编译器中规则就是这样，数字直接用，字符加‘’ 和case无关。

基础的知识，建议多看书上的说明和例子。

==是判断，=是赋值； if()括号里面是判断条件，判断条件有真和假之分； =是赋值符号，用于给变量赋值。 switch ()；根据括号里的值来走不同case分支。 case 'a'等价于case 97: case 1就是switch中变量位1时的分之； switch case可以理解为是if else的另一种形式；


Question: 折叠加密

算法描述清楚了，实现并不难