[置顶] 问题汇总与解决

1、NSS库调用之前务必做到初始化NSS库

Code:

<span style="font-family:KaiTi_GB2312;font-size:18px;">	PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
	PR_STDIO_INIT();
	PR_SetConcurrency(5);

	rv=NSS_NoDB_Init(".");
	if (rv!=SECSuccess)
	{
		printf("Error!");
		return -1;
	}</span>
2、在用C++进行内存申请开辟的时候:

char *pc = new char('a'); //开辟一个内存单元,并用括号里的初始化 char *pca = new char[15]; //开辟一个数组 PS: 释放内存的方法也不一样: delete pc; delete []pc;

而用C进行内存申请的时候,malloc和free用的是小括号,注意他们两种语言上的差别。

3、字符串与十六进制

    程序在对中文汉字进行编码时需要转换为十六进制,如果我们已经获得了中文汉字所对应的十六进制串时,我们需要对其进行解析翻译成所代表的中文,实现这段功能的代码如下(将十六进制串通过main函数的argv[1]传进去):

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char* argv[])
{
	printf("argv[1]=%s\n",argv[1]);
	int i = 0 ,j = 0,k = 0;

	char *p = (char*) malloc(sizeof(char) * 255);
	if (NULL == p)
	{
		printf("no more memory.\n");
		exit(EXIT_FAILURE);
	}
	memset(p,'\0',255);
	char chTemp [3] = {0};
	for (;i<strlen((const char *)argv[1]);i+=4)
	{
		//strcpy(&chTemp[j++],(const char *)(&argv[1][i+2]));
		//strcpy(&chTemp[j++],(const char *)(&argv[1][i+3]));
		chTemp[j++] = argv[1][i+2];
		chTemp[j++] = argv[1][i+3];
        chTemp[j] = '\0';

		sscanf(chTemp,"%x",&p[k++]);//from chTemp to p[k++]
		//sprintf(&p[k++],"%x",chTemp);//from p[k++] to chTemp

		j = 0;
		memset(chTemp,'\0',3);
	}
	printf("p=%s\n",p);

	char *pp="\xE4\xB8\x9A";
	printf("pChar=%s\n",pp);

	free(p);

	return 0;
}

在linux下默认采用utf8编码,那么中文汉字“业”所对应的十六进制为“\xE4\xB8\x9A”,那么如下执行该程序:mian "\xE4\xB8\x9A".  因为在windons平台下,默认采用的GBK编码,因此如果在windons下运行改程序的话是乱码。

说明:

1.在将十六进制\xE4\xB8\x9A传入到main时,main函数会将其视为一整个字符串来解析,因此会对\x当成字符来处理而非是十六进制的说明符号处理,因此函数体内的for循环采用i+2和i+3的方法跳过对\x的解析。

2.虽然argv[1]和函数体内的pp的内容都是"\xE4\xB8\x9A",但是所代表的意义不一样,前者是字符串,后者虽然也是字符串,但是在解析的时候遇到\x时,程序会知道,该字符串是十六进制数。通过F9断点+F10单步执行+内存窗口来观察内存的值。

3.以字符‘E’为例,如果是字符的话,那么其值为69(ascii码为:01000101)而如果是十六进制字符的话,那么其值是14.

4.注意字符串拷贝函数strcpy所操作的对象是字符串,如果是字符的拷贝的话建议不要使用该函数,字符间直接赋值即可。(字符拷贝时需要注意&:strcpy(&chTemp[j++],(const char *)(&argv[1][i+2]));)

5.sscanf与sprintf;memcpy与strcpy

C++实现方法:

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <string>
using namespace std;

int main(int argC, char ** argV){

  cout << "argV[1]:" << argV[1] << endl;

  string strTransfer(argV[1]);
  cout<<"strTransfer="<<strTransfer<<endl;

  string strDest;
  
  for(int i = 0; i < strTransfer.length(); i+=4){
    stringstream ssTmp;
    ssTmp << std::hex << strTransfer.substr(i+2, 2);
    int ch;
    ssTmp >> ch;
    strDest.push_back(ch);
  }
  cout << strDest << endl;

  return 0;
}

将"十六进制字符串"转十六进制内存数据

/* 十六进制字符串转十六进制 
*比如:将"abcdef0123"转为内存abcdef0123
*/
static int str2hex (const unsigned char *in, unsigned char *out, int outl)
{
	int i,j;
	unsigned char chOut[512] = {0};
	unsigned char chtemp[4] = {0};  

	if (strlen((char *)in) > 1024) {
		printf("The length of out < 1024.\n");
		return 0;
	}

	for (i = 0,j = 0; i < strlen((char *)in)/2; i++) {
		chtemp[0] = in[j++];
		chtemp[1] = in[j++];
		sscanf((char *)chtemp, "%x", &chOut[i]);
		//memset(chtemp, 0, 4);
	}

	if (outl >= i) {
		//strcpy(out, chOut);
		//strcpy_s(out, i, chOut);
		memcpy(out, chOut, i);
	} else {
		printf("The length of outl is small.\n");
		return 0;
	}

	return 1;
}

以十六进制显示的内存数据转为十六进制字符串并将其十进制数据显示出来

#include <stdio.h>  
#include "stdlib.h"
/*
*将内存为两个字节的01F6二进制数据以十进制显示,即502.
*/
void main()   
{   
	long lTemp;
	int nValude = 0;  
	int *pInt = NULL;
	char *p1 = "01F6";
	unsigned char *p2 = "\x01\xF6";
	char p3[5] = {0};

	/* 法一,将内存的01F6保存为01F6的字符串 */
	sprintf(&p3[0], "%x", p2[0]);
	sprintf(&p3[1], "%x", p2[1]);
	sscanf(p3, "%x", &nValude);      
	printf("%d\r\n", nValude);  

	/* 法二,注意大端与小端 */
	pInt = p2;
	printf("%d\n", *pInt);
	printf("%p\n", pInt);
	printf("%p\n", p2);

	/* 法三,每个字节求值后累加 */
	printf("%d\n", *p2*256 + *(p2+1));

	system("pause");
	return 0;
}  


4、C语言中字符与字符串比较

    在C语言中如果是单个字符的变量可以直接用==进行是否相等的判断,但如果是字符串数组或字符串指针则需要用strcmp进行是否相等的判断,如果直接用==则是两个字符串地址的判断。


5、数组与指针的区别;重载与重写

    这两个基本的概念我就不写了,网上很多,自己搜吧。


6、见如下代码

int _tmain(int argc, _TCHAR* argv[])
{
	char *pStr1,*pStr2;
	pStr1 = new char[10];
	pStr2 = new char[10];

	char *pstr = "abcde";
	for (int i=0;i<5;i++){
		sprintf(&pStr1[i*2],"%02X",61);
	}

	for (int i=0;i<5;i++){
		sprintf(pStr2+i*2,"%02X",pstr[i]);
	}

	printf("pStr1=%s,pStr2=%s",pStr1,pStr2);

	if (pStr1){
		delete pStr1;
		pStr1 = NULL;
	}
	if (pStr2){
		delete pStr2;
		pStr2 = NULL;
	}

	return 0;
}
pStr1[i*2]的返回值是char而pStr2+i*2的返回值是char*;两者在作为strcpy或sprintf或sscanf等类型是char*的参数时候尤其注意,如果要用pStr1[i*2]时需要加上取地址符&。


7.给字符数组赋值于字符与数字时的区别

如下代码:    

    char chT[10] = {0};
    chT[0] = '\x4';
    chT[1] = '4';
    chT[2] = 4;

断点调试时,内存数据如下:0x002DF408  04 34 04 00 00 00 00 00 00 00

分析:查看ASCII码得到字符4的值是52(十六进制是34,而VS断点调试内存框显示的数据正是按十六进制将其内存数据显示的);\x属于转义符,后面跟两位十六进制数,该两位十六进制数为对应字符的十六进制ascii码值,即\x后面跟的十六进制数据就是内存里面的数据。


你可能感兴趣的:([置顶] 问题汇总与解决)