文章目录
一、QString转char*的问题
问题说明:
const char* c = str.toStdString().c_str()
上面类型转换偶尔会出现问题,转换后按%s打印输出会出现乱码。
最难受的是有时正确、有时错误,完全没有规律。
解决方法:
std::string s = str.toStdString();
const char* c = s.c_str();
问题分析:
上述问题类型转化单步调试显示的结果可能会是’\0’,str.toStdString().c_str()中toStdString()是一个临时std::string变量,而c_str()是指向这个临时std::string变量的字符串地址,所以传给c时这个临时std::string变量已经被析构,其内容是空,c_str()自然就是’\0’。不过这种情况在未知情况下发生,有时直接写QString::toStdString().c_str() 也是好用的。
~~ ———————————————————————~~
二、读取结构体时,读取错误
问题说明:
读取结构体文件时,在保证结构体格式正确的前提下,读取第一条结果正确,其余的数据错误。
解决方法:
设置结构体的边界对齐为1个字节,也就是所有数据在内存中是连续存储的。
内存对齐,在文件头添加下面语句
#pragma pack(1)
问题分析:
#pragma pack 的主要作用就是改变编译器的内存对齐方式,#pragma pack(n)是他最基本的用法,其作用是改变编译器的对齐方式, 不使用这条指令的情况下,编译器默认采取#pragma pack(8)也就是8字节的默认对齐方式,n值可以取(1, 2, 4, 8, 16) 中任意一值。
比如定义一个这样的结构体:
struct s {
char ch;
int i;
};
然后在主函数中写一句:printf("%d", sizeof(struct s))
也就是输出结构体s所占的字节数,你觉得输出结果会是多少呢?
我们知道,char型占用1个字节,int型占4个字节,那么输出的结果是5吗?
答案是否定的。你可以自己试一下,输出结果为8。
为什么会这样呢?这是因为编译器为了让程序跑得跟快,减少CPU读取数据的指令周期,对结构体的存储进行了优化。实际上第一个char型成员虽然本来只有1个字节,但实际上却占用掉了4个字节,为的是让第二个int型成员的地址能够被4整除。因此实际占用的是8个字节。
而#pragma pack(1)让编译器将结构体数据强制连续排列,这样的话,sizeof(struct s)输出的结果就是5了。
参考:https://www.jianshu.com/p/d994731f658d
参考:https://blog.youkuaiyun.com/u012206617/article/details/89296515
———————————————————————
三、时间戳与标准时间的转换
1. 时间戳转换成标准时间
typedef struct times
{
int Year;
int Mon;
int Day;
int Hour;
int Min;
int Second;
}Times;
Times stamp_to_standard(int stampTime)
{
time_t tick = (time_t)stampTime;
struct tm tm;
char s[100];
Times standard;
//tick = time(NULL);
tm = *localtime(&tick);
strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", &tm);
printf("%d: %s\n", (int)tick, s);
standard.Year = atoi(s);
standard.Mon = atoi(s+5);
standard.Day = atoi(s+8);
standard.Hour = atoi(s+11);
standard.Min = atoi(s+14);
standard.Second = atoi(s+17);
return standard;
}
2. 标准时间转换成时间戳
int standard_to_stamp(char *str_time)
{
struct tm stm;
int iY, iM, iD, iH, iMin, iS;
memset(&stm,0,sizeof(stm));
iY = atoi(str_time);
iM = atoi(str_time+5);
iD = atoi(str_time+8);
iH = atoi(str_time+11);
iMin = atoi(str_time+14);
iS = atoi(str_time+17);
stm.tm_year=iY-1900;
stm.tm_mon=iM-1;
stm.tm_mday=iD;
stm.tm_hour=iH;
stm.tm_min=iMin;
stm.tm_sec=iS;
/*printf("%d-%0d-%0d %0d:%0d:%0d\n", iY, iM, iD, iH, iMin, iS);*/ //标准时间格式例如:2016:08:02 12:12:30
return (int)mktime(&stm);
}
3.获得系统标准时间
time_t rawtime ;
struct tm * timeinfo;
time ( &rawtime );
timeinfo = localtime ( &rawtime );
4. 获得当前时间戳
time_t now;
int unixTime = (int)time(&now);
参考:https://blog.youkuaiyun.com/wangqing_12345/article/details/52092728
5.使用Qt库函数进行时间的转换
前四个标题是自己用C语言写函数实现的,如果读者嫌麻烦或者不喜欢这么用,可与使用Qt自己封装的类进行实现,简单直接粗暴。
QDateTime time = QDateTime::currentDateTime(); //获取当前时间
int timeT = time.toTime_t(); //将当前时间转为时间戳
time = QDateTime::fromString(timeString, "yyyy-MM-dd hh:mm:ss"); //将字符串转化成标准时间
timeT= time.ToTime(); //将标准时间转化成时间戳
QDataTime time_1 = QDateTime::fromTime_t(StartTimeStamp); //将时间戳转化位标准时间
QString time_s=time_1.toString("yyyy-MM-dd hh:mm:ss"); //将时间转换成年月日时分秒格式的字符串
———————————————————————
四、Qt中遍历文件夹及子文件
传入一个目录路径,实现递归寻找目录下的文件,与QFileDialog搭配使用最佳。
bool FindFile(const QString & path)
{
QDir dir(path);
if (!dir.exists())
return false;
dir.setFilter(QDir::Dirs|QDir::Files);
dir.setSorting(QDir::DirsFirst);
QFileInfoList list = dir.entryInfoList();
int i=0;
do{
QFileInfo fileInfo = list.at(i);
if(fileInfo.fileName()=="."||fileInfo.fileName()=="..")
{
i++;
continue;
}
bool bisDir=fileInfo.isDir();
if(bisDir)
{
nFiles++;
qDebug() << qPrintable(QString("%1 %2 %3").arg(fileInfo.size(), 10) .arg(fileInfo.fileName(),10).arg(fileInfo.path()))<<endl;
FindFile(fileInfo.filePath());
}
else{
if(fileInfo.baseName()=="PeopleCount")
{
nFiles++;
//对最底层文件的处理操作
}
}
i++;
}while(i<list.size());
return true;
}
———————————————————————
五、重装系统无法在驱动0的分区1上安装windows
问题说明:
在通过U盘或光盘安装win8/win8.1/win10 时,遇到无法安装的问题,提示“无法在驱动器0的分区1上安装windows”,格式化分区也不能解决,进而提示Windows无法安装到这个磁盘,选中的磁盘采用GPT/MBR分区形式。
解决方法
方法一:遇到无法在驱动器0的分区1上安装的问题时,可以重启电脑,重新选择U盘启动项,比如之前选了不带UEFI的,现在选择带UEFI的启动项
方法二:点击“驱动器选项(高级)”,然后删除所有分区,再点击“新建”建立新的分区,新建立的分区就是跟BIOS对应的分区表类型。
方法三:通过命令方法,转换磁盘格式
1、在当前安装界面按住Shift+F10调出命令提示符窗口;
2、输入“diskpart”,按回车执行,进入DISKPART命令模式;
3、输入“list disk”回车,列出当前磁盘信息;
4、输入“select disk 0”回车,选中磁盘0;
5、输入“clean”,删除磁盘分区;
6、输入“convert mbr”,回车,将磁盘转换为MBR,或者,输入“convert gpt”将磁盘转换为GPT;
7、输入“exit”,回车,退出DISKPART命令模式,再次输入“exit”,回车,退出命令提示符,返回安装界面继续安装系统。
问题分析
win8/win10系统均添加快速启动功能,预装的win8/win10电脑默认都是UEFI引导和GPT硬盘,传统的引导方式为Legacy引导和MBR硬盘,UEFI必须跟GPT对应,同理Legacy必须跟MBR对应。如果BIOS开启UEFI,而硬盘分区表格式为MBR则无法安装;BIOS关闭UEFI而硬盘分区表格式为GPT也是无法安装Windows。
多数电脑同时支持UEFI引导和Legacy引导,如果制作了win8或win10 x64原版启动盘,那么可能会出现两个U盘启动项,一个是带有UEFI的表示从UEFI引导,一个是不带UEFI,表示Legacy传统方式引导。
参考:https://www.cnblogs.com/superlizhao/p/8178022.html
———————————————————————
六、char*、char[]、string之间的转换
string str="hello world";
char str2[]="0";
char* str1=str.c_str(); //string=>char*
string str=str1; //char*=>string
strcpy(str2,str1); //char*=>char[]
memcpy(str2,str1,strlen(str1)); //char*=>char[]
for(int i=0; i<str.length(); i++) //string => char[]
{
str2[i] = str[i];
}
string str3 = str2; //char[] => string
char* str4 = str2; //char[] => char*
详情请访问:https://blog.youkuaiyun.com/Hello_LHL/article/details/96902182
七、C库函数 strtok()
C 库函数 char *strtok(char *str, const char *delim) 分解字符串 str 为一组字符串,delim 为分隔符。
原型:
char *strtok(char *str, const char *delim)
实例:
#include <string.h>
#include <stdio.h>
int main () {
char str[80] = "This is a website";
const char s[2] = " ";
char *token;
/* 获取第一个子字符串 */
token = strtok(str, s);
/* 继续获取其他的子字符串 */
while( token != NULL ) {
printf( "%s\n", token );
token = strtok(NULL, s);
}
return(0);
}
八、mysql 替换字段部分内容
UPDATE更新一个字段中的的部分内容
现在有一条记录的字段是“abcdefg",现在我只想将该字段中的c改为C,update语句应该怎么写?
update 表名 set 字段1 = replace(字段1,'c','C')
九、qt 纯c或c++ 项目或者在控制台调试时出现 中文乱码
加入代码:
system("chcp 65001");
//修改qtcreator_process_stub.exe的字符编码为utf8