本文的目的是介绍更改C输出而不改变main()函数[closed]的详细情况,特别关注c语言中修改之前输入的信息的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解更改C
本文的目的是介绍更改C输出而不改变main()函数[closed]的详细情况,特别关注c语言中修改之前输入的信息的相关信息。我们将通过专业的研究、有关数据的分析等多种方式,为您呈现一个全面的了解更改C输出而不改变main()函数[closed]的机会,同时也不会遗漏关于Bash比较输出而不是命令、c – Qt MainWindow CloseEvent Mac Cmd Q.、c – 如何有效地将cv :: Mat的给定通道设置为给定值而不改变其他通道?、c – 解释Valgrind的trace-malloc输出的知识。
本文目录一览:- 更改C输出而不改变main()函数[closed](c语言中修改之前输入的信息)
- Bash比较输出而不是命令
- c – Qt MainWindow CloseEvent Mac Cmd Q.
- c – 如何有效地将cv :: Mat的给定通道设置为给定值而不改变其他通道?
- c – 解释Valgrind的trace-malloc输出
更改C输出而不改变main()函数[closed](c语言中修改之前输入的信息)
#include<iostream.h>void main(){ cout<<"love";}
问题是我们如何才能将这个程序的输出变成
“我爱你”,而不会改变main().
解决方法
#include <iostream>// to make sure std::cout is constructed when we use it// before main was called - thxx to @chapparstd::ios_base::Init stream_initializer;struct caller { caller() { std::cout << "I "; } ~caller() { std::cout << " You"; }} c;// ohh well,for the br0ken main functionusing std::cout;int main(){ cout<<"love";}
我想我应该解释为什么这个工作.该代码定义了一个具有构造函数和析构函数的结构.当您创建一个结构体的对象时运行构造函数,并且在销毁该对象时运行析构函数.现在,在结构定义的最后,你可以放置具有调用者类型的声明符.
所以,我们上面所做的是在程序启动时创建一个名为c的对象,它被构造(并且被调用),甚至在main运行之前.当程序终止时,对象被破坏,析构函数运行.之间,主打印“爱”.
该模式实际上是由RAII术语非常明确的,RAII通常在构造函数中声明一些资源,并在析构函数调用中再次释放它.
Bash比较输出而不是命令
#!/bin/sh REMOTEMD5=$(ssh user@host 'md5sum file.txt') LOCALMD5=$(md5sum 'file.txt') if [$LOCALMD5 !== $REMOTEMD5] then echo "all OK" else echo -e "no match,Local:"$LOCALMD5"\nRemote:"$REMOTEMD5 fi
这返回第4行:[6135222a12f06b2dfce6a5c1b736891e:command not found
我试过在$LOCALMD5周围使用“或”,但似乎没有能够比较输出,我做错了什么?
谢谢
if [ "$LOCALMD5" == "$REMOTEMD5" ]
这应该更好.
编辑:我认为你的代码中有==和!=反转.
c – Qt MainWindow CloseEvent Mac Cmd Q.
#include "mywindow.h"#include <QApplication>int main(int argc,char *argv[]) { QApplication a(argc,argv); MyWindow w(); w.show(); return a.exec(); }
MyWindow从QMainWindow派生并覆盖closeEvent(QCloseEvent *)方法,当我关闭应用程序窗口时调用此方法(例如单击windows(x)关闭按钮),但是当我通过main关闭应用程序时不会调用它菜单 – > “退出”或通过“CMD Q”键快捷键.
通过浏览网页和众多问题,我得到的结论是关闭应用程序应调用所有顶级窗口的closeEvent.这不是这种情况,或者这里出了什么问题?
编辑:除了上面关闭应用程序的方法之外,还有其他我一般应该处理的实例会导致QApplication :: quit而不是调用窗口的close事件吗?例如系统关闭怎么样?
在处理一个关闭事件时,我确认用户确实想要退出,我确保清理就像写回更改的设置一样.我是否应该将清理/保存设置移到析构函数中并在closeEvent中执行确认查询?
解决方法
QApplication::quit()
,这将不会触发您的MyWindow :: closeEvent(). 在您的UI中,您应该添加一个名为Exit的菜单项(在Mac上它将自动重命名为Quit),在MyWindow类构造函数中,您应该将该操作连接到close()
插槽(从QWidget继承).
更新 – 为了解决您的其他问题,不应该只使用析构函数来释放内存(释放文件锁等).任何可能涉及用户交互的事情(例如提示文件位置或通过QMessageBox警告用户某些事情失败)都需要进入closeEvent方法.保存窗口几何(以及使用QSettings的其他简单项目)也应该通过closeEvent来完成(但是,我已经看到了在析构函数中保存几何的代码,可能会出现一些边缘情况,它会出现意外情况).
c – 如何有效地将cv :: Mat的给定通道设置为给定值而不改变其他通道?
cv::Mat mat; // with type CV_BGRA...mat.getChannel(3) = Scalar(120); // <- this is what I want to do
P.S .:我的当前解决方案首先将mat拆分成多个通道,并设置alpha通道,然后将它们合并.
P.S.2:我知道如果我也想改变其他渠道,我可以快速做到这一点:
mat.setTo(Scalar(54,154,65,120));
更新与广义解决方案:
两种方法都可用于将给定通道上的所有垫值设置为给定值.并且它们将适用于所有矩阵,无论它们是否连续.
方法1 – 更有效率
– >基于@ Antonio的答案,并由@MichaelBurdinov进一步改进
// set all mat values at given channel to given valuevoid setChannel(Mat &mat,unsigned int channel,unsigned char value){ // make sure have enough channels if (mat.channels() < channel + 1) return; const int cols = mat.cols; const int step = mat.channels(); const int rows = mat.rows; for (int y = 0; y < rows; y++) { // get pointer to the first byte to be changed in this row unsigned char *p_row = mat.ptr(y) + channel; unsigned char *row_end = p_row + cols*step; for (; p_row != row_end; p_row += step) *p_row = value; }}
方法2 – 更优雅
– >基于@ MichaelBurdinov的答案
// set all mat values at given channel to given valuevoid setChannel(Mat &mat,unsigned char value){ // make sure have enough channels if (mat.channels() < channel+1) return; // check mat is continuous or not if (mat.isContinuous()) mat.reshape(1,mat.rows*mat.cols).col(channel).setTo(Scalar(value)); else{ for (int i = 0; i < mat.rows; i++) mat.row(i).reshape(1,mat.cols).col(channel).setTo(Scalar(value)); }}
P.S .:值得注意的是,根据documentation,使用Mat :: create()创建的矩阵始终是连续的.但是,如果使用Mat :: col(),Mat :: diag()等提取矩阵的一部分,或者为外部分配的数据构造矩阵头,则此类矩阵可能不再具有此属性.
解决方法
mat.reshape(1,mat.rows*mat.cols).col(3).setTo(Scalar(120));
如果不连续:
for(int i=0; i<mat.rows; i++) mat.row(i).reshape(1,mat.cols).col(3).setTo(Scalar(120));
编辑(感谢Antonio发表评论):
请注意,这段代码可能是最短的,它没有分配新的内存,但根本没有效率.它可能甚至比分割/合并方法更慢.当OpenCV对于连续1个像素的非连续矩阵执行操作时,效率是非常低的.如果时间性能很重要,您应该使用@Antonio提出的解决方案.
只是他的解决方案略有改进:
const int cols = img.cols;const int step = img.channels();const int rows = img.rows;for (int y = 0; y < rows; y++) { unsigned char* p_row = img.ptr(y) + SELECTED_CHANNEL_NUMBER; //gets pointer to the first byte to be changed in this row,SELECTED_CHANNEL_NUMBER is 3 for alpha unsigned char* row_end = p_row + cols*step; for(; p_row != row_end; p_row += step) *p_row = value; }}
这可以节省x的增量操作和一个较小的寄存器值.在资源有限的系统上,可以提供〜5%的加速.否则时间表现将是一样的.
c – 解释Valgrind的trace-malloc输出
--16301-- malloc(8) = 0x4EAD748 --16301-- free(0x4EAD748) --16301-- free(0x4EAD498) --16301-- malloc(21) = 0x4EAD780 --16301-- malloc(8) = 0x4EAD838 --16301-- free(0x4EAD6F8) --16301-- calloc(1,88) = 0x4EAD870 --16301-- realloc(0x0,160)malloc(160) = 0x4EB1CF8 --16301-- realloc(0x4EB9F28,4) = 0x4EBA060
有没有一个工具来解析这个输出,并告诉我每个地址是否没有正确分配和释放匹配的一对?
GCC与mtrace()函数和mtrace命令行工具类似,但格式不同.
奖金问题:是否可以在“绝对丢失”语句旁边输出实际地址?
(我将这个“C”和“C”标记为最有可能与Valgrind一起使用的两种语言.)
解决方法
#include "boost/regex.hpp" #include <functional> #include <iostream> #include <iterator> #include <map> #include <stdexcept> #include <string> #include <vector> namespace re = boost; long to_long(std::string const& s) { return strtol(s.c_str(),10); } template <typename T> static void insert(T& map,std::string const& address,std::string const& call,size_t size) { if (!map.insert(std::make_pair(address,std::make_pair(call,size))).second) std::cout << "WARNING: duplicate address for " << call << ": " << address << "\n"; } template <typename T> static void erase(T& map,std::string const& call) { auto it(map.find(address)); if (it == map.end() && address != "0x0") std::cout << "WARNING: spurIoUs address in " << call << "\n"; else map.erase(it); } static void process(std::istream& in) { std::map<std::string,std::pair<std::string,size_t>> m; std::vector<std::pair<re::regex,std::function<void(re::smatch&)>>> exps; exps.emplace_back(re::regex(".*(malloc\\((.*)\\)) = (.*)"),[&](re::smatch& results){ ::insert(m,results[3],results[1],::to_long(results[2])); }); exps.emplace_back(re::regex(".*(free\\((.*)\\))"),[&](re::smatch& results){ ::erase(m,results[2],results[1]); }); exps.emplace_back(re::regex(".*(calloc\\((.*),(.*)\\)) = (.*)"),results[4],::to_long(results[2]) * ::to_long(results[3])); }); exps.emplace_back(re::regex(".*(realloc\\((.*),results[1]); ::insert(m,::to_long(results[3])); }); for (std::string line; std::getline(in,line); ) { re::smatch results; for (auto it(exps.begin()),end(exps.end()); it != end; ++it) { if (re::regex_match(line,results,it->first)) { (it->second)(results); break; } } } size_t total{0}; for (auto it(m.begin()),end(m.end()); it != end; ++it) { std::cout << "leaked memory at " << it->first << " " << "from " << it->second.first << "\n"; total += it->second.second; } std::cout << "total leak: " << total << "\n"; } int main(int,char*[]) { try { ::process(std::cin); } catch (std::exception const &ex) { std::cerr << "ERROR: " << ex.what() << "\n"; } }
因为gcc的当前版本的std :: regex似乎是错误的,所以我使用了Boost的实现.应该很容易切换版本:只需将re定义为std的别名,而不是boost.
今天关于更改C输出而不改变main()函数[closed]和c语言中修改之前输入的信息的介绍到此结束,谢谢您的阅读,有关Bash比较输出而不是命令、c – Qt MainWindow CloseEvent Mac Cmd Q.、c – 如何有效地将cv :: Mat的给定通道设置为给定值而不改变其他通道?、c – 解释Valgrind的trace-malloc输出等更多相关知识的信息可以在本站进行查询。
本文标签: