// Below gives an example in C++ Builder
// "in.txt" is a text file with the same folder of ~.exe as follows:
// 5 6
// 0 0 0 0 0 0
// 0 1 1 1 1 0
// 0 1 1 1 1 0
// 0 1 1 1 1 0
// 0 0 0 0 0 0
#include <stdio.h>
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
using namespace std;
// Add this statement for using "cin/cout"
TForm1 *Form1;
//----------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
}
//----------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{ int m, n, i, j;
freopen("in.txt", "r", stdin);
// read data in "in.txt" as standard input 將in.txt當成stdin
freopen("out.txt", "w", stdout); // write into file "out.txt"
cin >> m >> n; // get the matrix size m*n from in.txt (stdin)
int ** maze;
maze = new int * [m];
for (int i=0; i<m; i++)
{ maze[i] = new int [n];
for (int j=0; j<n; j++)
cin >> maze[i][j]; // 自in.txt (stdin) 讀資料
}
fclose(stdin);
cin.clear(); // clear the possible errors from cin
String s; // write data onto Form1
for (int i=0; i<m; i++)
{ for (int j=0, s=""; j<n; j++)
s = s + IntToStr(maze[i][j]) + " ";
Form1->Memo1->Lines->Add(s);
}
// write data into file "out.txt"
cout << m << " " << n << endl;
for (i=0; i<m; i++)
{ for (j=0; j<n; j++)
cout << maze[i][j] <<" ";
cout << endl;
}
fclose(stdout);
}
// Refer to https://en.cppreference.com/w/cpp/io/c/freopen
// 將檔案內容(含兩整數m,n和 m*n 個整數)讀入程式中 (BCB):
#include "stdio.h"
//----------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//-----------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner)
{
}
//-------------------------------------------------------------
int maze [20][20];
void __fastcall TForm1::Button1Click(TObject *Sender)
{ FILE *fp; // Define fp as a pointer pointing to some file (with data type FILE) in HD
String out;
int m, n, i, j;
AnsiString infile; // Use builder's string (AnsiString) to ease the conversion (into const char *)
if (OpenDialog1->Execute())
{ infile = OpenDialog1->FileName;
fp = fopen(infile.c_str(), "r+");
//c_str函数的傳回值是 const char *, 即把AnsiString轉成const char *給fopen使用
fscanf(fp, "%d %d", &m, &n); // Read in two integers m & n
Memo1->Lines->Add("(m, n)="+IntToStr(m)+", "+IntToStr(n));
for (i=0; i<m; i++) // Reda in m*n 0/1/2's into maze[][]
for (j=0; j<n; j++)
fscanf(fp, "%d", &maze[i][j]);
fclose(fp);
for (i=0; i<m; i++) // Print out maze[][] in Memo1
{ out = "";
for (j=0; j<n; j++) out += " "+IntToStr(maze[i][j]);
Memo1->Lines->Add(out);
}
// Print out maze[][] in StringGrid1
StringGrid1->RowCount = m;
StringGrid1->ColCount = n;
for (i=0; i<m; i++)
for (j=0; j<n; j++)
StringGrid1->Cells[j][i] = maze[i][j];
}
}
--- An example for (m, n) = (4, 4) where (0, 0) is the entrance and (m, n) = (4, 4) is the exit -----------
4 4
0 1 1 0
0 0 1 1
1 0 0 1
1 1 1 0
--- An example for (m, n) = (7, 7) where (1, 1) is the entrance and (m-1, n-1) = (6, 6) is the exit ((1,0)-(1,1) and (6,6)-(6,7) are intentionally set as parts of the tour so that the final tour would be (1,0)-(1,1)- ... -(6,6)-(6,7)) -----------
7 7
2 2 2 2 2 2 2
0 0 0 0 1 1 2
2 0 1 0 0 0 2
2 0 1 1 1 0 2
2 0 0 1 1 0 2
2 1 0 0 0 0 0
2 2 2 2 2 2 2
//------------寫檔範例--------------
if (SaveDialog1->Execute()) //確認SaveDialog1讀取檔案成功
{ // 取SaveDialog1所開啟的檔案名稱, 將檔案名稱轉為char格式後用fopen開啟此檔案
AnsiString file_name = SaveDialog1->FileName;
FILE *fp = fopen(file_name.c_str(),"w"); // "w" 表示開以寫檔的方式開啟
//利用fprintf將g_matrix中的元素寫入fp, 當需要換行時使用putc將'\n'加入fp中
if (fp)
{ fprintf(fp, "%d %d", g_Heigh, g_Width);
putc('\n', fp);
for (int i=0 ; i<g_Heigh ; i++)
{ for (int j=0 ; j<g_Width ; j++)
{ fprintf(fp, "%d ", g_maze[i][j]);
}
putc('\n', fp);
}
fclose(fp); // 寫完檔後請關檔
}
}
使用 Builder 者,不必參閱下面資料!
-------------- 利用 stdio.h 的指令 --- 讀檔 --- 寫檔 ------------------
# include <stdio.h>
(or # include <iostream>)
// 欲使用檔案功能, 請 include stdio.h 或 iostream 擇一即可
using namespace System::Runtime::InteropServices;
// 呼叫 Marshal::StringToHGlobalAnsi 轉換 String ^ to char * 時用!
// 下面的 fopen 需要檔名以 char * 型態為參數
// 有關 字串轉換 ==> https://support.microsoft.com/zh-tw/kb/311259
String ^ a;
String ^ b;
int m, p;
char * fname;
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK) // 順利開啟檔案才繼續往下做
{ a = openFileDialog1->FileName;
char * str2 = (char*) (void*) Marshal::StringToHGlobalAnsi(a);
FILE *fp = fopen(str2,"r"); // 讀檔, 注意第二參數為 "r" (read)
if (fp)
{ fscanf(fp, "%d %d", &m, &p);
listBox1->Items->Add("m="+m+" p="+p);
listBox1->Items->Add(a);
fclose(fp); // 讀完檔後請關檔
}
// 下面程式碼將檔名 xxx.yyy 變更為 xxx-1.yyy 做為寫入檔案的檔名
int k = a->IndexOf(".");
b = a->Substring(0, k)+"-1"+a->Substring(k, a->Length-k);
str2 = (char*)(void*)Marshal::StringToHGlobalAnsi(b);
listBox1->Items->Add(b);
fp = fopen(str2,"w"); // 寫檔, 注意第二參數為 "w" (write)
if (fp)
{ fprintf(fp, "m=%d p=%d", m, p);
putc('\n', fp);
fclose(fp); // 寫完檔後務必關檔
}
fp = fopen(str2,"a"); // 自檔尾寫入, 注意第二參數為 "a" (append)
if (fp)
{ fprintf(fp, "append=> m=%d p=%d", m, p);
fclose(fp); // 寫完檔後務必關檔
}
}
------------------------ 與 Mouse in a Maze 有關 -----------------------
--------- Read in a maze from a file as above and Show it in dataGridView ------ using String ^ (VS C++) ---
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e)
{ // wchar_t chrow[256], cm[10], cp[10]; //String ^ S, ^ T, ^ U = "";
String ^ S;
int m, p, i, j, p1, p2, len;
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK) // 順利開啟檔案才繼續往下做
{ richTextBox1->LoadFile(openFileDialog1->FileName, RichTextBoxStreamType::PlainText);
S = richTextBox1->Lines[0];
p1 = S->IndexOf(" ");
m = int::Parse(S->Substring(0, p1));
p = int::Parse(S->Substring(p1+1, S->Length-p1-1));
maze = new int * [m];
for (i=0; i<m; i++)
{ maze[i] = new int [p];
}
for (i=1; i<=m; i++)
{ S = richTextBox1->Lines[i];
for (j=0; j<p; j++)
maze[i-1][j] = int::Parse(S->Substring(2*j, 1));
}
dataGridView1->RowCount = m; // Define the size of dataGridView1
dataGridView1->ColumnCount = p;
dataGridView1->ColumnHeadersVisible = false;
dataGridView1->RowHeadersVisible = false; // Remove the Row/ColumnHeader
for (i=0; i<m; i++)
{ // dataGridView1->Columns[i]->Width = 80;
// dataGridView1->Rows[i]->Height = 80;
for (j=0; j<p; j++)
{ if (maze[i][j] == 2)
// dataGridView1->Rows[i]->Cells[j]->Value = "●";
dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::Olive; // Beige; //IndianRed;
else
// dataGridView1->Rows[i]->Cells[j]->Value = maze[i][j];
if (maze[i][j] == 1)
dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::DarkKhaki; //LightGray else dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::Ivory; //象牙色;
}
}
for (i=0; i<m; i++)
{ delete maze[i];
}
delete maze;
}
}
-------------------------------------------------------------------------------------------
將檔案內容當串流(stream)讀讀入程式中 (VisualStudio C++):
using namespace System::IO;
using namespace System::Text;
// 呼叫StreamReader與StreamWriter用
if(openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK) // 順利開啟檔案才繼續往下做
{
// 讀檔
StreamReader^ file = gcnew StreamReader(openFileDialog1->FileName);
String^ one_line = file->ReadLine(); // 一次讀檔案中的一列
cli::array<String^>^ split = one_line->Split(' ');
// 以空白當作分隔符號抓取每兩個空白間的字串
/*
例如:
檔案中的第一列串流是 Data Structures and Algorithms
我們以空白字元當分隔符號去分隔第一列串流
就能分別擷取出Data, Structures, and, Algorithms這四個字串
*/
// 寫檔
StreamWriter^ output = gcnew StreamWriter(Directory::GetCurrentDirectory()+" - output.txt");
// 必須給系統知道寫檔的檔名與存放路徑
for(i=0; i< dataGridView1->RowCount; i++)
{
String^ forOutput = "";
for(j=0; j<dataGridView1->ColumnCount; j++)
{
forOutput += dataGridView1->Rows[i]->Cells[j]->Value;
}
output->WriteLine(forOutput); // 一次寫出一列,寫完後即換行
}
output->Close(); // 寫完檔後務必關檔
9 9
2 2 2 2 2 2 2 2 2
0 0 0 0 0 0 1 0 2
2 0 1 1 1 0 1 0 2
2 0 1 0 0 0 0 0 2
2 0 1 1 1 1 1 1 2
2 0 1 0 0 0 0 0 2
2 0 1 0 1 1 1 0 2
2 0 0 0 0 0 1 0 0
2 2 2 2 2 2 2 2 2
--------- Read in a maze from a file as above and Show it in dataGridView ------ using stdio.h ---
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e)
{ String ^ a;
int m, p, i, j;
char * fname;
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK)
{ // 順利開啟檔案才繼續往下做
richTextBox1->LoadFile(openFileDialog1->FileName, RichTextBoxStreamType::PlainText);
a = openFileDialog1->FileName;
char * str2 = (char*) (void*) Marshal::StringToHGlobalAnsi(a);
FILE *fp = fopen(str2,"r"); // 讀檔, 注意第二參數為 "r" (read)
if (fp)
{ fscanf(fp, "%d %d", &m, &p);
listBox1->Items->Add("m="+m+" p="+p);
listBox1->Items->Add("input file :"+a);
// Allocate memory dynamically for **maze
maze = new int * [m];
for (i=0; i<m; i++) maze[i] = new int [p];
dataGridView1->RowCount = m; // Define the size of dataGridView1
dataGridView1->ColumnCount = p;
// dataGridView1->AutoSizeColumnsMode = System::Windows::Forms::DataGridViewAutoSizeColumnsMode::ColumnHeader;
for (i=0; i<m; i++)
{ // dataGridView1->Columns[i]->Width = 32;
// dataGridView1->Rows[i]->Height = 32;
for (j=0; j<p; j++)
{ fscanf(fp, "%d", &maze[i][j]);
// dataGridView1->Rows[i]->Cells[j]->Value = maze[i][j];
}
}
fclose(fp); // close file
for (i=0; i<m; i++)
{ for (j=0; j<p; j++)
{ if (maze[i][j] == 2)
// dataGridView1->Rows[i]->Cells[j]->Value = "●";
dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::Brown;//海軍藍;
else
// dataGridView1->Rows[i]->Cells[j]->Value = maze[i][j];
if (maze[i][j] == 1)
dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::Navy;//海軍藍;
else dataGridView1->Rows[i]->Cells[j]->Style->BackColor = Color::Honeydew;//淺綠;
}
}
for (i=0; i<m; i++) // Release memory of **maze
{ delete maze[i];
}
delete maze;
}
}
}
================================ Visual Studio 2022 =================================
// 讀檔
private: System::Void button3_Click(System::Object^ sender, System::EventArgs^ e) {
if (openFileDialog1->ShowDialog() == System::Windows::Forms::DialogResult::OK) //順利開檔才要繼續做下去
{
StreamReader^ reader = gcnew StreamReader(openFileDialog1->FileName);
String^ firstLine = reader->ReadLine(); // 一次讀檔案中的一行
cli::array<String^>^ width_and_height = firstLine->Split(' ');
width = int::Parse(width_and_height[0]);
height = int::Parse(width_and_height[1]);
textBox1->Text = width_and_height[0];
textBox2->Text = width_and_height[1];
maze = new int* [height];
for (int i = 0; i < height; i++)
{
maze[i] = new int[width];
}
for (int i = 0; i < width; i++)
{
cli::array<String^>^ maze_content = reader->ReadLine()->Split(' ');
for (int j = 0; j < height; j++)
{
maze[i][j] = int::Parse(maze_content[j]);
}
}
dataGridView1->RowCount = height + 1; // 要多加 1,不然他會IndexOutOfRange,可能是dataGridView本身的設定問題
dataGridView1->ColumnCount = width;
dataGridView1->ColumnHeadersVisible = false; // 隱藏columns
dataGridView1->RowHeadersVisible = false; // 隱藏index
dataGridView1->AllowUserToAddRows = false; // 去掉最後一行空白行
//dataGridView1->AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill; // 調整欄位寬度,但不知為何這邊沒辦法用這行程式,所以手動去更改屬性的地方
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
dataGridView1->Rows[i]->Cells[j]->Value = maze[i][j];
}
}
draw_dataGridView();
}
}
// 存檔
private: System::Void button4_Click(System::Object^ sender, System::EventArgs^ e) {
// 讓系統知道存放路徑
try
{
StreamWriter^ writer = gcnew StreamWriter(Directory::GetCurrentDirectory() + "- output.txt");
// 第一行先填入width和height
String^ firstLine = width + " " + height;
writer->WriteLine(firstLine);
// 填入迷宮內容
for (int i = 0; i < dataGridView1->RowCount; i++)
{
String^ outputString = "";
for (int j = 0; j < dataGridView1->ColumnCount; j++)
{
outputString += dataGridView1->Rows[i]->Cells[j]->Value + " ";
}
writer->WriteLine(outputString);
}
// 寫完記得關檔
writer->Close();
MessageBox::Show("Save successfully !");
}
catch(Exception^ e)
{
MessageBox::Show("Save failed !");
}
}