Question: 求算法高手看看这个题目的意思:如何以最快的速度计算出一个二进制数中1的个数

引用 9 楼 KenZhang1031 的回复:将n写成二进制形式，然后相邻位相加，重复这个过程，直到只剩下一位。以123为例，二进制为1111101，如下图：  不用分开加，直接按位都加一遍更方便。

这个比6楼的还慢, 顶楼的最快..  引用 3 楼 xwhbwas2008 的回复:这个方法好点  8bit静态表查找法 Precompute_8bit       static int bits_in_char [256] = {                   0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2,      3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3,      3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3,      4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4,      3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5,      6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4,      4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5,      6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4, 4, 5,      3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,      4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5, 5, 6, 5, 6, 6, 7, 5, 6,  6, 7, 6, 7, 7, 8  };             int bitcount (unsigned int n)       {          // works only for 32-bit ints          return bits_in_char [n           & 0xffu]              +bits_in_char [(n >>8) & 0xffu]              +bits_in_char [(n >> 16) & 0xffu]              +bits_in_char [(n >> 24) & 0xffu] ;       }  使用静态数组表，列出所有8bit(256个)无符号数含有Bit1的个数。将32Bit 的n分4部分，直接在表中找到对应的Bit1的个数，然后求和。  这是最快的方法了。缺点是需要比较大的内存。

Hacker's Delight

见《高效程序的奥秘》。

这题在编程之美上提过 n=(n&MASK1)+((n>>1)&MASK1)算出的是相邻的两位中1的个数。 n=6二进制表示为0110 n&MAKS1=0100 n>>1&MASK=0001 n=(n&MASK1)+((n>>1)&MASK1)=0101 表示6的前两位中有一个1后两位中有一个1 同理n = (n & MASK2) + ((n >> 2) & MASK2); 算出相邻的四位有多少个1同样在上面的结果为例n=0010 接着就是相邻的8位。。

引用 6 楼 Inhibitory 的回复:[quote=引用 4 楼 iamkconghua 的回复:]  //将x转化为2进制，计算含有的1的个数 int GetNumOfOne(int x) { 	int count = 0; 	while (x) 	{ 		count++; 		x = x & (x - 1); 	} 	return count; }   原理：一个数减去1，则这个数的二进制数种最后一个1及其后的数字取反。 x & (x - 1)为它的二进制数中少一个1[/quote]  这个解法没看过那个面试题的，一般人肯定想不到。

引用 4 楼 iamkconghua 的回复: //将x转化为2进制，计算含有的1的个数 int GetNumOfOne(int x) { 	int count = 0; 	while (x) 	{ 		count++; 		x = x & (x - 1); 	} 	return count; }   原理：一个数减去1，则这个数的二进制数种最后一个1及其后的数字取反。 x & (x - 1)为它的二进制数中少一个1

上述解法源自 微软 的一道面试题

各位相加得出的值是1的个数，这个是一个并行的加法。


Question: 关于收到的数据帧的处理！

这错误，哎！！  以后用这种写法吧  if(0 == i)

引用 6 楼 sanredfish 的回复:你的这句判定少写了一个等号，于是变成赋值，偏巧值为0,于是跳过了文件创建。  if(i=0) 正解！

RETURN VALUE        Upon successful completion fopen(), fdopen() and freopen() return a FILE pointer.  Otherwise, NULL is returned and errno is set  to        indicate the error.  ERRORS        EINVAL The mode provided to fopen(), fdopen(), or freopen() was invalid.         The  fopen(),  fdopen()  and  freopen()  functions may also fail and set errno for any of the errors specified for the routine mal‐        loc(3).         The fopen() function may also fail and set errno for any of the errors specified for the routine open(2).         The fdopen() function may also fail and set errno for any of the errors specified for the routine fcntl(2).         The freopen() function may also fail and set errno for any of  the  errors  specified  for  the  routines  open(2),  fclose(3)  and        fflush(3).  看看 errno

引用 2 楼 zhao4zhong1 的回复:void packet_handler(u_char *dumpfp, const struct pcap_pkthdr *header, const u_char *pkt_data) {     static int i=0;     static u_char filename[256];     printf("in packet handler\n");     if(i=0) {         strncpy((char*)filename,(const char *)pkt_data+18,255);filename[255]=0;         i=1;     } else {/*处理一帧*/         savetofile(filename,pkt_data);     }     return; } void savetofile(u_char *filename,const u_char *pkt_data) {     FILE *onfile;     if((onfile=fopen((char*)filename,"ab"))==NULL) {         printf("[%s]文件打开失败",filename);         exit(0);     }     fwrite(pkt_data+18,1,542,onfile);     fclose(onfile);     return ; } 不行啊。。。还是显示打开失败，昨天用这个还是可以的，只是存在丢包问题，今天不知道怎么的就不行了

引用 1 楼 zhxianbin 的回复:文件存在吗？？？ 不存在的话不是会创建的吗？

文件存在吗？？？


Question: 怎么使用openssl的crypto库呢？

http://yuanshuilee.blog.163.com/blog/static/2176972752013113035156535/ 你可以参考上面的博客，安装openssl以及md5测试代码。 openssl sha1 tmp.c 即可。

引用 1 楼 user-2 的回复:只是需要计算hash用下个MD5库不就可以了  MD5和sha1的结果长度不一样啊。。。

只是需要计算hash用下个MD5库不就可以了


Question: 飞机大战

步步高 学习机吗

打飞机我觉得去东莞学习比较好...

现在还用不到，不过再过一段时间可能用到，先留下来

收藏了，喜欢收藏

这个估计有点难，先收藏了。以后有时间再看


Question: 求解啊 代码 很短

上面打印的全部是地址的值，两个相同类型的地址相减结果是偏移值，而不是实际的地址值的减法

引用 5 楼 user-8 的回复:[quote=引用 4 楼 u012421456 的回复:] 你不加这个的话，system ("pause");能用吗？  "pause"只是system的实参， system是标准函数。 [/quote] 我也不太清楚，只知道曾经不用加“windows.h”可以用，但有时候又必须得加，不加就出错，不知道咋回事

mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\vclang.chm::/html/_clang_subtraction_.289629.htm Subtraction (–) The subtraction operator (–) subtracts the second operand from the first. Both operands can be either integral or floating types, or one operand can be a pointer and the other an integer.    When two pointers are subtracted, the difference is converted to a signed integral value by dividing the difference by the size of a value of the type that the pointers address. The size of the integral value is defined by the type ptrdiff_t in the standard include file STDDEF.H. The result represents the number of memory positions of that type between the two addresses. The result is only guaranteed to be meaningful for two elements of the same array, as discussed in Pointer Arithmetic.   When an integer value is subtracted from a pointer value, the subtraction operator converts the integer value (i) by multiplying it by the size of the value that the pointer addresses. After conversion, the integer value represents i memory positions, where each position has the length specified by the pointer type. When the converted integer value is subtracted from the pointer value, the result is the memory address i positions before the original address. The new pointer points to a value of the type addressed by the original pointer value.

mk:@MSITStore:C:\Program%20Files\Microsoft%20Visual%20Studio\MSDN98\98VS\2052\vclang.chm::/html/_clang_pointer_arithmetic.htm Pointer Arithmetic Additive operations involving a pointer and an integer give meaningful results only if the pointer operand addresses an array member and the integer value produces an offset within the bounds of the same array. When the integer value is converted to an address offset, the compiler assumes that only memory positions of the same size lie between the original address and the address plus the offset.  This assumption is valid for array members. By definition, an array is a series of values of the same type; its elements reside in contiguous memory locations. However, storage for any types except array elements is not guaranteed to be filled by the same type of identifiers. That is, blanks can appear between memory positions, even positions of the same type. Therefore, the results of adding to or subtracting from the addresses of any values but array elements are undefined.  Similarly, when two pointer values are subtracted, the conversion assumes that only values of the same type, with no blanks, lie between the addresses given by the operands.

1.地址相减 == 地址偏移/每个元素所占空间（即代表偏移的元素个数） 2.你这个地方出现负数是因为：地址是无符号整数，所以这个地方%d输出产生了负数(实则为正).

用%p打印p和q试试。

用%p大约p和q试试。

指针相减 难道不是地址相减吗  我是在windows下试的 用的 win-tc，这东西 不太好用，还是linux用的习惯 但是 差值 不对啊

指向同一数组的两个指针相减，是两个指针存储值相减再除以所指向的类型大小

引用 4 楼 u012421456 的回复:你不加这个的话，system ("pause");能用吗？  "pause"只是system的实参， system是标准函数。

你不加这个的话，system ("pause");能用吗？

引用 1 楼 u012421456 的回复:lz，你确定你的代码能运行？应该在上面加一个# include <windows.h>吧！ 最后运行结果我怎么得到的是这个 跟windows有啥关系。

打印地址用%p,不要用%d 地址相减的意义是计算偏移量（中间有多多少个元素）：&a[2] - &a[0] 当然等于2


Question: C显示图片问题求助

free必须和malloc之类的函数配对使用，否则就会出现异常。 Image_Buf不知道哪里申请的内存。 而numOfReadBytes更是不需要free

如果没有使用操作系统(linux),建议不要使用动态内存


Question: 关于字符数组输出中++i和i++问题。

引用 楼主 mywdlgx 的回复:char s1[38]="www.yjxsoft"; 	char s2[]=".com"; 	int i,j; 	i=j=0; 	 //计算 s1的长度,当s1[i]不为0时一直循环，直到s1[i]==0时退出循环，从而移到s1字符串末尾 也就是s[i]=='\0'处 	while(s1[++i]); 	printf("%d\n",i); 	//当j下标未指向'\0'时 逐一复制字符至s1末尾 	while (s2[j]) 	{ 		s1[i++]=s2[j++]; //这里用后置++表示 先对s1[i]=s2[j]后 才对i和j进行自增1操作 	} 	printf("%s \n",s1); 红字处换位i++就不行了，按理说换成i++只会比++i多出一个空字符啊，为啥不行呢？求教空字符代表结束吧~~后面不应该有字符了~~个人理解~~

++i是先使i自身+1然后再取值，所以while(s1[++i]);第一次读到的是s1[1]不是s[0]，最后一个读到的'\0'时，i正好在这个位置上。 如果是i++的话，先取值后+1，那么开始是s[0]，当s[i++]为'\0'时，i会在'\0'的下一个位置上，所以需要在while循环后，进行i--

i = 0; while(s1[i++]); //s1[i-1] == '\0', s[i]也等于'\0' int tmp = i - 1; while (s2[j]) { s1[i++]=s2[j++]; //这里用后置++表示 先对s1[i]=s2[j]后 才对i和j进行自增1操作 }  //这样s1中间s1[tmp]为'\0',字符穿到这里结束了

引用 1 楼 user-3 的回复:char s1[38]="www.yjxsoft"; char s2[]=".com"; int i,j; i=j=0;  //计算 s1的长度,当s1[i]不为0时一直循环，直到s1[i]==0时退出循环，从而移到s1字符串末尾 也就是s[i]=='\0'处 i = -1; //加上这句 while(s1[++i]); printf("%d\n",i); //当j下标未指向'\0'时 逐一复制字符至s1末尾 while (s2[j]) { s1[i++]=s2[j++]; //这里用后置++表示 先对s1[i]=s2[j]后 才对i和j进行自增1操作 }为啥。。。。我想知道原因。。。- -呃


Question: GDB 调试

引用 6 楼 u012889234 的回复:在 logger_init__处打断点没问题， 问题是在它的调试者logger_create 处打断点，单步执行到logger_init__() 在这里再 s 为什么进不去？ 看看汇编，call xxx的地方可以s

直接在 logger_init__(Logger *logger)里面加断点。

先 break logger_init__ 再从头开始运行 如果还是不行， 重新编译。

引用 2 楼 zhao4zhong1 的回复:step：简记为 s ，单步跟踪程序，当遇到函数调用时，则进入此函数体（一般只进入用户自定义函数）。 next：简记为 n，单步跟踪程序，当遇到函数调用时，也不进入此函数体；此命令同 step 的主要区别是，step 遇到用户自定义的函数，将步进到函数中去运行，而 next 则直接调用函数，不会进入到函数体内。  break 函数名：在用户定义的函数“函数名”处设置断点，如：break logger_init__ 我是执行的  s 命令啊。 但是没有进入 logger_init__函数。直接跳到下一行了。

都过节去了吗？


Question: c primer plus书中程序清单15.4这里完全看不懂啊

“#define OPAQUE          0x1”后面一连串声明的数值是怎样来的？ 自己编的，只要保证使用不同的二进制位就行。  union Views     {     struct box_props st_view;     unsigned int     ui_view;（这里我咋没找到赋值的语句呢？直接就把ui_view作为参数show_settings1 };  解释下show_settings1(box.ui_view)这个函数是怎么运作的，看不明白。  这是联合体，自己百度查，我不知道怎么回答。我觉得根本就不需要赋值语句。

也在学这本书的飘过~~

引用 3 楼 user-3 的回复:引用 2 楼 u012757050 的回复:引用 1 楼 user-3 的回复:我原以为“这里”是“这里” 没想到是“这堆”。。。菜鸟 伤不起。。具体一点吧  这样工作量太大了“#define OPAQUE          0x1”后面一连串声明的数值是怎样来的？  union Views     {     struct box_props st_view;     unsigned int     ui_view;（这里我咋没找到赋值的语句呢？直接就把ui_view作为参数show_settings1 };  解释下show_settings1(box.ui_view)这个函数是怎么运作的，看不明白。  问题多多，麻烦了。

我原以为“这里”是“这里” 没想到是“这堆”


Question: 关于printf输出问题

后面不是注释了吗？ 最后一行，先输出的是 j 的值，经过上面的 j--，j已经变成了1，最后一行的输出结果先是1，而里边的那个printf里边\n\n%d，算三个字符，所以输出3，如果你去掉一个\n，即最后一个语句会变成这样 printf("%d",printf("\n%d",j)); //printf 返回打印的字符的数目，则输出结果变成了 1   1 12Press any key to continue

编译选项加/EP /P，重新编译，查看宏展开后对应的.i文件。gcc加-E

printf("%d  %d ",MIN(i,j--),j);//宏展开 printf("%d  %d ", ( (i) <= (j--) ? (i):(j--) ),j); //1<=2(j--，表示先取j的值，再自减）所以表达式为TRUE,就取第一个值 //(i)，所以后面那个j--没有被执行，此时j为1；   printf("%d",printf("\n\n%d",j));  //首先执行第一个printf("\n\n%d",j)，此时j为1，那么打印出1，当然前面还有2个回车， 所以printf返回3，再执行printf("%d",3);打印出3，由于回车只是在前面，所以这里1和3就连在一起， 出现13

不要纠缠这种代码了，未定义行为


Question: c语言新手请教一个循环给字符串指针数组赋值的问题

纠正上帖： char* STR_CHOICE_D[50]; char str[70]; char *p; int n; p=str; for(int i=0;i<3;i++) {     n=sprintf(p,"%c",'A'+i);     STR_CHOICE_D[i]=p;     p+=n+1; }  MessageBox( STR_CHOICE_D[0],"提示",MB_OK); // A MessageBox( STR_CHOICE_D[1],"提示",MB_OK); // B MessageBox( STR_CHOICE_D[2],"提示",MB_OK); // C

char* STR_CHOICE_D[50]; char str[70]; char *p; int n; p=str; for(int i=0;i<3;i++) {     n=sprintf(p,"%c",'A'+i);     p+=n+1;     STR_CHOICE_D[i]=p; }  MessageBox( STR_CHOICE_D[0],"提示",MB_OK); // A MessageBox( STR_CHOICE_D[1],"提示",MB_OK); // B MessageBox( STR_CHOICE_D[2],"提示",MB_OK); // C

U8 str[70]; 这个是什么？

改为如下的试试：  //char* STR_CHOICE_D[50]; char STR_CHOICE_D[50][70]; U8 str[70]; for(i.....){ 	//此处改变str的值 	//STR_CHOICE_D[i]=str;         memcpy(&STR_CHOICE_D[i][0], &str[0], 70); }   引用 楼主 juyangjia 的回复: char* STR_CHOICE_D[50]; U8 str[70]; for(i.....){ 	//此处改变str的值 	STR_CHOICE_D[i]=str; }  MessageBox( STR_CHOICE_D[0],"提示",MB_OK); //期望应该等于  A  实际输出 C   MessageBox( STR_CHOICE_D[1],"提示",MB_OK); //期望应该等于  B  实际输出 C MessageBox( STR_CHOICE_D[2],"提示",MB_OK); //期望应该等于  C  实际输出 C  //也就是所有数组都保存着最后一个字符串，我猜是因为str赋值给STR_CHOICE_D[i]的时候赋的是地址，所有下标都指向的同一个地址   怎么解决这个问题？


Question: 新手请教一个指针问题

会存在隐患 覆盖是会的

静观讨论。。。。

引用 11 楼 navy007hyj 的回复:[quote=引用 7 楼 xinyunyxq 的回复:] [quote=引用 6 楼 navy007hyj 的回复:] 试了一下	 int  nn = 3; char bb=4; char cc = 5;  如果&bb=1的话，则&cc=5，所以往（int *）&bb拷贝int型数据并不会覆盖其它有用数据  你的意思是代码中加了（int *）&bb的强转，虽然bb是一个字节的数据，但系统为其保留了多3个字节的空间，不会因其他地方需要而分配掉这些空间么？[/quote]  c和对应的汇编如下： 24:       int  nn = 3; 004018BE   mov         dword ptr [ebp-4],3 25:       char bb=4; 004018C5   mov         byte ptr [ebp-8],4 26:       char cc = 5; 004018C9   mov         byte ptr [ebp-0Ch],5  我是在32位平台上试验的，如果这样定义char类型的话，系统其实还是给他分配了4字节的空间，和int型空间一样[/quote]  我的是单片机平台下用的，不过看回复还是有争议的，不纠结了，程序中也避免了这种用法，不过还是多谢你

引用 12 楼 lin5161678 的回复:引用 11 楼 navy007hyj 的回复:你有没有考虑过 连续2个都是char 的时候  我测试的就是连续两个char的情况 25:       char bb=4; 004018C5   mov         byte ptr [ebp-8],4 26:       char cc = 5; 004018C9   mov         byte ptr [ebp-0Ch],5  bb和cc都是char类型

引用 7 楼 xinyunyxq 的回复:[quote=引用 6 楼 navy007hyj 的回复:] 试了一下	 int  nn = 3; char bb=4; char cc = 5;  如果&bb=1的话，则&cc=5，所以往（int *）&bb拷贝int型数据并不会覆盖其它有用数据  你的意思是代码中加了（int *）&bb的强转，虽然bb是一个字节的数据，但系统为其保留了多3个字节的空间，不会因其他地方需要而分配掉这些空间么？[/quote]  c和对应的汇编如下： 24:       int  nn = 3; 004018BE   mov         dword ptr [ebp-4],3 25:       char bb=4; 004018C5   mov         byte ptr [ebp-8],4 26:       char cc = 5; 004018C9   mov         byte ptr [ebp-0Ch],5  我是在32位平台上试验的，如果这样定义char类型的话，系统其实还是给他分配了4字节的空间，和int型空间一样

处理器不同 会进行不同的对齐

想要从本质上理解C指针，必须学习汇编以及C和汇编的对应关系。 从汇编的角度理解和学习C语言的指针，原本看似复杂的东西就会变得非常简单！ 指针即地址。“地址又是啥？”“只能从汇编语言和计算机组成原理的角度去解释了。” 但我又不得不承认：  有那么些人喜欢或者适合用“先具体再抽象”的方法学习和理解复杂事物；  而另一些人喜欢或者适合用“先抽象再具体”的方法学习和理解复杂事物。 而我本人属前者。  不要企图依赖输出指针相关表达式的值【比如printf("%p\n",...)】来理解指针的本质， 而要依赖调试时的反汇编窗口中的C/C++代码【比如void *p=...】及其对应汇编指令以及内存窗口中的内存地址和内存值来理解指针的本质。  这辈子不看内存地址和内存值；只画链表、指针示意图，画堆栈示意图，画各种示意图，甚至自己没画过而只看过书上的图……能从本质上理解指针、理解函数参数传递吗？本人深表怀疑！ 这辈子不种麦不收麦不将麦粒拿去磨面；只吃馒头、吃面条、吃面包、……甚至从没看过别人怎么蒸馒头，压面条，烤面包，……能从本质上理解面粉、理解面食吗？本人深表怀疑！！  提醒： “学习用汇编语言写程序” 和 “VC调试(TC或BC用TD调试)时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 （Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。） 想要从本质上理解C指针，必须学习C和汇编的对应关系。” 不是一回事！  不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！  电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址； 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……  十字链表交换任意两个节点C源代码（C指针应用终极挑战）http://download.csdn.net/detail/zhao4zhong1/5532495

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 6 楼 navy007hyj 的回复:试了一下	 int  nn = 3; char bb=4; char cc = 5;  如果&bb=1的话，则&cc=5，所以往（int *）&bb拷贝int型数据并不会覆盖其它有用数据  你的意思是代码中加了（int *）&bb的强转，虽然bb是一个字节的数据，但系统为其保留了多3个字节的空间，不会因其他地方需要而分配掉这些空间么？

一般避免强制类型转换

觉得应该没事，主要看C的强制转换是怎么处理的，(int)b把b转换成4个字节了吧？

有可能覆盖掉，有隐患

looks not beautiful

你的顾虑是对的 a只有1个字节  memcpy处理了a开始的sizeof(int)个字节 是类似于数组越界的错误


Question: 新手对这个程序有点不懂，求解答

这个有点故弄玄虚了，其实数组指针，跟数组名一个意思，因为数组名也代表了数组的起始地址。

数组指针的用法， char (*ss)[M] ; ss指向一个维数为M的数组。


Question: 表达式求值，出现链接错误，望大神指教

这个main。应该改一下。

main函数名修改下，再有错误贴出信息

main函数的main单词还真是写错了哦！

main函数的main单词写错了

贴出错误说明，方便回答

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


Question: onvif测试工具与代码配合的问题

你好，你的问题我也遇到了，可以加你qq和你交流一下吗

这个问题是由于socket的属性设置在bind之前做了，我把广播属性设置相关的动作放到bind之后就好了。

引用 6 楼 kenchowcn 的回复:[quote=引用 4 楼 alexmayer 的回复:] 求一个测试工具的新版安装包  onvif device test tool version 13.12  我上传了你要的版本,要一分,意思一下,我也是忽然发现我自己没有分了. http://download.csdn.net/detail/kenchowcn/6990403[/quote]   多谢！

引用 4 楼 alexmayer 的回复:求一个测试工具的新版安装包  onvif device test tool version 13.12  我上传了你要的版本,要一分,意思一下,我也是忽然发现我自己没有分了. http://download.csdn.net/detail/kenchowcn/6990403

引用 3 楼 hcywcx 的回复:Probe应该是设备端程序启动后主动发送。我也看了那个程序，__wsdd__Proble没被调用。求交流, 569493867  加QQ群:7622995,一起交流.已经很多人都做这个在这个群里面.

很久以前搞过onvif，我记得那时的问题是使用的soap命名空间版本不对造成的。其实就是nsmap文件里面的地址。 现在不太记得，要找找代码才行。

引用 1 楼 user-5 的回复:我顶你一下。。。。不懂 谢谢！

我顶你一下。。。。不懂


Question: C调用外部可执行程序（交互式）

fork+exec

EXEC Section: Linux Programmer's Manual (3 ) Updated: 1993-11-29  --------------------------------------------------------------------------------    NAME execl, execlp, execle, execv, execvp - execute a file    SYNOPSIS #include <unistd.h>  extern char **environ;   int execl(const char *path, const char *arg, ...);  int execlp(const char *file, const char *arg, ...);  int execle(const char *path, const char *arg , ..., char * const envp[]);  int execv(const char *path, char *const argv[]);  int execvp(const char *file, char *const argv[]);     DESCRIPTION The exec family of functions replaces the current process image with a new process image. The functions described in this manual page are front-ends for the function execve(2). (See the manual page for execve for detailed information about the replacement of the current process.)  The initial argument for these functions is the pathname of a file which is to be executed.   The const char *arg and subsequent ellipses in the execl, execlp, and execle functions can be thought of as arg0, arg1, ..., argn. Together they describe a list of one or more pointers to null-terminated strings that represent the argument list available to the executed program. The first argument, by convention, should point to the file name associated with the file being executed. The list of arguments must be terminated by a NULL pointer, and, since these are variadic functions, this pointer must be cast (char *) NULL.   The execv and execvp functions provide an array of pointers to null-terminated strings that represent the argument list available to the new program. The first argument, by convention, should point to the file name associated with the file being executed. The array of pointers must be terminated by a NULL pointer.   The execle function also specifies the environment of the executed process by following the NULL pointer that terminates the list of arguments in the parameter list or the pointer to the argv array with an additional parameter. This additional parameter is an array of pointers to null-terminated strings and must be terminated by a NULL pointer. The other functions take the environment for the new process image from the external variable environ in the current process.   Some of these functions have special semantics.   The functions execlp and execvp will duplicate the actions of the shell in searching for an executable file if the specified file name does not contain a slash (/) character. The search path is the path specified in the environment by the PATH variable. If this variable isn't specified, the default path ``:/bin:/usr/bin'' is used. In addition, certain errors are treated specially.   If permission is denied for a file (the attempted execve returned EACCES), these functions will continue searching the rest of the search path. If no other file is found, however, they will return with the global variable errno set to EACCES.   If the header of a file isn't recognized (the attempted execve returned ENOEXEC), these functions will execute the shell with the path of the file as its first argument. (If this attempt fails, no further searching is done.)     RETURN VALUE If any of the exec functions returns, an error will have occurred. The return value is -1, and the global variable errno will be set to indicate the error.    FILES /bin/sh    ERRORS All of these functions may fail and set errno for any of the errors specified for the library function execve(2).    SEE ALSO sh(1), execve(2), fork(2), ptrace(2), environ(5)    COMPATIBILITY On some other systems the default path (used when the environment does not contain the variable PATH) has the current working directory listed after /bin and /usr/bin, as an anti-Trojan-horse measure. Linux uses here the traditional "current directory first" default path.  The behavior of execlp and execvp when errors occur while attempting to execute the file is historic practice, but has not traditionally been documented and is not specified by the POSIX standard. BSD (and possibly other systems) do an automatic sleep and retry if ETXTBSY is encountered. Linux treats it as a hard error and returns immediately.   Traditionally, the functions execlp and execvp ignored all errors except for the ones described above and ENOMEM and E2BIG, upon which they returned. They now return if any error other than the ones described above occurs.     CONFORMING TO execl, execv, execle, execlp and execvp conform to IEEE Std1003.1-88 (``POSIX.1'').  --------------------------------------------------------------------------------

引用 楼主 fivedoumi 的回复:我想在LINUX系统中的C里边调用一个可执行程序 这个可执行程序是可交互的，即运行过程中会有多个用户提示，也可接受用户的多次输入。 我想在C里面模拟这个交互过程，有什么方法可以实现吗。  我查了一下，system()不可交互，而popen只能是单纯的输入或者输出重定向。 请问有其他可用的API吗？ 多线程，信号，共享内存，消息队列。

fork + excec


Question: 同一段程序，单独运行可以，接在另一个程序后面编译错误

#include  <stdio.h>

把贴过去之后的大程序发出来

你那个大程序是cpp后缀吧

把定义：FILE *filei;FILE *fileo; 贴到你的大程序的最前面位置 你的大程序后缀名是C的吗？

根据错误提示来看，你的FILE *filei; FILE *fileo;是不是没有申明？  建议你直接将封装一个函数，然后，丢到大的程序里面跳用。


Question: 二十进制数的加法 求教

谢谢。。。。

引用 5 楼 zhao4zhong1 的回复:base is between 2 and 36: long strtol( const char *nptr, char **endptr, int base ); char *_ltoa( long value, char *string, int base );  意思就是这两个函数支持2～36进制的转换。 你要实现20进制的加法，只要先用strtol将两个要加的20进制数转为10进制数，相加，再将结果用ltoa函数转为20进制数即可。

没有明白，请大神详细一点

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <locale.h> int main() {     int i,v;     char bs[33];     char b[33];     char hs[9];     char h[9];     char s[4];     char *e;  // 十进制整数转二进制串；     i=1024;     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("i=%d,bs=%s\n",i,bs); // 十进制整数转十六进制串；     i=1024;     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("i=%d,hs=%s\n",i,hs); // 十六进制字符串转成十进制数     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     printf("hs=%s,i=%d\n",hs,i); // 二进制字符串转化为十六进制字符串；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     ltoa(i,h,16);     sprintf(hs,"%08s",h);     printf("bs=%s,hs=%s\n",bs,hs); // 二进制字符串转化为十进制数；     strcpy(bs,"00000000000000000000010000000000");     i=strtol(bs,&e,2);     printf("bs=%s,i=%d\n",bs,i); // 十六进制字符串转成二进制串     strcpy(hs,"00000400");     sscanf(hs,"%x",&i);     ltoa(i,b,2);     sprintf(bs,"%032s",b);     printf("hs=%s,bs=%s\n",hs,bs); // ASC\GBK字符串转十六进制串     strcpy(s,"a汉");     i=0;     while (1) {         if (0==s[i]) break;         sprintf(hs+i*2,"%02X",(unsigned char)s[i]);         i++;     }     setlocale(LC_ALL,"chs");     printf("s=%s,hs=%s\n",s,hs); // 十六进制字符串转成汉字（GBK）及字符(ASC)     strcpy(hs,"61BABA");     i=0;     while (1) {         if (1!=sscanf(hs+i*2,"%2x",&v)) break;         s[i]=(char)v;         i++;     }     s[i]=0;     printf("hs=%s,s=%s\n",hs,s);      return 0;  } //i=1024,bs=00000000000000000000010000000000 //i=1024,hs=00000400 //hs=00000400,i=1024 //bs=00000000000000000000010000000000,hs=00000400 //bs=00000000000000000000010000000000,i=1024 //hs=00000400,bs=00000000000000000000010000000000 //s=a汉,hs=61BABA //hs=61BABA,s=a汉

确实很多新手不喜欢调试, 很多问题单步调试, 问题就简单明了的摆在哪里.

楼主这个程序不完整。没有引用string.h，主函数也没有写完，你是怎么测试数据不通过的？

谁给置顶一个各个编译器的debug步骤 我送500可用分！


Question: 一个年过完之后东西忘的差不多了，大神帮我看看结果。

引用 2 楼 zhxianbin 的回复:char str[10] = “hello.c/”; char (*p)[10] = str ; int n = 10;  sizeof (str ) =9 ？  //应该等于 10 吧 strlen(str)=8 ? //数一下，不包含 \0 sizeof ("abcdef") =7 ? //数一下，包含 \0 sizeof ("abcdef" + 1) = 8? sizeof ( p ) = 40？  //不确定，我觉得是 4   sizeof ( n ) = 4？                      void Foo ( char str[100]){                          sizeof( str ) = 4？  //指针的长度                   void *p = malloc( 100 );  sizeof ( p ) = 4？; //指针的长度 好像是的 等于4

char (*p)[10] = str ;//这个编译错误的会；一个是指针，一个是指向数组的指针 //应该改成：  char (*p)[10]= &str;//所以本意还是指针，sizeof还是4(32位)

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！


Question: 指针问题。两种写法的区别

我觉得最重要的区别是, 1可以适用于其它数据. 而2已经定死了, 只能对read_dat操作.

不明白！第二种写法不需要返回一个值吗？

第1种写法比第2种写法多了一个传值过程。 如果调用第1种写法：void f1(&read_dat)，事实上是先把&read_dat的值传给了函数f1()的参数result，然后再在f1()中使用reslut。而对于第2种写法就是直接使用&result，就少了这个传值过程了。事实上，两种方式达到的效果是一样的。 最后要说明的是，你第2种写法没有u8类型的返回值。

依赖不一样！

从指针来看没什么区别啊

若不需要改变全局变量，则用第一种； 若必须改变全局变量，则用第二种，有时这是必须的。

第一种是参数传递，第二个是全局变量 如版主所说，最大的区别是函数返回值类型不同。。

u32 read_dat = 0;  u8 f1()  {     pr->rxdat = (void *)&read_dat;     getdat(pr);  }  这个函数重入就危险了...

第二个感觉问题蛮多的

引用 楼主 dsoyy 的回复:1、 void f1(u32* result) {    pr->rxdat = result;    getdat(pr); } 2、 u32 read_dat = 0; u8 f1() {    pr->rxdat = (void *)&read_dat;    getdat(pr); }  着两种写法的区别是什么？  rxdat的类型是什么?

第一个看不出什么问题来  第二个的话，问题太多了，跟这样的人做同事我会觉得恐怖 u32 read_dat = 0;         //尽量避免使用全局变量 u8 f1()                   //危险，不会进行参数检查 {    pr->rxdat = (void *)&read_dat;    //强制类型转换，慎用，随意使用void指针是不负责任的表现    getdat(pr); }

最主要的区别就是第二个有返回值...

在内存的位置不一样

一个用函数参数一个用全局变量。

那就是没区别了

pr->rxdat = result; 下面有做指针转换~ pr->rxdat = (void *)&read_dat;

区别。。。。。。。


Question: 求C或c++语言实现的AES加密算法源码，要贴过去就能编译执行的

求能跨操作系统运行的。万分感谢！求能跨操作系统运行的。万分感谢！求能跨操作系统运行的。万分感谢！

#pragma comment(lib, "crypt32.lib") #pragma comment(lib, "advapi32.lib") #define _WIN32_WINNT 0x0400 #include <stdio.h> #include <windows.h> #include <wincrypt.h> #define MY_ENCODING_TYPE  (PKCS_7_ASN_ENCODING | X509_ASN_ENCODING) #define KEYLENGTH  0x00800000 void HandleError(char *s); //-------------------------------------------------------------------- //  These additional #define statements are required. #define ENCRYPT_ALGORITHM CALG_RC4 #define ENCRYPT_BLOCK_SIZE 8 //   Declare the function EncryptFile. The function definition //   follows main. BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword); //-------------------------------------------------------------------- //   Begin main. void main(void) {     CHAR szSource[100];     CHAR szDestination[100];     CHAR szPassword[100];     printf("Encrypt a file. \n\n");     printf("Enter the name of the file to be encrypted: ");     scanf("%s",szSource);     printf("Enter the name of the output file: ");     scanf("%s",szDestination);     printf("Enter the password:");     scanf("%s",szPassword);     //--------------------------------------------------------------------     // Call EncryptFile to do the actual encryption.     if(EncryptFile(szSource, szDestination, szPassword)) {         printf("Encryption of the file %s was a success. \n", szSource);         printf("The encrypted data is in file %s.\n",szDestination);     } else {         HandleError("Error encrypting file!");     } } // End of main //-------------------------------------------------------------------- //   Code for the function EncryptFile called by main. static BOOL EncryptFile(     PCHAR szSource,     PCHAR szDestination,     PCHAR szPassword) //-------------------------------------------------------------------- //   Parameters passed are: //     szSource, the name of the input, a plaintext file. //     szDestination, the name of the output, an encrypted file to be //         created. //     szPassword, the password. {     //--------------------------------------------------------------------     //   Declare and initialize local variables.     FILE *hSource;     FILE *hDestination;     HCRYPTPROV hCryptProv;     HCRYPTKEY hKey;     HCRYPTHASH hHash;     PBYTE pbBuffer;     DWORD dwBlockLen;     DWORD dwBufferLen;     DWORD dwCount;     //--------------------------------------------------------------------     // Open source file.     if(hSource = fopen(szSource,"rb")) {         printf("The source plaintext file, %s, is open. \n", szSource);     } else {         HandleError("Error opening source plaintext file!");     }     //--------------------------------------------------------------------     // Open destination file.     if(hDestination = fopen(szDestination,"wb")) {         printf("Destination file %s is open. \n", szDestination);     } else {         HandleError("Error opening destination ciphertext file!");     }     //以下获得一个CSP句柄     if(CryptAcquireContext(                 &hCryptProv,                 NULL,               //NULL表示使用默认密钥容器，默认密钥容器名                 //为用户登陆名                 NULL,                 PROV_RSA_FULL,                 0)) {         printf("A cryptographic provider has been acquired. \n");     } else {         if(CryptAcquireContext(                     &hCryptProv,                     NULL,                     NULL,                     PROV_RSA_FULL,                     CRYPT_NEWKEYSET))//创建密钥容器         {             //创建密钥容器成功，并得到CSP句柄             printf("A new key container has been created.\n");         } else {             HandleError("Could not create a new key container.\n");         }     }     //--------------------------------------------------------------------     // 创建一个会话密钥（session key）     // 会话密钥也叫对称密钥，用于对称加密算法。     // （注: 一个Session是指从调用函数CryptAcquireContext到调用函数     //   CryptReleaseContext 期间的阶段。会话密钥只能存在于一个会话过程）     //--------------------------------------------------------------------     // Create a hash object.     if(CryptCreateHash(                 hCryptProv,                 CALG_MD5,                 0,                 0,                 &hHash)) {         printf("A hash object has been created. \n");     } else {         HandleError("Error during CryptCreateHash!\n");     }     //--------------------------------------------------------------------     // 用输入的密码产生一个散列     if(CryptHashData(                 hHash,                 (BYTE *)szPassword,                 strlen(szPassword),                 0)) {         printf("The password has been added to the hash. \n");     } else {         HandleError("Error during CryptHashData. \n");     }     //--------------------------------------------------------------------     // 通过散列生成会话密钥     if(CryptDeriveKey(                 hCryptProv,                 ENCRYPT_ALGORITHM,                 hHash,                 KEYLENGTH,                 &hKey)) {         printf("An encryption key is derived from the password hash. \n");     } else {         HandleError("Error during CryptDeriveKey!\n");     }     //--------------------------------------------------------------------     // Destroy the hash object.     CryptDestroyHash(hHash);     hHash = NULL;     //--------------------------------------------------------------------     //  The session key is now ready.     //--------------------------------------------------------------------     // 因为加密算法是按ENCRYPT_BLOCK_SIZE 大小的块加密的，所以被加密的     // 数据长度必须是ENCRYPT_BLOCK_SIZE 的整数倍。下面计算一次加密的     // 数据长度。     dwBlockLen = 1000 - 1000 % ENCRYPT_BLOCK_SIZE;     //--------------------------------------------------------------------     // Determine the block size. If a block cipher is used,     // it must have room for an extra block.     if(ENCRYPT_BLOCK_SIZE > 1)         dwBufferLen = dwBlockLen + ENCRYPT_BLOCK_SIZE;     else         dwBufferLen = dwBlockLen;     //--------------------------------------------------------------------     // Allocate memory.     if(pbBuffer = (BYTE *)malloc(dwBufferLen)) {         printf("Memory has been allocated for the buffer. \n");     } else {         HandleError("Out of memory. \n");     }     //--------------------------------------------------------------------     // In a do loop, encrypt the source file and write to the source file.     do {         //--------------------------------------------------------------------         // Read up to dwBlockLen bytes from the source file.         dwCount = fread(pbBuffer, 1, dwBlockLen, hSource);         if(ferror(hSource)) {             HandleError("Error reading plaintext!\n");         }         //--------------------------------------------------------------------         // 加密数据         if(!CryptEncrypt(                     hKey,           //密钥                     0,              //如果数据同时进行散列和加密，这里传入一个                     //散列对象                     feof(hSource),  //如果是最后一个被加密的块，输入TRUE.如果不是输.                     //入FALSE这里通过判断是否到文件尾来决定是否为                     //最后一块。                     0,              //保留                     pbBuffer,       //输入被加密数据，输出加密后的数据                     &dwCount,       //输入被加密数据实际长度，输出加密后数据长度                     dwBufferLen))   //pbBuffer的大小。         {             HandleError("Error during CryptEncrypt. \n");         }         //--------------------------------------------------------------------         // Write data to the destination file.         fwrite(pbBuffer, 1, dwCount, hDestination);         if(ferror(hDestination)) {             HandleError("Error writing ciphertext.");         }     } while(!feof(hSource));     //--------------------------------------------------------------------     //  End the do loop when the last block of the source file has been     //  read, encrypted, and written to the destination file.     //--------------------------------------------------------------------     // Close files.     if(hSource)         fclose(hSource);     if(hDestination)         fclose(hDestination);     //--------------------------------------------------------------------     // Free memory.     if(pbBuffer)         free(pbBuffer);     //--------------------------------------------------------------------     // Destroy session key.     if(hKey)         CryptDestroyKey(hKey);     //--------------------------------------------------------------------     // Destroy hash object.     if(hHash)         CryptDestroyHash(hHash);     //--------------------------------------------------------------------     // Release provider handle.     if(hCryptProv)         CryptReleaseContext(hCryptProv, 0);     return(TRUE); } // End of Encryptfile //-------------------------------------------------------------------- //  This example uses the function HandleError, a simple error //  handling function, to print an error message to the standard error //  (stderr) file and exit the program. //  For most applications, replace this function with one //  that does more extensive error reporting. void HandleError(char *s) {     fprintf(stderr,"An error occurred in running the program. \n");     fprintf(stderr,"%s\n",s);     fprintf(stderr, "Error number %x.\n", GetLastError());     fprintf(stderr, "Program terminating. \n");     exit(1); } // End of HandleError

用crypto++行不


Question: 有没有汇编的解释库

//汇编的解释库 //F("nop \n nop \n") 返回 "\x90\x90" //生成一个临时.c文件，扔给VC6编译器让其编译并生成带机器码的.cod文件，然后读这个.cod文件的内容。 #include <stdio.h> #include <stdlib.h> #include <string.h> char *F(const char* asmins,int *L) {     FILE *f;     static char s[1000];     char ln[80],*p;     int z,i,v,n;      f=fopen("tmp.c","w");     fprintf(f,         "#include <stdio.h>\n"         "int main() {\n"         "    __asm {////\n"         "%s"         "    }////\n"         "    return 0;\n"         "}\n",         asmins     );     fclose(f);     system("cl.exe /nologo /MDd /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"_AFXDLL\" /FAcs /Fa\"Debug/\" /Fo\"Debug/\" /Fd\"Debug/\" /FD /c tmp.c >NUL 2>NUL");     f=fopen("debug\\tmp.cod","r");     if (NULL==f) {         printf("Can not open file tmp.cod!\n");         exit(1);     }     z=0;     i=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         if (z==0) {             if (strstr(ln,"__asm {////")) {                 z=1;             }         }         if (z>0) {             if (strstr(ln,"}////")) break;             if (1==sscanf(ln,"  %x%n",&v,&n)) {                 p=ln+n;                 while (1) {                     if (1==sscanf(p,"%2x%n",&v,&n)) {                         s[i++]=(char)v;                         p+=n;                     } else break;                 }             }         }     }     fclose(f);     *L=i;     return s; } int main() {     char *a;     int i,L;      a=F("nop \n mov eax,0x12345678\n nop \n",&L);     for (i=0;i<L;i++) {         printf("\\x%02x",(unsigned char)a[i]);     }     return 0; } //\x90\xb8\x78\x56\x34\x12\x90 //

//汇编的解释库 //F("nop \n nop \n") 返回 "\x90\x90" //生成一个临时.c文件，扔给VC6编译器让其编译并生成带机器码的.cod文件，然后读这个.cod文件的内容。 #include <stdio.h> #include <stdlib.h> #include <string.h> char *F(const char* asmins,int *L) {     FILE *f;     static char s[1000];     char ln[80],*p;     int z,i,v,n;      f=fopen("tmp.c","w");     fprintf(f,         "#include <stdio.h>\n"         "int main() {\n"         "    __asm {////\n"         "%s"         "    }////\n"         "    return 0;\n"         "}\n",         asmins     );     fclose(f);     system("cl.exe /nologo /MDd /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"_AFXDLL\" /FAcs /Fa\"Debug/\" /Fo\"Debug/\" /Fd\"Debug/\" /FD /c tmp.c >NUL 2>NUL");     f=fopen("debug\\tmp.cod","r");     if (NULL==f) {         printf("Can not open file tmp.cod!\n");         exit(1);     }     z=0;     i=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         if (z==0) {             if (strstr(ln,"__asm {////")) {                 z=1;             }         }         if (z>0) {             if (strstr(ln,"}////")) break;             if (1==sscanf(ln,"  %x%n",&v,&n)) {                 p=ln+n;                 while (1) {                     if (1==sscanf(p,"%2x",&v,&n)) {                         s[i++]=(char)v;                         p+=n;                     } else break;                 }             }         }     }     fclose(f);     *L=i;     return s; } int main() {     char *a;     int i,L;      a=F("nop \n nop \n",&L);     for (i=0;i<L;i++) {         printf("\\x%02x",(unsigned char)a[i]);     }     return 0; } //\x90\x90 //

引用 7 楼 zhao4zhong1 的回复:还可以考虑生成一个临时.asm文件，扔给汇编器让其汇编并生成带机器码的.map文件，然后读这个.map文件的内容。 //汇编的解释库 //F("nop \n nop \n") 返回 "\x90\x90" //生成一个临时.asm文件，扔给汇编器让其汇编并生成带机器码的.map文件，然后读这个.map文件的内容。 #include <stdio.h> #include <stdlib.h> #include <string.h> char *F(const char* asmins,int *L) {     FILE *f;     static char s[1000];     char ln[80],*p;     int z,i,v,n;      f=fopen("tmp.c","w");     fprintf(f,         "#include <stdio.h>\n"         "int main() {\n"         "    __asm {////\n"         "%s"         "    }////\n"         "    return 0;\n"         "}\n",         asmins     );     fclose(f);     system("cl.exe /nologo /MDd /W3 /Gm /GX /ZI /Od /D \"WIN32\" /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_MBCS\" /D \"_AFXDLL\" /FAcs /Fa\"Debug/\" /Fo\"Debug/\" /Fd\"Debug/\" /FD /c tmp.c >NUL 2>NUL");     f=fopen("debug\\tmp.cod","r");     if (NULL==f) {         printf("Can not open file tmp.cod!\n");         exit(1);     }     z=0;     i=0;     while (1) {         if (NULL==fgets(ln,80,f)) break;         if (z==0) {             if (strstr(ln,"__asm {////")) {                 z=1;             }         }         if (z>0) {             if (strstr(ln,"}////")) break;             if (1==sscanf(ln,"  %x%n",&v,&n)) {                 p=ln+n;                 while (1) {                     if (1==sscanf(p,"%2x",&v,&n)) {                         s[i++]=(char)v;                         p+=n;                     } else break;                 }             }         }     }     fclose(f);     *L=i;     return s; } int main() {     char *a;     int i,L;      a=F("nop \n nop \n",&L);     for (i=0;i<L;i++) {         printf("\\x%02x",(unsigned char)a[i]);     }     return 0; } //\x90\x90 //

汇编到二进制都是一一对应的。 你用汇编写的程序，编译出来就是一一对应的二进制码。

自己下载nasm的源码，做成一个lib调用

参考gcc自带的汇编器的源代码？

自己写： 1. 编译汇编码-->可执行文件         2. 执行上一步中的可执行文件。  汇编码虽然很低级，但是CPU依然不能直接执行。

没有什么现成的可以直接用么

参考MSDN98\SAMPLES\VC98\SDK\SDKTOOLS\IMAGE\DRWATSON\*.*

搞个汇编和机器码对照表即可


Question: 可以用c语言写出消除之星完全消除的程序吗

我再顶，最多顶三次。

崩溃就调试啊  赵老师上！

汗，后来想了下，逻辑不通，因为筛选的时候，需要保存很多很多的数据，但是我又没办法将数据一一保存，只要改变一次就凌乱了。这个办法应该不通。求大神。

step by step

学编程，应该从写helloworld开始就学会单步调试 所有写了一大篇代码却只能编译运行测试结果的初学者技能树都点歪了

汗，没人，自己顶


Question: 虚拟键问题

要用KeyDown或者是KeyUp来判别，RawKey的话很可能会是多次。  引用 楼主 wangli1000000 的回复:#define _WIN32_WINNT    0x0500  //必须在开头  #include <stdio.h> #include <windows.h>  HANDLE hInput;  /*  获取标准输入设备句柄 */ INPUT_RECORD inRec;/*  返回数据记录 */ DWORD numRead; /*  返回已读取的记录数 */   int main() {        COORD pos = {0,0}; char ch;     HWND hwnd=GetConsoleWindow();/*  控制台窗口句柄 */     hInput = GetStdHandle(STD_INPUT_HANDLE); /*  输入设备句柄 */     while(1){					         	 	    ReadConsoleInput(hInput, &inRec, 1, &numRead); 						 			// 键盘事件              if (inRec.EventType == KEY_EVENT){                if (inRec.Event.KeyEvent.wVirtualKeyCode ==VK_F1)                   ShellExecute(NULL,"open","帮助.exe",NULL,NULL,SW_SHOW);                                if (inRec.Event.KeyEvent.bKeyDown) {                    ch =  inRec.Event.KeyEvent.uChar.AsciiChar;                  if(ch=='q')printf("演示.\n");                 }                                  if (inRec.Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE) break;                                                                                }                         // end键盘事件                }  }  请问：为什么按下F1键，ShellExecute(NULL,"open","帮助.exe",NULL,NULL,SW_SHOW); 语句执行了两次。  怎么才能只执行一次？

if (inRec.Event.KeyEvent.bKeyDown) ｛ if (inRec.Event.KeyEvent.wVirtualKeyCode ==VK_F1)                   ShellExecute(NULL,"open","帮助.exe",NULL,NULL,SW_SHOW); ｝

你按q，显示几次“演示”


Question: 求助，关于指针数组argv的问题

argv是OS帮你解析完命令行参数填好的，不用自己处理

可以简单的认为 argv[i] 是个只读参数。 这个参数，只是传递命令行参数用的,不是让你改着玩的。 唯一可改变的，是指针argv 的值而已，一般也就是让她不断增加。 PS： 这个参数， 是C库中的初始化程序， 分析命令行参数后，建立的一个指针数组，其中每个指针指向一个命令行参数 分析完成后，做一些数据的初始化工作，然后调用main 函数，参数参数个数和命令行数组  所以，一般用户程序，都是从main 函数开始启动的。 用户编写的代码，是从main 开始正式工作的。 不要企图改变，任何一个命令行参数。  这些参数，只是由C库中的初始化程序，调用main 函数用的。 main 函数只需要使用他们就行了，需要改变这些数据，可以复制他们，然后修改。 main 函数执行到这里，已经被调用过了，改变参数并不能改变命令行本身。  用户程序，是在main 函数执行过程中执行的 用户程序，一般就是main 函数内部的代码，这些代码再去调用别的函数，执行别的代码。

int main(int argc, char **argv); argv参数可以看成:   char *argv[argc];  argc和argv参数是由main函数的调用者设置的，如果argv == 1, 则argv只分配了1个char*的内存,即argv[0]。 而你想往argv[1]和argv[2]里面存东西，肯定不行啊，内存都没分配，咋存？


Question: 这里人多，广撒网多捞鱼！

引用 1 楼 user-1 的回复:lea？ 同志是powerpc32的指令啊，我是觉得lea面熟啊，结果x86的啊

引用 1 楼 user-1 的回复:lea？ 我试试

lea？

O(∩_∩)O~ 没接触过你说的那个 查下指令手册


Question: 怎样通过sizeof或别的方式获取指针变量所占空间大小

32位系统, 4字节, 64位8字节

现在好多了,16Bits有两种指针长度 near * 16 Bits,far* 32Bits 32Bits不约而同的省掉了far指针(48Bits)  64 没用过,不清楚 C51 3种指针长度8Bits,16Bits,24Bits 通用24Bits xdata*,code* 16Bits data* 8Bits

四个字节：sizeof(void*)

引用 2 楼 akirya 的回复:sizeof(void*)  就是sizeof(void*)

引用 15 楼 bruceteen 的回复:在 LLP64 模式下，long 是 32bits，而指针是 64bits 在C语言中，有个标准的类型名 intptr_t  一直以为(unsign long) == sizeof(void*)，微软与众不同啊。

看看这篇博文 被人误解的SIZEOF

看编译器，sizeof（void *）才是最靠谱的

主要是看编译器的，

在《Linux Driver Device 》中确实提到了这个取巧的方式，就是长整形长度等于指针长度。是一个经验说法。具体宽度最准的还是看编译器。

还是通过sizeof判断吧

大家都这么说,32位系统, 4字节, 64位8字节

引用 8 楼 lin5161678 的回复:[quote=引用 7 楼 u013470052 的回复:] 指针变量就是一个地址，也就是长整形的数，长整形的数占几位，指针变量就占几位。没这回事  别把看到的巧合当成真理[/quote]

引用 7 楼 u013470052 的回复:指针变量就是一个地址，也就是长整形的数，长整形的数占几位，指针变量就占几位。没这回事  别把看到的巧合当成真理

指针变量就是一个地址，也就是长整形的数，长整形的数占几位，指针变量就占几位。

数据模型。。

readelf（linux）

sizeof的结果是编译器告诉你的。

和编译器的目标平台有关

sizeof(void*)


Question: 一个错误程序~~求指教什么原因导致这种显示结果~~这个程序本身是错的~~是不是scanf()的原因

引用 2 楼 chenyegui 的回复:没初始化。。值不确定没初始化但是装入输入scanf的值了~~而且就算是因为没有初始化，也应该第一个值开始就是垃圾值啊~~

没初始化。。值不确定

double i[8],j[8], s = 0;  s+=i[m]; j[m] = s;  应该做上述改动。 因为j[8]没有初始化，当m>1时，j[m] += i[m]的时候，j[m]原有的值未知。


Question: 四叉树的问题

可算绕出来了，谢谢各位！

等比数列求和公式可以用在这里，很容易算出最后一层的节点数是(3n+1)/4 然后空指针数再＊4 http://baike.baidu.com/link?url=HXEsRDz6ys1KJ5EVGaavIS4o7SB2acCYM76pK9t6Vt6fwBL61s0xbEVsKNPTcqtzMQ1zWWHWTMJ-_n75xU4rNq

因为每个树都有一个头结点。头结点下面是4个子结点，然后每个子结点又有4个子节点。 例如一个2层的四叉树，就会有5个结点，但头结点并不能计算进去。他的4个子节点下面接的都是空指针，可以得出空指针的个数为4*4=16个。这个时候n=5，则4*n-(n-1)=4*5-(5-1)=16。

最简单的理解就是，n个节点一定就有4n个指针。 除了root节点，所有的节点都用了一个指针，就是用了n-1个 所以答案就是 4n -n +1 = 3n +1


Question: 新手请问码值的定义

进来看看。。。。。。

引用 6 楼 u013475621 的回复:谢谢回答 可能我最后一个追加的问题没说清楚 在编写源代码阶段 我们在文本里敲击键盘A键 显示器中显示A 那么下面哪种说明对  A. 这随着敲键盘显示出来的A 这时要编写的程序还没有运行 还没有转换成目标代码 但是仍能显示出字符出来 说明敲键盘显示字符是计算机的基本功能 即使没有程序运行也可以做到  B. 这些随着敲键盘显示出来的所有字符 不是计算机的基本功能 而是编写源代码时使用的程序在运行时的功能 因为这时要编写的程序还没有运行 所以要编写的程序还没有被程序设计语言规定数据类型 不会产生char类型的数据 所以这个时候显示A是编写源代码时使用的程序在运行时产生char类型的数据的结果 你不装操作系统开机试试，看看敲键盘会不会显示字符？ 数据类型是编程语言为了让人能够方便的控制计算机而规定的，在程序运行时没有数据类型这玩意。 你敲键盘会造成键盘电路的变化，如果操作系统能够正确处理这个变化，就会得到操作系统内相应的结果，如果操作系统不能正确处理（没装驱动之类的），那么电路再怎么变化也没用。 这个时候显示A？首先操作系统处理键盘电路信号，得到一个输入，然后将这个输入经过操作系统内部机制（windows是消息机制）转换为一组数据交给在它上面运行的某个程序，这个程序再处理这组数据并执行对应的功能。 再说一次，计算机运行时根本不知道内存中的数据类型是char还是int，因为CPU只认识电位状态！数据类型是用来让人方便理解使用编程语言的，如果你在编程语言内写下int a=0，编译器编译程序时会把这条语句编译为向栈内压入4字节并把这4字节全部设为0，至于之后CPU是使用1个字节2个字节还是8个字节，那都跟你写代码时的数据类型没有任何关系！

引用 4 楼 baichi4141 的回复:[quote=引用 3 楼 u013475621 的回复:] 谢谢回答 是不是这样 而是内存的一块区域中 每个最小区域储存的0和1的情况 代码11111111是8个位中储存的数排列在一起 而不是一个有8个数位的二进制的数字 本身没有值 每个1之间没有换算关系   那么数据以二进制储存 以十进制传输又是怎么回事呢 既然代码不是一个数字 那它也有进位制？还是说仅表达每个位储存的都只有0或1 而没有表达代码的前个数位 等于后个数位的2倍的意思？   8位的数据对象表示值65的内存状态 与ASCII规定的字符A的代码的内存状态一样 但它们不是一回事 那么我想问一下 这个不一样 是不是他们在内存中的区域不一样造成的？前者所在的内存区域 只是和后者一样可以有几个位是1 几个位是0 但只要被数据类型指定在内存的这片区域中储存 就永远没有字符A的意思？   还有个问题哈 我们在编写源代码时 在机器内的代码 是不是都是char类型的 把我们打出来的字符- 1 6变成int类型的-16 把打出来的字符" - 1 6 "变成char类型的字符串-16的是不是编译器的功能？ 在硬件实现上，由于历史原因，每8个存储bit构成了一个基本的存储单元byte，CPU运算、总线传输和存储芯片都是以byte作为操作单位。为了便于理解，人类使用一个byte按照每个bit为2的n次方相加之和来称呼这个byte的内容，如果一个byte的bit全是1，那你可以说它的值是十六进制FF或者十进制255——但本质上，这8个bit可以表示任何信息，彼此之间也完全不必有任何关系只是放在一起而已（虽然大多数情况下都是有关系的），每个bit用来干什么由设置这些bit状态和读取这些bit状态的人/程序决定。 数据以二进制存储指的是硬件原理，由于每个基本电路单元只能表示两个状态，所以建立在硬件上的软件就用一个bit对应一个基本电路单元，建立起了现在的计算机系统。如果有更好的能表示三个状态的基本电路单元（不太可能），那建立在该种硬件上的计算机系统就是数据以3进制存储了。至于以十进制传输，没听过这种说法，你去问说这话的人怎么想的吧。 用一个byte表示一个字符，就是首先规定“这8个bit一起用，按照2进制计算数值表示0~255这256个数之一”，然后再规定“其中有一些数和一些字符存在一一对应关系，例如A这个字符和65这个数一一对应”。然后如果有人想在计算机内表示A这个字符，就设置一个byte内的8个bit为65的2进制状态。数据本身没有类型，是纯粹的bit信息，只有使用这些bit的人规定了每个bit代表什么意思，这些信息对这个人来说才有类型。 机器命令在实现上也是以byte为单位，一般第一个byte是命令类型各bit表示不同意思，后几个byte表示该命令所需的参数。将第一个byte的2进制数值和一些特定的名字对应起来，就是汇编语言了，例如CPU读取到2进制数值为90的byte时，这个机器周期就什么也不执行，然后规定90和NOP这个名字对应起来，汇编语言中就有了一条名为NOP的指令，该指令对应的功能是什么也不做。  数据没有类型，数据类型由设置该数据和使用该数据的人/程序彼此约定。 32位机器上int和float同样是4个byte，没有任何方法区分这两种数据类型的内存，你读取到的4个byte表示多大的数，取决于你认为这4个byte是int类型还是float类型[/quote]  谢谢回答 可能我最后一个追加的问题没说清楚 在编写源代码阶段 我们在文本里敲击键盘A键 显示器中显示A 那么下面哪种说明对  A. 这随着敲键盘显示出来的A 这时要编写的程序还没有运行 还没有转换成目标代码 但是仍能显示出字符出来 说明敲键盘显示字符是计算机的基本功能 即使没有程序运行也可以做到  B. 这些随着敲键盘显示出来的所有字符 不是计算机的基本功能 而是编写源代码时使用的程序在运行时的功能 因为这时要编写的程序还没有运行 所以要编写的程序还没有被程序设计语言规定数据类型 不会产生char类型的数据 所以这个时候显示A是编写源代码时使用的程序在运行时产生char类型的数据的结果

引用 3 楼 u013475621 的回复:谢谢回答 是不是这样 而是内存的一块区域中 每个最小区域储存的0和1的情况 代码11111111是8个位中储存的数排列在一起 而不是一个有8个数位的二进制的数字 本身没有值 每个1之间没有换算关系   那么数据以二进制储存 以十进制传输又是怎么回事呢 既然代码不是一个数字 那它也有进位制？还是说仅表达每个位储存的都只有0或1 而没有表达代码的前个数位 等于后个数位的2倍的意思？   8位的数据对象表示值65的内存状态 与ASCII规定的字符A的代码的内存状态一样 但它们不是一回事 那么我想问一下 这个不一样 是不是他们在内存中的区域不一样造成的？前者所在的内存区域 只是和后者一样可以有几个位是1 几个位是0 但只要被数据类型指定在内存的这片区域中储存 就永远没有字符A的意思？   还有个问题哈 我们在编写源代码时 在机器内的代码 是不是都是char类型的 把我们打出来的字符- 1 6变成int类型的-16 把打出来的字符" - 1 6 "变成char类型的字符串-16的是不是编译器的功能？ 在硬件实现上，由于历史原因，每8个存储bit构成了一个基本的存储单元byte，CPU运算、总线传输和存储芯片都是以byte作为操作单位。为了便于理解，人类使用一个byte按照每个bit为2的n次方相加之和来称呼这个byte的内容，如果一个byte的bit全是1，那你可以说它的值是十六进制FF或者十进制255——但本质上，这8个bit可以表示任何信息，彼此之间也完全不必有任何关系只是放在一起而已（虽然大多数情况下都是有关系的），每个bit用来干什么由设置这些bit状态和读取这些bit状态的人/程序决定。 数据以二进制存储指的是硬件原理，由于每个基本电路单元只能表示两个状态，所以建立在硬件上的软件就用一个bit对应一个基本电路单元，建立起了现在的计算机系统。如果有更好的能表示三个状态的基本电路单元（不太可能），那建立在该种硬件上的计算机系统就是数据以3进制存储了。至于以十进制传输，没听过这种说法，你去问说这话的人怎么想的吧。 用一个byte表示一个字符，就是首先规定“这8个bit一起用，按照2进制计算数值表示0~255这256个数之一”，然后再规定“其中有一些数和一些字符存在一一对应关系，例如A这个字符和65这个数一一对应”。然后如果有人想在计算机内表示A这个字符，就设置一个byte内的8个bit为65的2进制状态。数据本身没有类型，是纯粹的bit信息，只有使用这些bit的人规定了每个bit代表什么意思，这些信息对这个人来说才有类型。 机器命令在实现上也是以byte为单位，一般第一个byte是命令类型各bit表示不同意思，后几个byte表示该命令所需的参数。将第一个byte的2进制数值和一些特定的名字对应起来，就是汇编语言了，例如CPU读取到2进制数值为90的byte时，这个机器周期就什么也不执行，然后规定90和NOP这个名字对应起来，汇编语言中就有了一条名为NOP的指令，该指令对应的功能是什么也不做。  数据没有类型，数据类型由设置该数据和使用该数据的人/程序彼此约定。 32位机器上int和float同样是4个byte，没有任何方法区分这两种数据类型的内存，你读取到的4个byte表示多大的数，取决于你认为这4个byte是int类型还是float类型

引用 2 楼 baichi4141 的回复:不存在码制这玩意，初学者最忌讳的就是自创概念，往往发明一些别人连看都看不懂的术语 一种数据格式要表示一个数，就按照这种格式设置内存Bit是1是0，所以不同的数据格式表示不同的数可能有相同的内存状态，你不能拿一个内存状态说这是什么数据格式是什么数 ASCII码是“单字节对应单英文字符”的数据格式，按照ASCII码这种格式用一个字节表示字符'A'和按照二进制数据格式用一个字节表示整数65，内存中的这个字节是相同的，但那不代表这二者之间就一样，而是因为语言承认这两种数据格式之间的自动转换，二者才能够被视为等价  A 没有码制这玩意 B 字符和整数可以直接按内存状态一一映射，这是语言默认规定，别想到处推广无限适用 C 同B    谢谢回答 是不是这样 而是内存的一块区域中 每个最小区域储存的0和1的情况 代码11111111是8个位中储存的数排列在一起 而不是一个有8个数位的二进制的数字 本身没有值 每个1之间没有换算关系   那么数据以二进制储存 以十进制传输又是怎么回事呢 既然代码不是一个数字 那它也有进位制？还是说仅表达每个位储存的都只有0或1 而没有表达代码的前个数位 等于后个数位的2倍的意思？   8位的数据对象表示值65的内存状态 与ASCII规定的字符A的代码的内存状态一样 但它们不是一回事 那么我想问一下 这个不一样 是不是他们在内存中的区域不一样造成的？前者所在的内存区域 只是和后者一样可以有几个位是1 几个位是0 但只要被数据类型指定在内存的这片区域中储存 就永远没有字符A的意思？   还有个问题哈 我们在编写源代码时 在机器内的代码 是不是都是char类型的 把我们打出来的字符- 1 6变成int类型的-16 把打出来的字符" - 1 6 "变成char类型的字符串-16的是不是编译器的功能？

浮点不是很清楚。 所以回答后两个。    B. 字符型和布尔型的这种数据类型 似乎与整数（或者整数的代码 或者整数对应的数据对象）有什么关系 我有点弄不清楚书的中意思 我猜是不是字符型跟所有整数型(signed int signed long int等)的代码一样 代码00000001表示整数1 而不是像浮点数那样前8位是尾数后面是指数这样制作代码的意思?   reply: char型的值 占1字节， 对应 ASC码值  如 char a = '1'; 转换成整数 对应ASC码的 1  bool 型， true and false, 转换成整数 1 和 0     C. 字符型和布尔型的代码 有没有整数值的含义在里边？ 这个值是不是就是代码相同的整数型的值？  reply: 编译器会做隐式转换。 具体值得对应参考前述。


Question: 学生党一枚，求各位大神debug

动态规划的问题很麻烦的。 刷题的话，不会做的题到网上搜题目基本上都能搜到题解的。

自己百度找个正确代码

二楼补上题目 在讲述DP算法的时候，一个经典的例子就是数塔问题，它是这样描述的：   有如下所示的数塔，要求从顶层走到底层，若每一步只能走到相邻的结点，则经过的结点的数字之和最大是多少？


Question: 如何使用zlib或者其他库编写一个程序实现目录的压缩

你先用tar打包成一个文件，再用你的那个代码最这个打包后的tar文件进行压缩就可以了

引用 2 楼 user-32 的回复:zlib里那个压缩函数会用之后，剩下的不是只要自己设计下文件结构了么 能给个思路吗？

引用 4 楼 zhao4zhong1 的回复:WinExec("C:\\Program Files\\WinRAR\\rar.exe a d:\\mydir.rar -r d:\\mydir\\*.*",SW_HIDE); #include <memory.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>  #include <zlib.h> #include "GZIPFile.h"  #define BUFFERLEN 100   //zip文件打包 int G_gzfile(const char *inFile, const char *outFile) {     int fp; char buff[BUFFERLEN]; int len;     gzFile file;      if((fp=open(inFile,O_RDONLY))==0)//O_BINARY     {         printf("open打开%s文件错误!\n",inFile);         return -1;     }     file = gzopen(outFile, "wb");     if (file == NULL)  {         printf("gzopen打开%s文件错误!\n",outFile);         return -1;     } memset(buff,0,sizeof(buff));  len = read(fp,buff,sizeof(buff)); while(len  > 0) { gzwrite(file,buff,len); len = read(fp,buff,sizeof(buff)); }     gzclose(file); close(fp);     return 0; } //zip文件解包 int G_ungzfile(const char *inFile, const char *outFile) { gzFile file; char uncompr[BUFFERLEN]; int len; int count =0;   	FILE *fp_out;    	file = gzopen(inFile, "rb");   	if (file == NULL)    	{   	printf("gzopen打开%s文件错误!\n",inFile);     return -1;   	}     if((fp_out=fopen(outFile,"wb+"))==NULL)//O_BINARY     {         printf("fopen打开%s文件错误!\n",outFile);         return -1;     } len = gzread(file, uncompr, sizeof(uncompr));     while( len > 0 ) { int nLen = fwrite(uncompr,1,len,fp_out); if ( nLen!= len) { //printf("nLen = [%d], len= [%d]\n", nLen, len); printf("write写%s文件错误!\n",outFile); return -1; } len = gzread( file, uncompr, sizeof(uncompr));     }     gzclose(file); fclose(fp_out);     return 0; } 通过这个可以想到思路吗？请求支招

直接调用现成压缩软件的命令行最方便。 非要看目录压缩解压的代码的话，参考Linux下tar的源代码。

没思路，我手头上有的文件压缩代码拿出来   #include <memory.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h>  #include <zlib.h> #include "GZIPFile.h"  #define BUFFERLEN 100   //zip文件打包 int G_gzfile(const char *inFile, const char *outFile) {     int fp; 		char buff[BUFFERLEN]; 		int len;     gzFile file;      if((fp=open(inFile,O_RDONLY))==0)//O_BINARY     {         printf("open打开%s文件错误!\n",inFile);         return -1;     }     file = gzopen(outFile, "wb");     if (file == NULL)  		{         printf("gzopen打开%s文件错误!\n",outFile);         return -1;     } 		memset(buff,0,sizeof(buff));  		len = read(fp,buff,sizeof(buff)); 		while(len  > 0) 		{ 			gzwrite(file,buff,len); 			len = read(fp,buff,sizeof(buff)); 		}     gzclose(file); 		close(fp);     return 0; } //zip文件解包 int G_ungzfile(const char *inFile, const char *outFile) { 		gzFile file; 		char uncompr[BUFFERLEN]; 		int len; 		int count =0;   	FILE *fp_out;    	file = gzopen(inFile, "rb");   	if (file == NULL)    	{   	printf("gzopen打开%s文件错误!\n",inFile);     return -1;   	}     if((fp_out=fopen(outFile,"wb+"))==NULL)//O_BINARY     {         printf("fopen打开%s文件错误!\n",outFile);         return -1;     } 		len = gzread(file, uncompr, sizeof(uncompr));     while( len > 0 ) 		{ 			int nLen = fwrite(uncompr,1,len,fp_out); 			if ( nLen!= len) 			{ 				//printf("nLen = [%d], len= [%d]\n", nLen, len); 				printf("write写%s文件错误!\n",outFile); 				return -1; 			} 		len = gzread( file, uncompr, sizeof(uncompr));     }     gzclose(file); 		fclose(fp_out);     return 0; } 怎么在这个上面更改，达到可以实现压缩目录

WinExec("C:\\Program Files\\WinRAR\\rar.exe a mydir.rar -r d:\\mydir\\*.*".SW_HIDE);

zlib里那个压缩函数会用之后，剩下的不是只要自己设计下文件结构了么

顶起来。。。。


Question: 2道题目!!求大神给看看 谢谢

引用第二题可以用指数对数转换，不过有些时候会有误差 lg(n^n)=n*lgn,然后去掉整数部分假定为x，计算10^x,取最高位 这个是什么原理 做是做出来了 就是不懂为什么可以这样做  x那里不懂?


Question: 用C自己写了个简易推箱子游戏，但是感觉自己设计地图的时候步奏太繁琐，求指教

推箱子游戏VC6源代码 仓库番游戏VC6源代码 http://download.csdn.net/detail/zhao4zhong1/3230945


Question: c语言编程常见的错误1

引用 6 楼 u012789847 的回复:哈哈哈，菜鸟一枚，请多指教 分给我吧！ [img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/mo

哈哈哈，菜鸟一枚，请多指教

printf里面的%和变量的一一对应关系 scanf里面的%和变量以及变量前加不加&的一一对应关系 是C代码中非常容易出错的地方，而且通常编译还不出错。 所以在编译源代码之前值得专门仔细检查一遍甚至多遍。  “多一少一”问题占程序员常犯错误的10%以上！  常量也有类型。 C++ Integer Constants Integer constants are constant data elements that have no fractional parts or exponents. They always begin with a digit. You can specify integer constants in decimal, octal, or hexadecimal form. They can specify signed or unsigned types and long or short types.  Syntax  integer-constant :  decimal-constant integer-suffixopt octal-constant integer-suffixopt hexadecimal-constant integer-suffixopt 'c-char-sequence'  decimal-constant :  nonzero-digit decimal-constant digit  octal-constant :  0 octal-constant octal-digit  hexadecimal-constant :  0x hexadecimal-digit 0X hexadecimal-digit hexadecimal-constant hexadecimal-digit  nonzero-digit : one of  1 2 3 4 5 6 7 8 9  octal-digit : one of  0 1 2 3 4 5 6 7  hexadecimal-digit : one of  0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D E F  integer-suffix :  unsigned-suffix long-suffixopt long-suffix unsigned-suffixopt  unsigned-suffix : one of  u U  long-suffix : one of  l L  64-bit integer-suffix :  i64  To specify integer constants using octal or hexadecimal notation, use a prefix that denotes the base. To specify an integer constant of a given integral type, use a suffix that denotes the type.  To specify a decimal constant, begin the specification with a nonzero digit. For example:  int i = 157;   // Decimal constant int j = 0198;  // Not a decimal number; erroneous octal constant int k = 0365;  // Leading zero specifies octal constant, not decimal  To specify an octal constant, begin the specification with 0, followed by a sequence of digits in the range 0 through 7. The digits 8 and 9 are errors in specifying an octal constant. For example:  int i = 0377;   // Octal constant int j = 0397;   // Error: 9 is not an octal digit  To specify a hexadecimal constant, begin the specification with 0x or 0X (the case of the “x” does not matter), followed by a sequence of digits in the range 0 through 9 and a (or A) through f (or F). Hexadecimal digits a (or A) through f (or F) represent values in the range 10 through 15. For example:  int i = 0x3fff;   // Hexadecimal constant int j = 0X3FFF;   // Equal to i  To specify an unsigned type, use either the u or U suffix. To specify a long type, use either the l or L suffix. For example:  unsigned uVal = 328u;             // Unsigned value long lVal = 0x7FFFFFL;            // Long value specified                                    //  as hex constant unsigned long ulVal = 0776745ul;  // Unsigned long value  C++ Floating-Point Constants Floating-point constants specify values that must have a fractional part. These values contain decimal points (.) and can contain exponents.  Syntax  floating-constant :  fractional-constant exponent-partopt floating-suffixopt digit-sequence exponent-part floating-suffixopt  fractional-constant :  digit-sequenceopt . digit-sequence digit-sequence .  exponent-part :  e signopt digit-sequence E signopt digit-sequence  sign : one of  + –  digit-sequence :  digit digit-sequence digit  floating-suffix :one of  f l F L  Floating-point constants have a “mantissa,” which specifies the value of the number, an “exponent,” which specifies the magnitude of the number, and an optional suffix that specifies the constant’s type. The mantissa is specified as a sequence of digits followed by a period, followed by an optional sequence of digits representing the fractional part of the number. For example:  18.46 38.  The exponent, if present, specifies the magnitude of the number as a power of 10, as shown in the following example:  18.46e0      // 18.46 18.46e1      // 184.6  If an exponent is present, the trailing decimal point is unnecessary in whole numbers such as 18E0.  Floating-point constants default to type double. By using the suffixes f or l (or F or L — the suffix is not case sensitive), the constant can be specified as float or long double, respectively.  Although long double and double have the same representation, they are not the same type. For example, you can have overloaded functions like  void func( double );  and   void func( long double );

引用 2 楼 user-5 的回复:应该是为了自己便于记忆吧,不过如果这样发帖还不如写个blog比较好 嗯，有道理，lz可以写博客啊

散分吗？

应该是为了自己便于记忆吧,不过如果这样发帖还不如写个blog比较好

lz发这个是为了？？？


Question: 我想写一个程序，自动启动，无法关闭，请问能实现吗

奉劝楼主不要把有限的生命浪费在无限的加密解密死循环中！

守护进程在应用层解决不了问题，但是如果都到驱动层那又是矛和盾的问题了， 但是如果对方在应用层，你在驱动层，任何R3层的程序都无法操作你的进程， HANDLE都打不开，更何况干掉

通常, 在这种情况下, 赵老师会说: 不要把有限的生命,浪费在无限的加密解密中.  确实, 你能想到的防结束方法, 安全软件也能想对结束的方法, 只是看哪个的技术能力更强.

rootkit 搜索搜搜索 这个 对你有帮助地

正确的做法是hook，lz这样的简单，hook掉任务管理器就行了  守护什么是不靠普的，呵呵呵

我也想到的是守护进程！

最简单的就是开个守护进程了，检测你的程序挂了的话，就重启。

QQ电脑管家 在任务管理器中就无法删除... 同问 如何让任务管理器等管理软件无法删除启动的程序？

给个建议，当然可能躲不过杀毒软件之类的啊！  用守护的方式，弄两个应用程序， 两个程序里面添加个功能就是相互监视，发现对方被K掉了 就启动对方。再把两个程序都添加到系统的开机自动启动项目里面。 或者是把一个程序做成服务程序，用服务程序来监视你自己的程序是否在运行。  这个可以让任务管理器没法杀死，但是躲不过杀毒软件

引用 4 楼 user-11 的回复:楼主在哪个流氓软件公司工作 冤枉

引用 5 楼 u012421456 的回复:lz想干啥啊做想做的事

引用 3 楼 zhuobattle 的回复:[quote=引用 2 楼 cjwcommonuse 的回复:] [quote=引用 1 楼 zhuobattle 的回复:] 无法关闭是指用任务管理器无法结束？这个也只是相对的。 能无法用任务管理器关闭最好， 不能的话可以退一步：关闭后又能够复活 求教。。。[/quote] 会写驱动不？[/quote]没写过

lz想干啥啊

楼主在哪个流氓软件公司工作

引用 2 楼 cjwcommonuse 的回复:[quote=引用 1 楼 zhuobattle 的回复:] 无法关闭是指用任务管理器无法结束？这个也只是相对的。 能无法用任务管理器关闭最好， 不能的话可以退一步：关闭后又能够复活 求教。。。[/quote] 会写驱动不？

引用 1 楼 zhuobattle 的回复:无法关闭是指用任务管理器无法结束？这个也只是相对的。 能无法用任务管理器关闭最好， 不能的话可以退一步：关闭后又能够复活 求教。。。

无法关闭是指用任务管理器无法结束？这个也只是相对的。


Show or Question ？


Question: 为什么求B出现次数的sum函数出错？

代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

你的count2即表示字符串长, 又表示B的个数, 冲突了. 需要定义成2个变量.


Question: 我用c生成out文件去编译另一个c 说没main？

引用 1 楼 truelance 的回复:你源代码编译有问题,不是程序执行的问题. 多行字符串每一行都用引号对括起来, 比如"AAABBB"可以写成 "AAA" "BBB"恩恩～～～

引用 2 楼 zhao4zhong1 的回复:19行前加一句fclose(p);谢谢！！！确实如此～～～我现在都一对对写了


Question: 结构体初始化影响入参的值，求帮助！！！

贴出来的代码是没有任何问题的！只可能是别的地方对pstDataCell这个指针进行了操作。多线程下要特别注意

但是那个值没有发生过改写，我用GDB跟踪到(*pstDataCell)->read = (*pstDataCell);这个的时候那个值就发生变化了

引用 4 楼 xiaohuh421 的回复:memcpy((*pstDataCell)->pstDataPoint, pstPointData, sizeof(DATA_POINT_S));  问题就在于这句  因为long *plData;是一个指针, memcpy就只复制了指针值, 而它指向的内容是不会复制的.  这样的话, 如果你在memcpy后, 原来的pstPointData中的plData内存被释放或者改写, (*pstDataCell)->pstDataPoint.lpData指向的内容肯定就会一起变化了. +++

4L说的对~

嗯 malloc出来的

楼主，你在进这个函数之前，pstPointData->plData的值是怎么来的？是malloc出来的吗？

试改如下: #include<stdio.h> #include<stdlib.h> #include<string.h> #define SUCCESS 0 #define FAILED 1  typedef struct tagDataPoint {   long *plData;   time_t arrtime;   int den; }DATA_POINT_S;  typedef struct tagDataCell {   DATA_POINT_S *pstDataPoint;   struct tagDataCell *write;   struct tagDataCell *read; }DATA_CELL_S;   int DATA_STREAM_CellInit(DATA_CELL_S **pstDataCell, DATA_POINT_S *pstPointData) {   int iRet = SUCCESS;    if (NULL == pstDataCell) //加   {     iRet = FAILED;   }   else //加   {     *pstDataCell = (DATA_CELL_S *)malloc(sizeof(DATA_CELL_S));     if (NULL == *pstDataCell) //改 if (NULL == pstDataCell)     {       iRet = FAILED;       printf("DATA_CELL_S malloc Failed\n");     }     else //加     {       (*pstDataCell)->pstDataPoint = (DATA_POINT_S *)malloc(sizeof(DATA_POINT_S));       if (NULL == (*pstDataCell)->pstDataPoint)       {         iRet = FAILED;         printf("DATA_POINT_S malloc Failed\n");       }     }      if (NULL != pstPointData)     {       //移上 (*pstDataCell)->pstDataPoint = (DATA_POINT_S *)malloc(sizeof(DATA_POINT_S));       memcpy((*pstDataCell)->pstDataPoint, pstPointData, sizeof(DATA_POINT_S));     }      (*pstDataCell)->write = (*pstDataCell);     (*pstDataCell)->read = (*pstDataCell);   }   return iRet; }  int main(void) {   DATA_CELL_S *pstDataCell;   long l[5] = {1, 2, 3, };   DATA_POINT_S pstPointData = {l, 100, 200};   int r = DATA_STREAM_CellInit(&pstDataCell, &pstPointData);   return 0; }

怀疑你是多进程/线程运行, 对 (*pstDataCell)->write 赋过值以后, 就有别的进程/线程向这个地址写入数据了.

memcpy((*pstDataCell)->pstDataPoint, pstPointData, sizeof(DATA_POINT_S)); 这句话也有问题，，(*pstDataCell)->pstDataPoint 这个指针也是不定值，没有初始化。

这个应该容易排查，跟一下就行了。 你的是32位，还是64位的？  我感觉不像read这个语句出了问题。可以在pstPointData->plData 这个内存地址上打个硬件断点看一下。


Question: 不包含stdlib.h时，strtod结果诡异

引用 6 楼 ielxd1989 的回复:[quote=引用 5 楼 zhao4zhong1 的回复:] 计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 这种代码在vc6中是编不过的，gcc这样可以编过，很容易坑人啊。[/quote] 研究一下gcc的命令行选项： [root]# gcc --help [root]# gcc -v --help

引用 5 楼 zhao4zhong1 的回复:计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构…… 这种代码在vc6中是编不过的，gcc这样可以编过，很容易坑人啊。

计算机组成原理→DOS命令→汇编语言→C语言（不包括C++）、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言（包括C++）、架构……  对学习编程者的忠告： 眼过千遍不如手过一遍！ 书看千行不如手敲一行！ 手敲千行不如单步一行！ 单步源代码千行不如单步对应汇编一行！  VC调试时按Alt+8、Alt+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化，这样过一遍不就啥都明白了吗。 对VC来说，所谓‘调试时’就是编译连接通过以后，按F10或F11键单步执行一步以后的时候，或者在某行按F9设了断点后按F5执行停在该断点处的时候。 （Turbo C或Borland C用Turbo Debugger调试,Linux或Unix下用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。）

引用 3 楼 zhao4zhong1 的回复:搜“隐式声明” 隐式声明都是以int作为返回值类型的。 而strtod实际上返回的是double，会不会是编译器生成代码时，按照整形返回值来取strtod的结果，导致取到的返回值不正确呢？

搜“隐式声明”

引用 1 楼 user-2 的回复:你开-Wall编译看看它给你啥警告 [root@localhost Test]# gcc -Wall t.c t.c: 在函数‘main’中: t.c:7: 警告：隐式声明函数‘strtod’

你开-Wall编译看看它给你啥警告


Question: 座位随机分配算法

能麻烦讲解一下思路么？

仅供参考#include <stdio.h> #include <stdlib.h> #include <time.h> int d[6]; int i,n,a,b,t; int c,j; void main() {     srand(time(NULL));     printf("shuffle 0..n-1 demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=0;i<n;i++) d[i]=i;/* 填写0～n-1 */             for (i=n;i>0;i--) {/* 打乱0～n-1 */                 a=i-1;b=rand()%i;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=0;i<n;i++) printf("%d",d[i]);             printf("\n");         }     }     printf("shuffle 1..n demo\n");     for (n=1;n<=5;n++) {/* 测试1～5个元素 */         printf("_____n=%d_____\n",n);         j=1;         for (c=1;c<=n;c++) j=j*c;/* j为n! */         j*=n*2;         for (c=1;c<=j;c++) {/* 测试n*2*n!次 */             for (i=1;i<=n;i++) d[i]=i;/* 填写1～n */             for (i=n;i>1;i--) {/* 打乱1～n */                 a=i;b=rand()%i+1;                 if (a!=b) {t=d[a];d[a]=d[b];d[b]=t;}             }             printf("%04d:",c);             for (i=1;i<=n;i++) printf("%d",d[i]);             printf("\n");         }     } }


Question: 关于电信短信网关SMGP3.0协议的问题

hello 楼主，你的问题解决了么？

建议楼主先学会用抓包软件比如wireshark

引用 3 楼 ForestDB 的回复:format是对的。 大神做过？能否留个联系方式 我老返回21啊  堵这了

format是对的。

哦！我还没发现呢 那我这么对时间戳赋值 sprintf(timestamp, "%02d%02d%02d%02d%02d",time->tm_mon+1,time->tm_mday,time->tm_hour,time->tm_min,time->tm_sec); 你觉得对不？

0x30 is the ascii code of 0

不知道有多少前人掉在TCP Socket send(人多)send(病少)send(财富) recv(人多病)recv(少财富) 陷阱里面啊！ http://topic.csdn.net/u/20120210/09/51109ed0-07b9-41f2-b487-a51597f2ca01.html

引用 5 楼 zhao4zhong1 的回复:建议楼主先学会用抓包软件比如wireshark 会用啊  不过抓到了也没用  MD5加密过的内容  也看不出什么来啊


Question: 新手发帖 return 可以这样用吗？

写是可以这么些，不过逻辑有点混乱，这个返回值的意义是什么？？？ x<y 和 x>y 我们知道他返回二者的最大值，x==y 返回 输出的字符个数，这个逻辑好像不对吧！！！

printf的返回值是打印出字符串的个数

lz 你自己看看   函数返回的是int类型   而你返回的是printf（“==”）   我测试的结果是==2    ==我们知道是输出“==”，但是这个2又是什么意思呢？  我们在看下lz的程序printf（”%d “，chen（3,3））  在这里等同于  printf("%d\n",printf("=="));    我们还是不知道这个2是从哪里来的！！！于是我把printf("==")改成  printf("==abc")    结果输出结果是==abc5   在这里 我想大家都应该猜想出这个5是什么意思了吧！！！没错   后面这个数字就是指  字符的个数   前面的”==“是两个字符   所以是2  而”==abc“是五个字符   所以理所当然是5啦！

这个return只是你自己定义的，没有多大意思，除非你自己让return后面有个变量值

应该是可以的

return只要返回和声明的返回类型兼容的对象即可 chen声明返回int，printf的返回值也是int，该返回值进而由return返回给chen

凑凑热闹，，，，，

可以 打印的是后面的返回结果

print是有返回值的。

#include <stdio.h> int chen(int x,int y) { 	if (x<y) 		return y; 	else if (x>y) 		return x; 	else if(x==y) 		return printf("==asd\n"); } int main() {	  	printf("一共打印了%d个字符\n",chen(3,3)); 	return 0; }这么写是可以的啊

这么简单的问题，清晰的回答，还没结贴？

printf的返回值是打印的字符串长度啊，"=="长度不就是2么

不要迷信书、考题、老师、回帖； 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实！  有人说一套做一套，你相信他说的还是相信他做的？ 其实严格来说这个世界上古往今来所有人都是说一套做一套，不是吗？  不要写连自己也预测不了结果的代码！   代码功能归根结底不是别人帮自己看或讲解或注释出来的；而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒：再牛×的老师也无法代替学生自己领悟和上厕所！ 单步调试和设断点调试是程序员必须掌握的技能之一。

看printf()函数有无返回参数，若有，再看返回的参数与当前函数要返回的类型是否一致，或者是否可以隐式转换

同意楼上的理解，printf函数也有返回值，它返回所打印的字符的数目。如果有输出错误，那么printf函数会返回一个负数。所以打印出2，有多少个字符打印出数字几，而数字前面的字符是由于返回了printf("==")函数，因此打印出“==2”。

可以参照递归函数理解，主函数调用chen(3,3),返回了printf("==")函数，主函数输出chen()函数的返回值，由于计算机打印形式为%d，故输出==2

至于 2 这个值 是printf的返回值  printf返回2是因为打印了== 2个字符 如果是打印 === 那么printf返回的就是 3 了

return后面接表达式语句  注意数据类型要能匹配 就OK

return后面加的是printf的返回值，但是为什么是2不太清楚了

return 的是printf函数的返回值


Question: 在对话框中输入一个汉字，然后程序自动以这个汉字为文档名，建立一个文本文档

//GBK汉字内码范围（不包括A1xx～A9xx的标点符号英文字母特殊符号等）    //区码  ,位码    //81-A0 ,40-7E 80-FE    //AA-AF ,40-7E 80-A0    //B0-D6 ,40-7E 80-FE    //D7    ,40-7E 80-F9    //D8-F7 ,40-7E 80-FE    //F8-FE ,40-7E 80-A0

#include <stdio.h> #include <string.h> #include <locale.h> char fn[7]; FILE *f; int main() {     setlocale(LC_ALL,"chs");     while (1) {         printf("请输入一个汉字，我们将新建一个以该汉字命名的文本文档:");fflush(stdout);         rewind(stdin);         if (1==scanf("%2s",fn)) {             if ((unsigned char)fn[0]>=0x81 && (unsigned char)fn[1]>=0x40 && fn[2]==0) break;         }     }     strcat(fn,".txt");     f=fopen(fn,"w");     if (NULL==f) {         printf("创建文件[%s]出错!\n",fn);         return 1;     }     fclose(f);     printf("创建文件[%s]成功。\n",fn);     return 1; }

引用 2 楼 cjwcommonuse 的回复:char fileName[256] = ""; scanf("%s", fileName); strcat(fileName, "txt");   //#include <stdlib.h> FILE fp = fopen(fileName, "w"); ... fp.close(); 大概是这个样子，可能某些细节不对  strcat(fileName, ".txt");   //#include <stdlib.h>

scanf fopen fclose


Question: 各位大神，如何用gcc编译器一起编译某个文件夹下的几个文件？？

多谢各位的回答，已经解决了！在命令行先输入cd 文件夹名即可进入该文件夹下，然后 gcc *.c就可以一起编译了

try to use makefile/CMake

把sqlist.c的文件声明跟main.c放在一起然后编译试试

gcc -Wall -c sqlist.c  gcc -Wall -o demo main.c sqlist.o

main.c肯定包含了common.h文件的，但是子函数都是写在sqlist.c里面的，我试了只编译main.c编译器报错的！找不到某某函数。。。

把头文件和c文件一起包含到main.c里，直接编译就可以了！编译器是从main函数开始编译的！


Question: 计算机新生面对如下几个问题不会书写，请求各位大神帮忙

提醒：再牛×的老师也无法代替学生自己学习和上厕所！

路过，自己的作业自己做。

我擦，新生怎么给这么难的题？如果学过一个学期的话，看看书还是能做出来的。。。楼主你说是不？

百度文库呀

发重复了。。。 6. #include <stdio.h> #include <string.h> int main() {  int i=0,letter=0,num=0;  char temp[100];  fgets(temp,100,stdin);  for(i=0;i<100;i++)  {    if((temp[i]>='a'&&temp[i]<='z')||(temp[i]>='A'&&temp[i]<='Z'))    {     letter++;    }    if(temp[i]>=48&&temp[i]<=58)    {      num++;    }  }  printf("num is %d letter is %d\n",num,letter);  return 0; }

看来还要再善良一点你才给分 6. #include<stdio.h> typedef struct  {  int num;  char name[10];  float ch,math,eng; }score; int main()  {  int i=0,j=0,best=0,result=0;  score arr[10];  float total[10];  printf("input number,name,scores");  for(i=0;i<10;i++)  {    scanf("%d%s%f%f%f",&(arr[i].num),&(arr[i].name),&(arr[i].ch),&(arr[i].math),&(arr[i].eng));    total[i]=arr[i].ch+arr[i].math+arr[i].eng;  }  for(i=0;i<9;i++)  {   for(j=i+1;j<10;j++)   {     if(total[i]<total[j]) 	{       best=total[i]; 	  total[i]=total[j]; 	  total[j]=best; 	}   }     }  for(i=0;i<10;i++)  {    if(best==total[i])    result=i;  }  printf("number one is%s\n",arr[result].name);  return 0; }

谢谢你得第一题，

还是我比较善良 不要太感动 1.#include<stdio.h> typedef struct  {  int num;  char name[10];  float ch,math,eng; }score; int main()  {  int i=0,j=0,best=0,result=0;  score arr[10];  float total[10];  printf("input number,name,scores");  for(i=0;i<10;i++)  {    scanf("%d%s%f%f%f",&(arr[i].num),&(arr[i].name),&(arr[i].ch),&(arr[i].math),&(arr[i].eng));    total[i]=arr[i].ch+arr[i].math+arr[i].eng;  }  for(i=0;i<9;i++)  {   for(j=i+1;j<10;j++)   {     if(total[i]<total[j]) 	{       best=total[i]; 	  total[i]=total[j]; 	  total[j]=best; 	}   }     }  for(i=0;i<10;i++)  {    if(best==total[i])    result=i;  }  printf("number one is%s\n",arr[result].name);  return 0; }

自己的作业找别人做？你是在虚心求教呢？还是想让别人帮你写作业呢？如果真是在学习当中碰见问题大家都会帮助你的，不过你这样的话。。真心有点看不起你......

自己的作业自己做。。 把书认真看一遍，我就不信你还不会做。。

沒有vc6，只能路過了。

唐浩强  c语言习题吧。

引用 1 楼 user-11 的回复:不会吧 这都已经放假了啊有的学校会在假期布置作业的，这不是显得学校重视学习嘛

不会吧 这都已经放假了啊


Question: 一个关于多尺度处理中数学稳定性的问题

个人思路：换成f(b) + f(c) = f(a)后 定义两个全局变量，分别表示等式左右奇数个数，f()都操作该数，使每次左右增长次数都一样 遇奇数就+1. PS：该思路只保证等式会成立，不具可逆性。

扩大数值不就行了 4变成8 3变成6 1变成2  这样就避免四舍五入的误差

1楼好man啊。

引用 2 楼 tangfengray 的回复:*10/5  soeasy 看错题目了

*10/5  soeasy

不存在 2-1=1 f(2)-f(1)=f(1) 于是 f(2)=2*f(1)（因为这里都是整数，并不是什么奇怪的数，所以可以两边加上f(1)） 如果等式成立，f(2)必然为偶数，这显然与一般意义上的除以2计算不同 除非lz自己定义一个除以2的行为，否则不存在这样的运算


Question: C语言求教简单问题

计算1->10的累和，你需要看一下for循环函数的使用

求一到十的和

等价于下面代码int s=10; for(i=10;0 ==i;i--) s+=i;

引用 5 楼 zhao4zhong1 的回复:for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } }  5楼说的好，就是这样，最终求的是10到1，这十个数的值

不知道这个是不是符合代码可读性的要求

这种问题没意义

就是计算从10加到1，当i=0时结束

这个是计算 S=10+9+....+1的值.  for(循环变量赋初值;循环条件(0,非0);循环变量增值)  for(;--i;)  此处省略了"循环变量赋初值"以及"循环变量增值"两个表达式,仅仅保留了"循环条件"  循环条件 一般无非是 条件关系比较 > >= < <= !=  ==   条件关系最终结果都被转化成"0""非0"两种结果.  这里的 循环条件 是--i  (i初值为10) for循环是以此变成 9 8 7 6 5 4 3 2 1 0 ,只有0会让for循环终止,前面的非0 都在执行 s+=i (s=s+i)也就是 s=10+9+8+...+3+2+1  10为s初值  9 8 ..2 1 为变量i  如果有循环 for(;1;) 那么这个for循环会一直执行下去(除非循环下面有break; goto 语句) 如果有循环for(;0;)那么这个循环不会执行以一次.  就是这个道理了.

//等同于while吧 int s=10; int i=10; while(--i) { s+=i； }

引用 5 楼 zhao4zhong1 的回复:for (A;B;C) D; //等价于 {  A;  while (1) {   if (!(B)) break;   D;   C;  } } 果断正解

这个就相当于 while（--i） {     s += i; } 就相当于计算 s = 10+9+8+7+6+5+4+3+2+1； 当--i为0的时候退出循环

i为0时，条件为false ,for循环结束

还有这种呢 for(;;) 死循环。

这个呢 就是for循环的初始化条件为空  更新条件为空(判断条件的时候有给变量自减) 这段代码的功能是求从10到1十个数的和


Question: 普里姆算法求最小生成树c语言，输出结果只有第一步。求纠正

我找不出错在哪，求解释

楼主先把代码格式化一下吧！要不看着太费劲！


Question: C语言读取txt文本里的数据。只要格式稍有复杂 就不会读了。。。

解决了~用的zhao4zhong1 和Automation_dmu 的方法 第一次注意到fscanf的返回值问题。。。  struct point { 	char num[10]; 	double x; 	double y; }; 	point pn[6]; //待判断的6个点 	char dust[50]; 	FILE *read; 	read = fopen("欲判断点.dat","r"); 	count = 0; 	fgets(dust,60,read); //fgets 后  文件指针指向下一行开头。 	int Line = 1; 	while(!feof(read)) 	{ 		if(fscanf(read,"%s%lf%lf",&pn[count].num,&pn[count].x,&pn[count].y) == 3) 		{ 			count++; 			Line++; 		} 		else 		{ 			printf("Line %d Error!\n",Line); 		} 	}   O(∩_∩)O谢谢~

std::ifstream ifs(szFileName, std::ios::in); if(ifs.fail())     return false;  ifs >> lpTestDataX >> lpTestDataY;  ifs.close();  可以参考一下！

FILE *pf; 	struct{ 		char name[16]; 		double px; 		double py; 	}p; 	pf = fopen("2.c", "r"); 	while(!feof(pf)) 	{ 		fscanf(pf, " %s %lf %lf ",p.name, &p.px, &p.py); 		printf("%-10s %-16lf %-16lf\n",p.name, p.px, p.py); 	} 	fclose(pf);

第7行前加一句i=0;

struct PS {  char no[40];  double x;  double y; } ps[100]; …… while(1) {     if (NULL==fgets(pc, 1000, pflIn)) break;     L++;     if (3==sscanf(pc,"%39s%lf%lf",ps[i].no,&ps[i].x,&ps[i].y) {       i++;     } else {      printf("line %d format error:%s",L,pc);     } }

一个思路 没有编译环境草写了一个！就是 1跳过第一行，取出剩下的行！ 2在二维数组中对数据进行核查 #include <stdio.h> #include <stdlib.h> #include <string.h> void fun(char *a,char *b,char *s) { 	int i,j; 	int c=0; 	for (i=0;i<strlen(a);i++) 	{ 		if (a[i]=='\t'&&c==0) 		{ 			c=1; 			continue; 		} 		if (c==1) 		{ 			for(j=0;a[i]!='\t';j++) 			{ 				b[j]=a[i]; 			} 			b[j]='\0'; 			c=2; 		} 		if (c==2) 		{ 			for(j=0;a[i]!='\0';j++) 			{ 				c[j]=a[i]; 			} 			c[j]='\0'; 		} 	} } int main() { 	FILE *fp; 	fp=fopen("1.txt","r"); 	char msg[40]; 	char qq[10][41]; 	char qq1[41]; 	char qq2[42]; 	memset(msg,sizeof(msg),0); 	int i=0; 	int j=0; 	while(fgets(msg,sizeof(msg)/sizeof(char),fp)) 	{ 		if (i==0){ 		        i++; 			memset(msg,sizeof(msg),0); 	       		continue; 		} 		else{ 			j++; 			strcpy(qq[j],msg); 			memset(msg,sizeof(msg),0); 		} 	} 	for (i=0;i<10;i++) 	{ 	fun(qq[i],qq1,qq2);	 	printf("%s\t%s\n",qq1,qq2); 	memset(qq1,sizeof(qq1),0); 	memset(qq1,sizeof(qq2),0); 	} 	return 0; }

引用 楼主 darksworld 的回复:点号     x坐标           y坐标 1        58589.592080  54596.681837 P2       59375.790588  53520.303530 D3       57590.790588  53675.457160 USA_90   55646.576183  54255.474606 5        59215.055150  54426.982554 P6       55644.576183  54200.474606  我建立了一个point结构体，想把6个点的x y坐标读进去 第一行用了while(c!='\n') 读到行末尾自动跳出 但是从第二行开始不知道怎么办了。  求指点。。 这样读完都是一行一行的字符串啊。那我怎么把 x y坐标存到结构体里呢？

fgets直接读一行  char pc[1000]; FILE *pflIn; pflIn = fopen("XX.txt", "rb"); fgets(pc, 1000, pflIn);//如果一行的内容小于1000个字节，读到行尾就结束。 while(!feof(pflIn)) { 	...///处理代码 	fgets(pc, 1000, pflIn);//如果一行的内容小于1000个字节，读到行尾就结束。 }


Question: 求教C语言字符串替换，在线等。

引用 4 楼 zhao4zhong1 的回复:char *sstring = "abcd"; //定义一个常量字符串abcd，再将char指针变量sstring的值保存为该常量字符串的地址 char sstring[100] = "abcd"; //定义一个100项的char字符数组sstring，再将该数组的前五个字节赋值为0x41,0x42,0x43,0x44,0x00  常量字符串abcd保存在常量区，该内存区的控制属性默认为不可写。一旦企图写，操作系统的内存管理模块发现并弹出对话框报异常。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 赵老师解释的非常到位。常量区的数据不可写。

引用 10 楼 zhao4zhong1 的回复:[quote=引用 4 楼 zhao4zhong1 的回复:] char *sstring = "abcd"; //定义一个常量字符串abcd，再将char指针变量sstring的值保存为该常量字符串的地址 char sstring[100] = "abcd"; //定义一个100项的char字符数组sstring，再将该数组的前五个字节赋值为0x41,0x42,0x43,0x44,0x00  常量字符串abcd保存在常量区，该内存区的控制属性默认为不可写。一旦企图写，操作系统的内存管理模块发现并弹出对话框报异常。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 正解！[/quote]恩，明白了，谢谢！

引用 4 楼 zhao4zhong1 的回复:char *sstring = "abcd"; //定义一个常量字符串abcd，再将char指针变量sstring的值保存为该常量字符串的地址 char sstring[100] = "abcd"; //定义一个100项的char字符数组sstring，再将该数组的前五个字节赋值为0x41,0x42,0x43,0x44,0x00  常量字符串abcd保存在常量区，该内存区的控制属性默认为不可写。一旦企图写，操作系统的内存管理模块发现并弹出对话框报异常。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 正解！

char *sstring = "abcd";  这种方式得到的字符串常量，不能修改编辑

引用 6 楼 user-5 的回复:特意上网找了找，给推荐个文章 http://blog.csdn.net/yahohi/article/details/7427724 非常感谢你推荐了一篇好文章！

引用 4 楼 zhao4zhong1 的回复:char *sstring = "abcd"; //定义一个常量字符串abcd，再将char指针变量sstring的值保存为该常量字符串的地址 char sstring[100] = "abcd"; //定义一个100项的char字符数组sstring，再将该数组的前五个字节赋值为0x41,0x42,0x43,0x44,0x00  常量字符串abcd保存在常量区，该内存区的控制属性默认为不可写。一旦企图写，操作系统的内存管理模块发现并弹出对话框报异常。  #pragma comment(linker,"/SECTION:.rdata,RW") //加这句可以让常量区可写，后果自负！ 谢谢！ 恩，后来我自己也试了一下，有new方式声明的sstring就可以被重新赋值。常量区是不是栈区呢？new出来的是保存在堆区。

断点调试显示异常信息是访问冲突，就算把18行改为sstring[i]=letter也是一样的。 但是如果把初始化中的char* sstring="abcd"改为char sstring[]="abcd"就没有异常了。

引用 2 楼 zhao4zhong1 的回复:#include<stdio.h> #include<string.h> int main(void)  {       char sstring[100] = "abcd";     printf("string before : %s\n", sstring);     char letter = '*';     char* tmp = sstring;    int con = 0;    while (*tmp++ != '\0')    {        ++con;    }    char* pp = sstring;    for (int i = 0; i < con; i++)    {        //printf("%c\n", pp[i]);       pp[i] = letter;    }    printf("%d\n", con);    printf("string after : %s\n", sstring);     return 0;  }   你好，非常感谢你的回答！ 不过我想知道为什么sstring是字符型指针的时候无法对其赋值。

#include <stdio.h> #include <string.h> #include <locale.h> char s[256]; char *p; int r,n,i; int main() {     setlocale(LC_ALL,"chs");     while (1) {         printf("请输入一行文字(空行结束),\"%%20\"将替换为\" \",\"你懂得\"将替换为\"XXXXXX\":\n");         fgets(s,256,stdin);         if ('\n'==s[0]) break;         p=s;         while (1) {             p=strstr(p,"%20");             if (p) {                 memmove(p+1,p+3,strlen(p)-3+1);                 p[0]=' ';             } else break;         }         p=s;         while (1) {             p=strstr(p,"你懂得");             if (p) {                 memmove(p+6,p+6,strlen(p)-6+1);                 for (i=0;i<6;i++) p[i]='X';             } else break;         }         printf("%s",s);     }     return 0; } //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //abcdefg%20helloworld%20something.pdf //abcdefg helloworld something.pdf //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //这是测试文字你懂得，在这个你懂的地方，就得做你懂得的事 //这是测试文字XXXXX，在这个你懂的地方，就得做XXXXX的事 //请输入一行文字(空行结束),"%20"将替换为" ","你懂得"将替换为"XXXXXX": //


XXXX_s的函数我不熟悉，也没用过，不过建议看看函数原型，看看它接收的参数有什么要求

引用 2 楼 zhao4zhong1 的回复:Read formatted data from the standard input stream. These are versions of scanf, _scanf_l, wscanf, _wscanf_l with security enhancements as described in Security Enhancements in the CRT.    int scanf_s(    const char *format [,       argument]...  ); int _scanf_s_l(    const char *format,    locale_t locale [,       argument]...  ); int wscanf_s(    const wchar_t *format [,       argument]...  ); int _wscanf_s_l(    const wchar_t *format,    locale_t locale [,       argument]...  );    Parameters format Format control string.  argument Optional arguments.  locale The locale to use.  Return Value Returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end-of-file character or the end-of-string character is encountered in the first attempt to read a character. If format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, scanf_s and wscanf_s return EOF and set errno to EINVAL.  For information on these and other error codes, see _doserrno, errno, _sys_errlist, and _sys_nerr.  Remarks The scanf_s function reads data from the standard input stream stdin and writes the data into the location given by argument. Each argument must be a pointer to a variable of a type that corresponds to a type specifier in format. If copying takes place between strings that overlap, the behavior is undefined.  wscanf_s is a wide-character version of scanf_s; the format argument to wscanf_s is a wide-character string. wscanf_s and scanf_s behave identically identically if the stream is opened in ANSI mode. scanf_s doesn't currently support input from a UNICODE stream.  The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.  Unlike scanf and wscanf, scanf_s and wscanf_s require the buffer size to be specified for all input parameters of type c, C, s, S, or [. The buffer size is passed as an additional parameter immediately following the pointer to the buffer or variable. For example, if reading a string, the buffer size for that string is passed as follows:  char s[10];  scanf("%9s", s, 10);  The buffer size includes the terminating null. A width specification field may be used to ensure that the token read in will fit into the buffer. If no width specification field is used, and the token read is too big to fit in the buffer, nothing will be written to that buffer.  Note:  The size parameter is of type unsigned, not size_t.    In the case of characters, one may read a single character as follows:  char c;  scanf("%c", &c, 1);  When reading multiple characters for non-null terminated strings, integers are used as the width specification and the buffer size.  char c[4];  scanf("%4c", &c, 4); // not null terminated  For more information, see scanf Width Specification.  TCHAR.H routine   _UNICODE & _MBCS not defined  _MBCS defined  _UNICODE defined   _tscanf_s  scanf_s  scanf_s  wscanf_s   _tscanf_s_l  _scanf_s_l  _scanf_s_l  _wscanf_s_l    For more information, see Format Specification Fields — scanf functions and wscanf Functions.   Requirements Routine  Required header   scanf_s, _scanf_s_l  <stdio.h>   wscanf_s, _wscanf_s_l  <stdio.h> or <wchar.h>    For additional compatibility information, see Compatibility in the Introduction.  Example   Copy Code  // crt_scanf_s.c // This program uses the scanf_s and wscanf_s functions // to read formatted input.    #include <stdio.h>  int main( void ) {    int      i,             result;    float    fp;    char     c,             s[81];    wchar_t  wc,             ws[81];     result = scanf_s( "%d %f %c %C %s %S", &i, &fp, &c, 1,                      &wc, 1, s, 80, ws, 80 );    printf( "The number of fields input is %d\n", result );    printf( "The contents are: %d %f %c %C %s %S\n", i, fp, c,            wc, s, ws);    result = wscanf_s( L"%d %f %hc %lc %S %ls", &i, &fp, &c, 2,                       &wc, 1, s, 80, ws, 80 );    wprintf( L"The number of fields input is %d\n", result );    wprintf( L"The contents are: %d %f %C %c %hs %s\n", i, fp,             c, wc, s, ws); }     Copy Code  71 98.6 h z Byte characters 36 92.3 y n Wide characters     Copy Code  The number of fields input is 6 The contents are: 71 98.599998 h z Byte characters The number of fields input is 6 The contents are: 36 92.300003 y n Wide characters    .NET Framework Equivalent System::Console::Read  System::Console::ReadLine  See also Parse methods, such as System::Double::Parse.  See Also Concepts Floating-Point Support Stream I/O Locale fscanf, _fscanf_l, fwscanf, _fwscanf_l printf, _printf_l, wprintf, _wprintf_l sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l sscanf, _sscanf_l, swscanf, _swscanf_l

scanf_s("%[^/n]", string,49);

用fgets吧

Read formatted data from a string. These are versions of sscanf, _sscanf_l, swscanf, _swscanf_l with security enhancements as described in Security Enhancements in the CRT.    int sscanf_s(    const char *buffer,    const char *format [,       argument ] ... ); int _sscanf_s_l(    const char *buffer,    const char *format,    locale_t locale [,       argument ] ... ); int swscanf_s(    const wchar_t *buffer,    const wchar_t *format [,       argument ] ... ); int _swscanf_s_l(    const wchar_t *buffer,    const wchar_t *format,    locale_t locale [,       argument ] ... );    Parameters buffer Stored data  format Format-control string. For more information, see Format Specifications.  argument Optional arguments  locale The locale to use  Return Value Each of these functions returns the number of fields successfully converted and assigned; the return value does not include fields that were read but not assigned. A return value of 0 indicates that no fields were assigned. The return value is EOF for an error or if the end of the string is reached before the first conversion.  If buffer or format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. If execution is allowed to continue, these functions return -1 and set errno to EINVAL  For information on these and other error codes, see _doserrno, errno, _sys_errlist, and _sys_nerr.  Remarks The sscanf_s function reads data from buffer into the location given by each argument. The arguments after the format string specify pointers to variables with a type that corresponds to a type specifier in format. Unlike the less secure version sscanf, a buffer size parameter countOfBuffer is required when using the type field characters c, C, s, S and [. This parameter must be supplied as an additional parameter after each buffer which requires it. For more information, see scanf_s, _scanf_s_l, wscanf_s, _wscanf_s_l and scanf Type Field Characters.  Note:  The size parameter is of type unsigned, not size_t.    The format argument controls the interpretation of the input fields and has the same form and function as the format argument for the scanf_s function. If copying takes place between strings that overlap, the behavior is undefined.  swscanf_s is a wide-character version of sscanf_s; the arguments to swscanf_s are wide-character strings. sscanf_s does not handle multibyte hexadecimal characters. swscanf_s does not handle Unicode full width hexadecimal or "compatibility zone" characters. Otherwise, swscanf_s and sscanf_s behave identically.  The versions of these functions with the _l suffix are identical except that they use the locale parameter passed in instead of the current thread locale.  TCHAR.H routine   _UNICODE & _MBCS not defined  _MBCS defined  _UNICODE defined   _stscanf_s  sscanf_s  sscanf_s  swscanf_s   _stscanf_s_l  _sscanf_s_l  _sscanf_s_l  _swscanf_s_l    Requirements Routine  Required header   sscanf_s, _sscanf_s_l  <stdio.h>   swscanf_s, _swscanf_s_l  <stdio.h> or <wchar.h>    For additional compatibility information, see Compatibility in the Introduction.  Example   Copy Code  // crt_sscanf_s.c // This program uses sscanf_s to read data items // from a string named tokenstring, then displays them.  #include <stdio.h> #include <stdlib.h>  int main( void ) {    char  tokenstring[] = "15 12 14...";    char  s[81];    char  c;    int   i;    float fp;     // Input various data from tokenstring:    // max 80 character string plus NULL terminator    sscanf_s( tokenstring, "%s", s, _countof(s) );    sscanf_s( tokenstring, "%c", &c, sizeof(char) );    sscanf_s( tokenstring, "%d", &i );    sscanf_s( tokenstring, "%f", &fp );     // Output the data read    printf_s( "String    = %s\n", s );    printf_s( "Character = %c\n", c );    printf_s( "Integer:  = %d\n", i );    printf_s( "Real:     = %f\n", fp ); }     Copy Code  String    = 15 Character = 1 Integer:  = 15 Real:     = 15.000000    .NET Framework Equivalent See Parse methods, such as System::Double::Parse.  See Also Concepts Stream I/O fscanf, _fscanf_l, fwscanf, _fwscanf_l scanf, _scanf_l, wscanf, _wscanf_l sprintf, _sprintf_l, swprintf, _swprintf_l, __swprintf_l _snprintf, _snprintf_l, _snwprintf, _snwprintf_l


Question: 新手求教 结合realloc 获取文件夹下的文件如何或者完整路径，我知道错在哪可是我不知道怎么写

请判断realloc的返回值！ 参考下面：//输出PROG中有但LIST中没有的文本行，即集合PROG-LIST #include <stdio.h> #include <string.h> #include <stdlib.h> #include <search.h> #define MAXCHARS 512 int MAXLINES=10000,MAXLINES2; char *buf,*buf2; char PROG[256]="PROG";//程序Program需要的文件列表 char LIST[256]="LIST";//dir /b /s生成的实际文件列表List FILE *fp,*fl; int i,c,n,L,hh; int ignore_case=0; char ln[MAXCHARS]; int icompare(const void *arg1,const void *arg2) {    return stricmp((char *)arg1,(char *)arg2); } int compare(const void *arg1,const void *arg2) {    return strcmp((char *)arg1,(char *)arg2); } int main(int argc,char **argv) {     if (argc>1) strcpy(PROG,argv[1]);//命令行参数1覆盖PROG     if (argc>2) strcpy(LIST,argv[2]);//命令行参数2覆盖LIST     if (argc>3) ignore_case=1;//若存在命令行参数3，忽略大小写     if ((fl=fopen(LIST,"rt"))==NULL) {         fprintf(stderr,"Can not open %s\n",LIST);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 1;     }     if ((fp=fopen(PROG,"rt"))==NULL) {         fclose(fl);         fprintf(stderr,"Can not open %s\n",PROG);         fprintf(stderr,"Usage: %s [PROG] [LIST] [-i]\n",argv[0]);         return 2;     }     buf=(char *)malloc(MAXLINES*MAXCHARS);     if (NULL==buf) {         fclose(fl);         fclose(fp);         fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES,MAXCHARS);         return 4;     }     n=0;     hh=0;     i=0;     while (1) {         if (fgets(ln,MAXCHARS,fl)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",LIST,hh,MAXCHARS);             while (1) {                 c=fgetc(fl);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             strcpy(buf+i,ln);i+=MAXCHARS;             n++;             if (n>=MAXLINES) {                 MAXLINES2=MAXLINES*2;                 if (MAXLINES2==1280000) MAXLINES2=2500000;                 buf2=(char *)realloc(buf,MAXLINES2*MAXCHARS);                 if (NULL==buf2) {                     free(buf);                     fclose(fl);                     fclose(fp);                     fprintf(stderr,"Can not malloc(%d LINES*%d CHARS)!\n",MAXLINES2,MAXCHARS);                     return 5;                 }                 buf=buf2;                 MAXLINES=MAXLINES2;             }         }     }     fclose(fl);     if (ignore_case) qsort(buf,n,MAXCHARS,icompare);     else qsort(buf,n,MAXCHARS,compare);     hh=0;     while (1) {         if (fgets(ln,MAXCHARS,fp)==NULL) break;//         hh++;         L=strlen(ln)-1;         if ('\n'!=ln[L]) {//超长行忽略后面内容             fprintf(stderr,"%s Line %d too long(>%d),spilth ignored.\n",PROG,hh,MAXCHARS);             while (1) {                 c=fgetc(fp);                 if ('\n'==c || EOF==c) break;//             }         }         while (1) {//去掉行尾的'\n'和空格             if ('\n'==ln[L] || ' '==ln[L]) {                 ln[L]=0;                 L--;                 if (L<0) break;//             } else break;//         }         if (L>=0) {             if (ignore_case) {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,icompare)) printf("%s\n",ln);             } else {                 if (NULL==bsearch(ln,buf,n,MAXCHARS,compare)) printf("%s\n",ln);             }         }     }     fclose(fp);     free(buf);     return 0; }

realloc Reallocate memory blocks.  void *realloc( void *memblock, size_t size );  Routine Required Header Compatibility  realloc <stdlib.h> and <malloc.h> ANSI, Win 95, Win NT    For additional compatibility information, see Compatibility in the Introduction.  Libraries  LIBC.LIB Single thread static library, retail version  LIBCMT.LIB Multithread static library, retail version  MSVCRT.LIB Import library for MSVCRT.DLL, retail version    Return Value  realloc returns a void pointer to the reallocated (and possibly moved) memory block. The return value is NULL if the size is zero and the buffer argument is not NULL, or if there is not enough available memory to expand the block to the given size. In the first case, the original block is freed. In the second, the original block is unchanged. The return value points to a storage space that is guaranteed to be suitably aligned for storage of any type of object. To get a pointer to a type other than void, use a type cast on the return value.  Parameters  memblock  Pointer to previously allocated memory block  size  New size in bytes  Remarks  The realloc function changes the size of an allocated memory block. The memblock argument points to the beginning of the memory block. If memblock is NULL, realloc behaves the same way as malloc and allocates a new block of size bytes. If memblock is not NULL, it should be a pointer returned by a previous call to calloc, malloc, or realloc.  The size argument gives the new size of the block, in bytes. The contents of the block are unchanged up to the shorter of the new and old sizes, although the new block can be in a different location. Because the new block can be in a new memory location, the pointer returned by realloc is not guaranteed to be the pointer passed through the memblock argument.  realloc calls malloc in order to use the C++ _set_new_mode function to set the new handler mode. The new handler mode indicates whether, on failure, malloc is to call the new handler routine as set by _set_new_handler. By default, malloc does not call the new handler routine on failure to allocate memory. You can override this default behavior so that, when realloc fails to allocate memory, malloc calls the new handler routine in the same way that the new operator does when it fails for the same reason. To override the default, call   _set_new_mode(1)  early in your program, or link with NEWMODE.OBJ.  When the application is linked with a debug version of the C run-time libraries, realloc resolves to _realloc_dbg. For more information about how the heap is managed during the debugging process, see Using C Run-Time Library Debugging Support.  Example  /* REALLOC.C: This program allocates a block of memory for  * buffer and then uses _msize to display the size of that  * block. Next, it uses realloc to expand the amount of  * memory used by buffer and then calls _msize again to  * display the new amount of memory allocated to buffer.  */  #include <stdio.h> #include <malloc.h> #include <stdlib.h>  void main( void ) {    long *buffer;    size_t size;     if( (buffer = (long *)malloc( 1000 * sizeof( long ) )) == NULL )       exit( 1 );     size = _msize( buffer );    printf( "Size of block after malloc of 1000 longs: %u\n", size );     /* Reallocate and show new size: */    if( (buffer = realloc( buffer, size + (1000 * sizeof( long )) ))          ==  NULL )       exit( 1 );    size = _msize( buffer );    printf( "Size of block after realloc of 1000 more longs: %u\n",              size );     free( buffer );    exit( 0 ); }   Output  Size of block after malloc of 1000 longs: 4000 Size of block after realloc of 1000 more longs: 8000   Memory Allocation Routines  See Also   calloc, free, malloc

.是本级目录 ..是上级目录 在循环中判断过滤

用readdir会出现.和..？为什么会出现呢


Question: 为什么不能激活

请检查每个函数的返回值。

路径名对么，可以改成英文的或者换个位置试试

引用 4 楼 zhao4zhong1 的回复:请检查每个函数的返回值。  #include <windows.h>  int main(void) {   char str1[]="E:\\飞机\\帮助.exe";   ShellExecute(NULL,"open",str1,NULL,NULL,SW_HIDE);   Sleep(100);      HWND hOut=FindWindow(NULL,str1);   printf("%d",hOut);      int h;   h=ShowWindow(hOut,SW_SHOWNORMAL);   printf("\n%d",h);      HWND hOut1;   hOut1=SetActiveWindow(hOut);   printf("\n%d",hOut1);      SetForegroundWindow(hOut);       getch();   if(hOut!=0)PostMessage(hOut,WM_CLOSE,0,0);	   return 0;   }  SetActiveWindow(hOut); 函数返回为0，说明没有激活。   现在问题已经搞定，用 SetForegroundWindow(HWND hOut) 函数。

引用 2 楼 xiaohuh421 的回复:FindWindow(NULL,str1);  你确定这里查找到了吗? 新开的窗口的名字, 你确定是路径名吗?  能显示 关闭，说明已经找到了。  问题已经搞定，用 SetForegroundWindow(HWND hOut) 函数。

引用 1 楼 user-6 的回复:能关闭是什么意思  就是能执行 PostMessage(hOut,WM_CLOSE,0,0);

ShellExecute(NULL,"open",str1,NULL,NULL,SW_SHOWNORMAL);不就完了

能关闭是什么意思


Question: 进程1操作数据库，并通知进程2，进程2读数据库并缓存，再给进程1返回结果，若失败，进程1如何将数据库回滚到操作之前

引用 楼主 jhyjhy1026 的回复:请教各位，如下场景的实现方案： 进程1对数据库进行增/删/改，完成操作后通知进程2；进程2读取数据库，缓存数据，完毕后给进程1返回结果，若返回失败，进程1需要将数据库回滚到增/删/改前。 注：语言：C，数据库：sqlite3。 问题：如何回滚？进程1对数据库进行操作后已提交事务，否则进程2查询不到最新的数据，此时有什么方案可以还原数据库到进程1操作之前。 就只能自己实现日志了，要是单线程的话还好，多线程的话建议你还是换数据库把 这玩意要自己写的话不简单的

这只是一个执行顺序的问题  进程1把要增删改的数据 交给进程2   进程2缓存，成功则进程2去操作数据库，并返回结果给进程1，失败则直接返回进程1

引用 7 楼 jhyjhy1026 的回复:脱离数据库，考虑程序设计上的其他方案，刚才想用共享内存，貌似也不太合理，实在想不出好方案了。。。 SQL存储过程中的BEGIN TRANSACTION，ROLLBACK TRANSACTION，COMMIT TRANSACTION事务处理功能不是那么容易自己实现的。

建议将本来打算写到C进程中的逻辑挪到SQL存储过程中实现。

sqlite转SQL Server应该不费什么劲吧。

没有其他办法了吗？换数据库估计够呛了，项目已经进入中后段了。

引用 2 楼 jhyjhy1026 的回复:sqlite好像不支持存储过程。 换SQL Server或MySQL

各位大神们，求支招啊!

sqlite好像不支持存储过程。


Question: 单链表删除不对劲

void delelist_all(list *&L, int n) { 	list *p1, *p2; 	list *head; 	head = L; 	p1 = head; 	list* head_temp = head;    //作为临时头结点 	while (p1 != NULL) 	{ 		p1 = findlist_single(head_temp, n);  //从临时头结点开始查找第一个D为n的结点 											//如果没有找到则p1为NULL，循环结束 		p2 = p1->next; 		p1->next = p2->next; 		free(p2);  		/*p1 = p1->next; 		p2 = p1; 		if (p2->D == n) 		{ 			delelist_single(head, n); 		}*/ 	} }  我对删除全部做了修改，这个编译并没有通过，你可以根据这个思路自己再改改。 不过今晚我没有时间了，明早有事要早睡，明天下午我帮你再看看。

read stl list source code. and slist a plus

楼主这样操作看上去每次删除之后链表就断了，因为你把中间的节点删了之后没有把前后的节点再连起来。

void delelist_all(list *&L, int n) { 	list *p1, *p2; 	list *head; 	head = L; 	p1 = head;  	while (p1->next != NULL)  //尾结点之前判断 	{ 		p2 = p1->next;		 		if (p2->D == n){ 			p1->next = p2->next; 			free(p2); 		} 		else 			p1 = p1->next; 	} 	if (p1->D == n){    //判断尾结点 		p1->next = NULL; 		free(p1); 	} }  严谨的说应该这样处理，才会覆盖所有的输入情况。

void delelist_single(list *&L,int n)//has been done { 	list *p1,*p2,*head; 	head=L; 	p1=findlist_single(head,n); 	if(p1!=NULL) 	{ 		p2=p1->next; 		p1->next=p2->next;//这里应该将前一元素的next指向跳过删除的元素 		free(p2); 	} }  void delelist_all(list *&L,int n) { 	list *p1,*p2,*p3; 	list *head; 	head=L; 	p1=head; 	while(p1!=NULL) 	{ 		p1=p1->next; 		p2=p1; 		if(p2->D==n) 		{ 			delelist_single(head,n); 		} 	} }   这是我修改后的例程 到底哪里不对哇→_→

引用 1 楼 Falleyes 的回复:#include "stdio.h" #include "stdlib.h" #include "malloc.h"  typedef struct node { 	int D; 	node *next;//to back }list;  //单链表例程 void init_single(list *&L); void creatlist_single(list *&L, int n); void printlist_single(list *&L); list* findlist_single(list *&L, int n);//用于发现一个节点的前驱元.n为要发现的节点 void delelist_single(list *&L, int n);//删除为n的 void delelist_all(list *&L, int n);//删除所有为n的 void cutlist_single(list *&L, int n);//插入例程  int main() { 	int n, m; 	list *L;//相当于head指针 	scanf("%d", &n);//确定链表长度 	creatlist_single(L, n); 	printlist_single(L); 	scanf("%d", &m);//要删除的数 	delelist_single(L, m); 	printlist_single(L); 	//delelist_all(L,m); 	//printlist_single(L); 	return 0; }   void init_single(list *&L)//has been done { 	L = (list*)malloc(sizeof(list)); 	L->next = NULL; }  void creatlist_single(list *&L, int n)//has been done { 	list *s, *r; 	init_single(L); 	r = L; 	while (n--) 	{ 		s = (list*)malloc(sizeof(list)); 		scanf("%d", &s->D); 		r->next = s; 		r = r->next;//important!   is right!!! 	} 	r->next = NULL; }  void printlist_single(list *&L)//has been done { 	list *p; 	p = L->next; 	while (p != NULL) 	{ 		printf("%d", p->D); 		p = p->next; 	} 	printf("\n"); }  list* findlist_single(list *&L, int n)//此例程用于寻找一个节点的前驱元 { 	list *head; 	list *p1, *p2; 	int tag = 0;//if find,tag=1,else tag=0,return NULL; 	head = L; 	p1 = head;    //注意这里，初始化不应该是p1=head->next,因为循环中一开始就p1=p1->next; 	while (p1 != NULL) 	{ 		p1 = p1->next; 		p2 = p1; 		p2 = p2->next; 		if (p2->D == n) 		{ 			tag = 1; 			break; 		} 	} 	if (tag == 1) 		return p1; 	else 		return NULL; }  void delelist_single(list *&L, int n)//has been done { 	list *p1, *p2, *head; 	head = L; 	p1 = findlist_single(head, n); 	if (p1 != NULL) 	{ 		/*p1 = p1->next; 		p2 = p1; 		p1 = p2->next;*/  		p2 = p1->next;     		p1->next = p2->next;   //这里应该将前一元素的next指向跳过删除的元素  		free(p2); 	} }  void delelist_all(list *&L, int n) { 	list *p1, *p2, *p3; 	list *head; 	head = L; 	p1 = head->next; 	while (p1 != NULL) 	{ 		p2 = findlist_single(head, n); 		if (p2 != NULL) 		{ 			p2 = p2->next; 			p3 = p2; 			p2 = p3->next; 			free(p3); 		} 		p1 = p1->next; 	} }  还有些问题额，第一个删除例程都弄好了，但是删除全部为n的例程还是不对，可以继续求教下嘛？