Qt 寫檔,寫入 txt 文字檔

本篇要介紹如何使用 Qt 的 QTextStream 來寫入 txt 文字檔。

範例. 寫入 txt 文字檔

在 QFile 建構子帶入檔案路徑,一開始先使用 QFile.open() 開檔,之後用 QTextStream 寫文字資料到檔案,
最後記得要用 QFile.close() 關檔。

qt-txt-write.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// qmake -project "QT += widgets" && qmake && make
#include <QApplication>
#include <QDebug>
#include <QString>
#include <QFile>
#include <QTextStream>

void writeFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
qDebug() << "Cannot open file for writing:" << qPrintable(file.errorString());
return;
}

QTextStream out(&file);
out << QObject::tr("123") << "\n";
QString str("456");
out << str << "\n";

file.close();
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

writeFile("output.txt");

return 0;
}

範例. 使用開啟檔案對話框選擇 txt 文字檔來寫入儲存

qt-txt-write-filedialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// qmake -project "QT += widgets" && qmake && make
#include <QApplication>
#include <QDebug>
#include <QFileDialog>
#include <QString>
#include <QFile>
#include <QTextStream>

void writeFile()
{
QString fileName = QFileDialog::getSaveFileName(NULL, QObject::tr("Text file"),
qApp->applicationDirPath(), QObject::tr("Files (*.txt)"));

QFile file(fileName);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text))
{
qDebug() << "Cannot open file for writing:" << qPrintable(file.errorString());
return;
}

QTextStream out(&file);
out << QObject::tr("123") << "\n";
QString str("456");
out << str << "\n";

file.close();
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

writeFile();

return 0;
}

其它相關文章推薦
如果需要使用 QTextStream 從檔案讀取文字資料請參考這篇
安裝 Qt 在 Windows 7 (使用MSVC)
Qt產生的exe發布方式
Qt 新增多國語言.ts翻譯檔案
Qt5的中文亂碼問題如何解決

Qt 讀檔,讀取 txt 文字檔

本篇要介紹如何使用 Qt 的 QTextStream 來讀取 txt 文字檔,讀檔且每次迴圈將讀取的文字印出來。

範例. 讀取 txt 文字檔

在 QFile 建構子帶入檔案路徑,一開始先使用 QFile.open() 開檔,之後再用 QTextStream 讀取文字資料,
另外補充如果是要讀取二進制資料要使用 QDataStream,處理檔案資訊可以使用 QFileInfo,處理目錄則使用 QDir,
之後就使用 readLine 逐行讀取並且用 qDebug 印出來,
最後別忘了使用 QFile.close() 關檔,這樣就完成了簡單的文字檔讀取的功能囉!

qt-txt-read.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
// qmake -project "QT += widgets" && qmake && make
#include <QApplication>
#include <QDebug>
#include <QString>
#include <QFile>
#include <QTextStream>

void readFile(const QString &fileName)
{
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Cannot open file for reading:" << qPrintable(file.errorString());
return;
}

QTextStream in(&file);
while (!in.atEnd())
{
QString fileLine = in.readLine();
qDebug() << fileLine;
}
file.close();
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

readFile("text.txt");

return 0;
}

範例. 使用開啟檔案對話框選擇 txt 文字檔來讀取

這邊使用 QFileDialog 檔案對話框來方便選擇文字檔來讀取。

qt-txt-read-filedialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// qmake -project "QT += widgets" && qmake && make
#include <QApplication>
#include <QDebug>
#include <QFileDialog>
#include <QString>
#include <QFile>
#include <QTextStream>

void readFile()
{
QString fileName = QFileDialog::getOpenFileName(NULL, QObject::tr("Text file"),
qApp->applicationDirPath(), QObject::tr("Files (*.txt)"));
QFile file(fileName);
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Cannot open file for reading:" << qPrintable(file.errorString());
return;
}

QTextStream in(&file);
while (!in.atEnd())
{
QString fileLine = in.readLine();
qDebug() << fileLine;
}
file.close();
}

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

readFile();

return 0;
}

其它相關文章推薦
如果需要使用 QTextStream 寫入文字資料進檔案請參考這篇
安裝 Qt 在 Windows 7 (使用MSVC)
Qt產生的exe發布方式
Qt 新增多國語言.ts翻譯檔案
Qt5的中文亂碼問題如何解決

dumpbin 用法與範例

本篇紀錄了如何在 Windows 使用 dumpbin 來查看 static library 裡的 symbols,dumpbin 算是 Windows 開發的實用除錯技巧,學會這招讓開發與除錯更輕鬆快速。

dumpbin 可以查看 Windows static library (*.lib) 裡面的 symbols,
就像 linux 的 nm, objdump, readelf 的工具一樣。

範例. 使用 dumpbin 來 dump symbols

1
dumpbin /SYMBOLS

dumpbin -exports work for dll,

範例. 使用 dumpbin 後再配合 findstr 搜尋 foo 字串

1
dumpbin -exports xxx.dll | findstr foo

範例. 使用 dumpbin 後再使用 undname 解析 C++ 符號

1
2
dumpbin /all /exports mylib.lib > mylib.txt
undname mylib.txt

參考
How to See the Contents of Windows library (.lib)
https://stackoverflow.com/questions/305287/how-to-see-the-contents-of-windows-library-lib
[問題] dll export symbol的疑問
https://www.ptt.cc/bbs/C_and_CPP/M.1338393437.A.80B.html
关于dumpbin和undname的使用
https://blog.csdn.net/Adam040606/article/details/46504613
List functions in *.lib on Windows
https://stackoverflow.com/questions/31410284/list-functions-in-lib-on-windows

其它相關文章推薦
nm 用法與範例
objdump 用法與範例
readelf 用法與範例

C/C++ 判斷資料夾是否存在

本篇記錄一下 C/C++ 在 Windows / Linux / MacOS 各平台判斷資料夾是否存在的方法,
其中介紹順序以多平台適用的方法優先,其次是特定平台的方法。

判斷資料夾是否存在大約分為下列幾種方法,

  • stat() (Windows / Linux / MacOS / Unix-like)
  • boost::filesystem::exists() (Boost)
  • std::filesystem::exists() (C++17)
  • GetFileAttributesA() (Windows)

stat() (Windows / Linux / MacOS / Unix-like)

stat() 用於 Linux, UNIX 和 Windows 也適用

函式原型:int stat(const char *path, struct stat *buf);,使用範例如下:

1
2
3
4
5
6
7
8
9
10
11
#include <sys/types.h>
#include <sys/stat.h>

struct stat info;

if (stat(path, &info) != 0)
printf("cannot access %s\n", path);
else if (info.st_mode & S_IFDIR)
printf("%s is a directory\n", path);
else
printf("%s is no directory\n", path);

常見的資料夾判斷函式
以下範例我自己在 Windows / Linux 都可以成功判斷.

cpp-is-dir-exists.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-is-dir-exists.cpp -o a.out
#include <sys/stat.h>
#include <iostream>

using namespace std;

bool dirExists(const std::string &path) {
struct stat info;
if (stat(path.c_str(), &info) == 0 && info.st_mode & S_IFDIR) {
return true;
}
return false;
}

int main() {
cout << dirExists("foo") << endl;
return 0;
}

boost::filesystem::exists() (Boost)

TBD

std::filesystem::exists() (C++17)

or std::filesystem::is_directory() 待驗證

GetFileAttributesA() (Windows)

函式原型:DWORD GetFileAttributesA(const char* filename);,使用範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
#include <windows.h>

bool dirExists(const std::string& path) {
DWORD ftyp = GetFileAttributesA(path.c_str());
if (ftyp == INVALID_FILE_ATTRIBUTES)
return false; //something is wrong with your path!

if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
return true; // this is a directory!

return false; // this is not a directory!
}

參考
https://stackoverflow.com/questions/18100097/portable-way-to-check-if-directory-exists-windows-linux-c
https://blog.csdn.net/caroline_wendy/article/details/21734915
http://stackoverflow.com/questions/8233842/how-to-check-if-directory-exist-using-c-and-winapi
https://caojingyou.github.io/2017/02/15/C++%E4%B8%AD%E5%88%A4%E6%96%AD%E6%9F%90%E4%B8%80%E6%96%87%E4%BB%B6%E6%88%96%E7%9B%AE%E5%BD%95%E6%98%AF%E5%90%A6%E5%AD%98%E5%9C%A8/

  • stat
  • boost的filesystem类库的exists函数

std::filesystem::exists() (C++17) 相關參考
std::filesystem::exists - cppreference.com
https://en.cppreference.com/w/cpp/filesystem/exists
std::filesystem::is_directory - cppreference.com
https://en.cppreference.com/w/cpp/filesystem/is_directory

其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ 判斷檔案是否存在
std::filesystem::copy 複製檔案的用法與範例
std::filesystem::create_directory 建立資料夾的用法與範例
std::filesystem::exists 判斷檔案是否存在的用法與範例

C/C++ 判斷檔案是否存在

本篇記錄一下 C/C++ 在 Windows / Linux / MacOS 各平台判斷檔案是否存在的方法,
其中介紹順序以多平台適用的方法優先,其次是特定平台的方法。

判斷檔案是否存在大約分為下列幾種方法,

  • ifstream (C++)
  • FILE (C)
  • acess()
  • std::filesystem::exists() (C++17)
  • boost::filesystem::exists() (Boost)

基本上推薦用 stat 或 acess

假設現在目錄下有 dir 資料夾、text.txt 文字檔、a.out 二進制執行檔,來看看這些範例的結果吧!

fstream (C++)

這方法是用於來測試開啟是否為文字檔,因為如果有個檔案是二進制檔這邊會回傳失敗。

cpp-file-exists.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// g++ cpp-file-exists.cpp -o a.out
#include <iostream>
#include <fstream>

using namespace std;

bool fileExists(const std::string& path) {
bool ret = false;
fstream fin(path.c_str());
//fstream fin;
//fin.open(path.c_str());
if (fin.good()) {
ret = true;
}
/*if (fin) {
ret = true;
}*/
/*if (fin.is_open()) {
ret = true;
}*/
fin.close();
return ret;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

輸出結果:
結果不太符合我的預期,等我有空再試試吧!

1
2
3
4
0
0
0
1

FILE (C)

這個方式在開啟文字檔或開啟二進制檔都能正確的回傳狀態。

cpp-file-exists2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// g++ cpp-file-exists2.cpp -o a.out
#include <iostream>
#include <fstream>

using namespace std;

bool fileExists(const std::string& path) {
FILE *fp;
if (fp = fopen(path.c_str(), "r")) {
fclose(fp);
return true;
}
return false;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

輸出結果:

1
2
3
4
0
1
1
1

acess()

在linux下使用 access 要 #inclue <unistd.h>
access()應該比fopen()判斷檔案是否存在來的快很多
函式原型:int _access(const char *path, int mode);,使用範例如下:

cpp-file-exists3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// g++ cpp-file-exists3.cpp -o a.out
#include <iostream>
#if _WIN32
#include <io.h>
#define _access access
#else
#include <unistd.h>
#endif

using namespace std;

bool fileExists(const std::string& path) {
bool ret = false;
if((access(path.c_str(), F_OK)) != -1) {
ret = true;
}
return ret;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

1
2
3
4
#define	R_OK	4		/* Test for read permission.  */
#define W_OK 2 /* Test for write permission. */
#define X_OK 1 /* Test for execute permission. */
#define F_OK 0 /* Test for existence. */

輸出結果:

1
2
3
4
0
1
1
1

stat()

cpp-file-exists4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// g++ cpp-file-exists4.cpp -o a.out
#include <sys/stat.h>
#include <iostream>

using namespace std;

bool fileExists(const std::string& path) {
struct stat info;
if (stat(path.c_str(), &info) == 0) {
return true;
}
return false;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

輸出結果:

1
2
3
4
0
1
1
1

std::filesystem::exists() (C++17)

cpp-file-exists5.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// g++ cpp-file-exists5.cpp -o a.out -std=c++11 -lstdc++fs
#include <iostream>
#include <experimental/filesystem>
//#include <filesystem> // C++ 17

using namespace std;
namespace fs = std::experimental::filesystem;

bool fileExists(const std::string& path) {
fs::path myfile(path.c_str());
if (fs::exists(myfile)) {
return true;
}
return false;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

輸出結果:

1
2
3
4
0
1
1
1

boost::filesystem::exists() (Boost)

cpp-file-exists6.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// g++ cpp-file-exists6.cpp -o a.out -I /usr/include/boost -lboost_filesystem
#include <iostream>
#include <boost/filesystem.hpp>

using namespace std;
namespace fs = boost::filesystem;

bool fileExists(const std::string& path) {
fs::path myfile(path.c_str());
if (fs::exists(myfile)) {
return true;
}
return false;
}

int main() {
cout << fileExists("nothing") << endl;
cout << fileExists("dir") << endl;
cout << fileExists("a.out") << endl;
cout << fileExists("text.txt") << endl;
return 0;
}

輸出結果:
結果有問題,等我有空再試試吧!

1
Segmentation fault (core dumped)

參考
C++ 判断文件文件夹是否存在
https://blog.csdn.net/u014436243/article/details/77312739

其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ 判斷資料夾是否存在
std::filesystem::copy 複製檔案的用法與範例
std::filesystem::create_directory 建立資料夾的用法與範例
std::filesystem::exists 判斷檔案是否存在的用法與範例

Python 四則運算,加法、減法、乘法、除法用法與範例

本篇 ShengYu 介紹 Python 四則運算,包含加法、減法、乘法、除法用法與範例,

Python 加法 (Addition)

這邊介紹 Python 加法 +,變數相加用法與範例如下,

1
2
3
4
n1 = 1 + 2
n2 = n1 + 5
print(n1)
print(n2)

結果如下,

1
2
3
8

Python 減法 (Subtraction)

這邊介紹 Python 減法 -,變數相減用法與範例如下,

1
2
3
4
n1 = 3 - 2
n2 = 4 - n1
print(n1)
print(n2)

結果如下,

1
2
1
3

Python 乘法 (Multiplication)

這邊介紹 Python 乘法 *,變數相乘用法與範例如下,

1
2
3
4
n1 = 2 * 3
n2 = n1 * 2
print(n1)
print(n2)

結果如下,

1
2
6
12

Python 除法 (Division)

這邊介紹 Python 除法 /,變數相除用法與範例如下,

1
2
3
4
5
6
n1 = 12 / 3
n2 = n1 / 5
print(type(n1))
print(type(n2))
print(n1)
print(n2)

結果如下,

1
2
3
4
<class 'float'>
<class 'float'>
4.0
0.8

上例可以發現除法使用浮點數運算所以結果會有小數點,如果要取得除法後的整數部份的話(無小數點部份)要使用 //,這樣結果就會是整數,範例如下,

1
2
3
4
5
6
n1 = 12 // 3
n2 = n1 // 5
print(type(n1))
print(type(n2))
print(n1)
print(n2)

結果如下,

1
2
3
4
<class 'int'>
<class 'int'>
4
0

下一篇介紹如何使用 print 格式化輸出與排版

其它相關文章推薦
Python mod 取餘數的用法
Python 平方、次方用法與範例
Python 新手入門教學懶人包
Python 寫檔,寫入 txt 文字檔
Python 讀取 csv 檔案
Python 寫入 csv 檔案
Python 讀寫檔案
Python 產生 random 隨機不重複的數字 list
Python PyAutoGUI 使用教學
Python OpenCV resize 圖片縮放

Python 計算 list 串列長度

本篇 ShengYu 介紹 Python 計算 list 串列長度,Python 計算串列長度的用法與範例如下,

len() 計算字元串列的元素個數,

1
2
l = ['h','e','l','l','o','w','o','r','l','d']
print(len(l))

輸出結果如下,

1
10

len() 計算數字串列的元素個數,

1
2
l = [1,2,3,4,5,6,7,8,9]
print(len(l))

輸出結果如下,

1
9

其它相關文章推薦
如果你想學習 Python 相關技術,可以參考看看下面的文章,
Python list 串列用法與範例
Python 計算 str 字串長度
Python 計算 dict 字典長度
Python 計算 tuple 元組長度
Python 計算 set 集合長度
Python 新手入門教學懶人包
Python 讀檔,讀取 txt 文字檔
Python 字串分割 split
Python 取代字元或取代字串 replace
Python 產生 random 隨機不重複的數字 list
Python print 格式化輸出與排版
Python PIL 讀取圖片並顯示
Python OpenCV resize 圖片縮放

Shell Script for 迴圈

本篇記錄 Shell Script 的 for 迴圈用法,Shell Script 的 for 迴圈大致上分為兩種寫法,請看以下的兩種 for 迴圈寫法介紹。

Shell Script 的 for 迴圈第 1 種寫法

這邊介紹 Shell Script 的 for 迴圈第 1 種寫法,這邊先簡單示範 Shell Script 跑 5 次 for 迴圈的寫法,

shellscript-for.sh
1
2
3
4
5
#!/bin/bash

for (( i=1; i<=5; i=i+1 )); do
echo "i=${i}"
done

結果輸出如下,

1
2
3
4
5
i=1
i=2
i=3
i=4
i=5

Shell Script 的 for 迴圈裡的 i=i+1 也可以寫成 i++,像 for (( i=1; i<=5; i++ )); do 這樣。

Shell Script 也可以將 5 變成一個變數帶入 for 迴圈,

shellscript-for-2.sh
1
2
3
4
5
6
#!/bin/bash

NUM=5
for (( i=1; i<=${NUM}; i++ )); do
echo "i=${i}"
done

也可以將 5 變成一個字串變數帶入 for 迴圈,另外一提,do 習慣寫在下一行的話,那 for 迴圈那行最後就不用加上分號,像這樣寫,

shellscript-for-3.sh
1
2
3
4
5
6
7
#!/bin/bash

NUM="5"
for (( i=1; i<=${NUM}; i++ ))
do
echo "i=${i}"
done

這邊就綜合以上學習到的技巧示範一下 Shell Script 加總 sum 的範例,

shellscript-for-4.sh
1
2
3
4
5
6
7
8
9
#!/bin/bash

SUM=0
NUM=5
for (( i=1; i<=${NUM}; i++ )); do
SUM=$(( ${SUM} + ${i} ))
done

echo "SUM=${SUM}"

結果輸出如下,

1
SUM=15

Shell Script 在 "" 雙引號裡取變數也可以不使用大括號,例如下面這樣寫,

1
2
3
4
#!/bin/bash

SUM=0
echo "SUM=$SUM"

Shell Script 的 for 迴圈第 2 種寫法

這邊是另外一種 Shell Script 的 for 迴圈寫法,以下使用 seq 指令來產生數字來給 for 迴圈使用,這邊示範用 seq 指令來產生 1~5 的數字,

shellscript-for-5.sh
1
2
3
4
5
#!/bin/bash

for i in $(seq 1 5); do
echo "i=${i}"
done

這個寫法跟上面類似,取而代之的是使用 {1..5} 表示產生 1~5 的數字,bash 版本太舊的話可能不支援這個寫法,

shellscript-for-6.sh
1
2
3
4
5
#!/bin/bash

for i in {1..5}; do
echo "i=${i}"
done

這邊示範改成 apple banana tomato 多個字串,

shellscript-for-7.sh
1
2
3
4
5
#!/bin/bash

for i in apple banana tomato; do
echo "i=${i}"
done

結果輸出如下,

1
2
3
i=apple
i=banana
i=tomato

將 apple banana tomato 放在 LIST 變數裡帶入 for 迴圈的話可以這樣寫,

shellscript-for-8.sh
1
2
3
4
5
6
#!/bin/bash

LIST="apple banana tomato"
for i in ${LIST}; do
echo "i=${i}"
done

結果輸出同上。

下一篇介紹 while 迴圈

其它相關文章推薦
Shell Script 新手入門教學
Shell Script 四則運算,變數相加、相減、相乘、相除
Shell Script if 條件判斷
Shell Script while 迴圈
Shell Script 讀檔,讀取 txt 文字檔

Shell Script 變數相加、相減、相乘、相除

本篇 ShengYu 介紹 Shell Script 的四則運算,變數相加、變數相減、變數相乘、變數相除。

加法 Addition

這邊介紹加法,Shell Script 變數相加範例如下,

shellscript-var-add.sh
1
2
3
4
#!/bin/bash
count=1
count=$(($count+1))
echo "counter=$count"

結果輸出:

1
counter=2

減法 Subtraction

這邊介紹減法,Shell Script 變數相減範例如下,

shellscript-var-sub.sh
1
2
3
4
#!/bin/bash
n=3
n=$(($n-2))
echo "number=$n"

結果輸出:

1
number=1

乘法 Multiplication

這邊介紹乘法,Shell Script 變數相乘範例如下,

shellscript-var-mul-div.sh
1
2
3
4
#!/bin/bash
n=3
n2=$(($n*4))
echo "number=$n2"

結果輸出:

1
number=12

除法 Division

這邊介紹除法,Shell Script 變數相除範例如下,

shellscript-var-mul-div.sh
1
2
3
4
#!/bin/bash
n=4
n3=$(($n/2))
echo "number=$n3"

結果輸出:

1
number=2

下一篇介紹 if 條件判斷

其他參考
https://blog.longwin.com.tw/2010/07/bash-var-num-add-2010/

其它相關文章推薦
Shell Script 新手入門教學
Shell Script if 條件判斷
Shell Script for 迴圈
Shell Script while 迴圈
Shell Script 讀檔,讀取 txt 文字檔