討論區快速選單
知識庫快速選單
討論區最近新進100則主題 程式設計俱樂部Facebook粉絲團
[ 回上頁 ] [ 討論區發言規則 ]
求大神指引方向-console 編輯程式
更改我的閱讀文章字型大小
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/11 下午 06:14:01
主要此editor 包含了 函數 結構 指標 陣列 buffer

整體是一個80*255的陣列,是可以對此陣列作1.編輯2.輸出3.插入4.複製5.回存6.刪除 等指令

目前小弟的進度是

設定一個結構
#define MAX 255
 
typedef struct data{
int len; //陣列長度
char content[MAX]; //內容
struct data *next; //指向結構的指標
}data;

typedef struct list{
data *head;
data *end;
int lineNum;
}list;

小弟構想是一開始 while 迴圈 給我們輸入 command (6個指令) 進到每個CASE 後再呼叫各自的函數,進行處理,但還有動態記憶體配置以及buffer 的運用,及函式的結構指標處理...請大神們指點迷津!!!!

作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/11 下午 10:00:38
>主要此editor 包含了 函數 結構 指標 陣列 buffer
>
>整體是一個80*255的陣列,是可以對此陣列作1.編輯2.輸出3.插入4.複製5.回存6.刪除 等指令

當然不只這樣, 除非你的 editor 只能處理最多 80 行的文字檔案.

80*255 應該只是螢幕上看到的範圍, 真正資料的儲存跟這個沒有關係. 如果你要寫的是視窗系統的 console 程式, 你可以用視窗系統的 console API 來幫你. 比方說用 CreateConsoleScreenBuffer() 來創建一個足夠大的 buffer 用來儲存螢幕上看得到的資料.

  https://msdn.microsoft.com/en-us/library/windows/desktop/ms685107(v=vs.85).aspx

  https://msdn.microsoft.com/en-us/library/windows/desktop/ms682010(v=vs.85).aspx


>目前小弟的進度是
>
>設定一個結構
>#define MAX 255
>
>typedef struct data{
>int len; //陣列長度
>char content[MAX]; //內容
>struct data *next; //指向結構的指標
>}data;
>
>typedef struct list{
>data *head;
>data *end;
>int lineNum;
>}list;
>
>小弟構想是一開始 while 迴圈 給我們輸入 command (6個指令) 進到每個CASE 後再呼叫各自的函數,進行處理,但還有動態記憶體配置以及buffer 的運用,及函式的結構指標處理...請大神們指點迷津!!!!

建議你先把最底層的資料結構的部份弄出來: 包括 node (也就是每一行) 的添增/刪減, 每一行內字元的添增/刪減, 資料結構到檔案的儲存與讀取, 等最基本的功能. 每一個功能對應一個函式.

所謂的指令, 就是呼叫上述資料結構的處理函式. 這個你已經知道了. 輸入的讀取可以用 ReadConsoleInput():
  https://msdn.microsoft.com/en-us/library/windows/desktop/ms685035(v=vs.85).aspx

  https://msdn.microsoft.com/en-us/library/windows/desktop/ms684961(v=vs.85).aspx


接下來的就是運用 console API 把資料結構裡的東西顯示到螢幕上.


作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/12 上午 06:22:56
there is an example for you study . http://www.codeproject.com/Articles/237508/How-To-Build-A-Simple-Text-Editor-A-Tutorial
get them and follow those guidelines on the page . you may study and then modify them to achieve your goal. have fun :-)
 

作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/12 上午 08:41:05
http://towo.net/mined/
there is a gpl freeware. you may get them and try to to understand how to construct a text editor in console mode .

have fun :)
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/12 上午 11:44:43
more deep knowledge about text editor - emacs , http://www.finseth.com/craft/
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/12 下午 01:36:03
https://www.cs.cmu.edu/~wjh/papers/byte.html
a technical paper about a editor design data structure
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/12 下午 06:02:21
http://www.fltk.org/doc-1.3/editor.html

there is a full source codes for a very simple text editor , but it uses fltk GUI framework . you may refer them and try to remove those framework dependency codes and then add those codes can work in console mode.
 

作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/13 上午 04:20:20
http://www.drdobbs.com/architecture-and-design/text-editors-algorithms-and-architecture/184408975

or ddj tells you how to design a text editor
have fun ;)
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/15 下午 05:55:56
各位前輩,學長好...以下是學弟我這幾天熬出的CODE,但卻無法正常執行,非常懊惱阿!請教我可以在改進的方向,如何正確執行...

typedef struct node{
char content[MAX_CHAR];
struct node *next;
}node;

typedef struct list{
node *HEAD;
node *TAIL;
int lineNum;
}List;
int main()
{
int i = 0, len = 0;
int atLine = 0;
char fileName[MAX_ROW] = {'\0'};
char stringBuffer[MAX_CHAR] = {'\0'};
char bufferCopy[MAX_CHAR] = {'\0'};
char cmd = {'\0'};
char blockString[MAX_CHAR] = {'\0'};

list fileBuffer;
fileBuffer.HEAD = NULL;
fileBuffer.TAIL = NULL;
fileBuffer.lineNum = 0;
list copyBuffer;
copyBuffer.HEAD = NULL;
copyBuffer.TAIL = NULL;
copyBuffer.lineNum = 0;
list blockBuffer;
blockBuffer.HEAD = NULL;
blockBuffer.TAIL = NULL;
blockBuffer.lineNum = 0;

printf("Enter following Command:\nWrite -W\nPrint -P\nDelete -D\nSave -S\nInsert -I\nCopy -C\nQuit -Q\n");

while(1)
{
printf("Command:");
scanf("%c", cmd);

switch(cmd)
{
case 'W':
printf("String: ");
scanf("%s", stringBuffer);
read(©Buffer, stringBuffer);
add(&fileBuffer, fileBuffer.lineNum, stringBuffer);
break;
case 'D':
printf("Atline: ");
scanf("%d", &atLine);
Delete(&fileBuffer, atLine);
break;
case 'S':
save(&fileBuffer,fileName);
freeList(©Buffer);
freeList(&blockBuffer);
break;
case 'I':
if(atLine == 0)
{
blockInLast(&fileBuffer, &blockBuffer, atLine);
}
else
{
blockInsert(&fileBuffer, &blockBuffer, atLine);
}
break;
case 'P':
print(&fileBuffer, fileName, atLine);
break;
case 'C':
printf("String: ");
scanf("%s", stringBuffer);
replace(&fileBuffer, atLine, stringBuffer);
break;
case 'Q':
save(&fileBuffer,fileName);
exit (0);
break;
default:
break;
}
len = strlen(stringBuffer);
for(i = 0; i < len; i++)
{
stringBuffer[i] = '\0';
}
}
}
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/15 下午 05:59:47
函式如下>"< (一)

void read(list *fileBuffer, char *stringBuffer)
{
node *newNode;
newNode = (node *) malloc (sizeof(node));
strcpy(newNode->content, stringBuffer);
newNode->next = NULL;

if(fileBuffer->HEAD == NULL)
{
fileBuffer->HEAD = newNode;
fileBuffer->TAIL = newNode;
}
else
{
fileBuffer->TAIL->next = newNode;
fileBuffer->TAIL = fileBuffer->TAIL->next;
}
}

void freeList(list *List)
{
node *tmpNode;
node *i;
for(i = List->HEAD; i != NULL; i = i->next)
{
tmpNode = List->HEAD->next;
free(List->HEAD);
List->HEAD = tmpNode;
}
List->HEAD = NULL;
List->TAIL = NULL;
List->lineNum = 0;
}

void print(list *fileBuffer, char *fileName, int atLine)
{
node *i;
int count;
count = 0;
if( atLine != 0)
{
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
if(atLine == fileBuffer->lineNum)
{
printf("%s", fileName[atLine]);
}
}
}
else
{
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
if(count < 9)
{
count++;
printf("0%i %s", count, i->content);
}
else
{
count++;
printf("%i %s", count, i->content);
}
}
}
}

void add(list *fileBuffer, int atLine, char *string)
{
node *i;
int counter;
counter = 1;

node *newNode;
newNode = (node *) malloc (sizeof(node));
strcpy(newNode->content, string);
    newNode->next = NULL;
if(atLine == 0 && fileBuffer->HEAD == NULL && fileBuffer->TAIL == NULL)
{
newNode->next = fileBuffer->HEAD;
fileBuffer->HEAD = newNode;
fileBuffer->TAIL = newNode;
}
else if(atLine == 0)
{
newNode->next = fileBuffer->HEAD;
fileBuffer->HEAD = newNode;
}
else
{
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
if(counter == atLine)
{

newNode->next = i->next;
i->next = newNode;
}
counter++;
}
if(atLine == fileBuffer->lineNum)
{
fileBuffer->TAIL = newNode;
}
}
fileBuffer->lineNum = fileBuffer->lineNum + 1;
}

作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/15 下午 06:01:17
函式(二)
void Delete(list *fileBuffer, int atLine)
{
node *i;
node *prevNode;
node *followNode;
int counter;
counter = 1;
if(atLine == 0)
{
freeList(fileBuffer);
}
else
{
if(atLine == 1)
{
free(fileBuffer->HEAD);
fileBuffer->HEAD = fileBuffer->HEAD->next;
}
else if(atLine == fileBuffer->lineNum)
{
for(i = fileBuffer->HEAD; i!= NULL; i = i->next)
{
if(counter == fileBuffer->lineNum - 1)
{
free(i->next);
i->next = NULL;
fileBuffer->TAIL = i;
}
counter++;
}
}
else
{
prevNode = fileBuffer->HEAD;
for(i = fileBuffer->HEAD->next; i != NULL; i = i->next)
{
followNode = i->next;
if(counter == atLine-1)
{
free(prevNode->next);
prevNode->next = followNode;
}
counter++;
prevNode = i;
}
}
fileBuffer->lineNum--;
}
}

void replace(list *fileBuffer, int atLine, char *string)
{
node *i;
int counter;
counter = 1;
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
if(counter == atLine)
{
strcpy(i->content, string);
}
counter++;
}
}

void blockInLast(list *fileBuffer, list *blockBuffer, int atLine)
{
if(fileBuffer->HEAD == NULL && fileBuffer->TAIL == NULL)
{
fileBuffer->HEAD = blockBuffer->HEAD;
fileBuffer->TAIL = blockBuffer->TAIL;
}
else
{
fileBuffer->TAIL->next = blockBuffer->HEAD;
fileBuffer->TAIL = blockBuffer->TAIL;
}
}

void blockInsert(list *fileBuffer, list *blockBuffer, int atLine)
{
node *i;
int counter;
counter = 1;
if(atLine == 0)
{
if(fileBuffer->HEAD != NULL && fileBuffer->TAIL != NULL)
{
blockBuffer->TAIL->next = fileBuffer->HEAD;
fileBuffer->HEAD = blockBuffer->HEAD;
}
else
{
blockInLast(fileBuffer, blockBuffer, atLine);
}
}
else
{
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
if(counter == atLine)
{
blockBuffer->TAIL->next = i->next;
i->next = blockBuffer->HEAD;
}
counter++;
}
}
}
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/16 上午 07:08:00
would you please describe your problems ?
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/16 上午 09:49:40
Dear Ozzy

sorry about that, my issue is that "Unhandled exception at 0x55cb6ad1 (msvcr90d.dll) in editor_new.exe: 0xC0000005: Access violation writing location 0x00000000."

My major is atmosphere sciences, but i like coding, so i can not solve some problem...
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/16 下午 06:04:22
this is memory access violation. it should be pointers access memory cause the fault.
a little suggestion for you reference .
you should test your program via stand alone function and put it all together.
they should be :
1. console commands test : W(edit) , P(output) , C(copy) , I(insert), R(restore)
2. how to edit a text on screen --> clear screen and edit a text on screen , then write them all into a file.
use clrscr() ---> clear screen , scanf() ----> input a character one by one , fopen ----> open a text file , putc() ---> write a character to a text file , fclose() ---> close a file.
3. If you have been write file successfully , it could be read from it one by one and print them on screen . you may use getc( )
its goal is checking those typing data have been written successfully. you can also compare them with written data .
via while loop till all characters have been read completely , e.g.
while (1) {
  int ch ;
  ch = getc(fp); // read a character from the text file
  if ( ch != -1)
  {
    // check they are correct
  }
  else
   break ; // EOF and exit loop
} // end of while

4. output function should work normally if step 3 is correct. if it did , you may fill those codes into the control block.
of ciourse, this action also can be ignored.

5. About insert function , you may design a well-manipulated data structure.
@: linked list type : each line has 255 characters length and total number of lines is 80. For each line , its data structure should like
     typedef struct LineContent {

     char line[255] ; // number of characters of each line
     struct LineContent* up ; // link to upper line
     struct LineContent* down ; // link to next line
     int no ; // the number of line
     } ;
    typedef struct LineContent* Linenode ;
  
  



 
 

作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/16 下午 06:41:50
you may construct the text content via linked structure.
it should look like as following.
null<--{255 chars , 1}<-->{255 chars , 2}<-->{255 chars , 3}<--> ... <-->{255 chars , 80}-->null
then you may insert strings or characters to it. But you must consider an algorithms that can handle the structure after insert/delete characters.
about restore function , you may keep the before data to a backup.
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/16 下午 09:18:24
這裡有錯誤:
  scanf("%c", cmd);
應該是
  scanf(" %c", &cmd);

%c 前面要加個空格, scanf() 才會跳過空格字元. scanf() 第二個以後的所有參數應該是位址. 如果輸入不只一個字元, 你必須把多餘的輸入清除. 最簡單的方法就是寫一個小函式:
    void clearInput(void)
    {
     int c;
     while ((c = getchar()) != '\n' && c != EOF);
    }

然後在 scanf(" %c", &cmd) 後呼叫.


case 'W' 裡的 scanf 用 "%s" 只會讀 word, 要讀一整行, 要用特殊格式 " %255[^\n]s" 或用 fgets().

如果用 fgets() 必須處理之前 scanf() 遺留下來的 newline (任何讀 line 都必須處理 scanf() 留下來的 '\n' 字元.

程式邏輯有點怪. 像 case 'W', read() 跟 add() 似乎有重複. 其它的邏輯就先不看了.


你的程式不完整, 而且有打錯的地方. 比方說:
 - MAX_ROW, MAX_CHAR 沒定義.
 - 沒有 #include 標準頭檔.
 - 函式在呼叫前編譯器必須要先看到它的定義或宣告.
 - 程式裡面有好幾個 ©Buffer 應該是你在 copy/paste 時發生的問題.
 - save() 沒有定義.

作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/17 下午 12:42:55
http://techapple.net/2013/01/turbocc-for-windows-7-windows-8-windows-xp-32bit64bit-fullscreen-single-installer/

there is a famous dos c IDE for you reference.
you may try to download and install it. Debugging your program via 'D'ebug ( Red Upper character )
:-)
作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/17 下午 04:01:40
Raymond 大大您好

您所敘述的問題,非常有幫助,但目前在執行copy paste 時出現的問題 我想請教一下

以下是我的函式

void copy(list *fileBuffer, list *copyBuffer, int atLine)
{
node *i;
int counter;
counter = 0;
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
counter++;
if(counter == atLine)
{
copyBuffer->HEAD = i;
copyBuffer->HEAD->next = NULL;
}
}
}

void replace(list *fileBuffer, list *copyBuffer, int atLine)
{
node *i;
node *followNode;
int counter;
counter = 0;
for(i = fileBuffer->HEAD; i != NULL; i = i->next)
{
counter++;
if(counter == atLine)
{
followNode = i->next;
followNode->next = i->next->next;
i = copyBuffer->HEAD;
i->next = followNode;
}
}
}

想請教一下當我執行copy時,copyBuffer->HEAD->next = NULL; 這個動作會導致 i->next; 的位置也發生改變,明明我是改了 copyBuffer->HEAD->next 但為何 i->next 會改變呢,求前輩指導~感恩
作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為最佳解答 2015/6/17 下午 09:58:00
>想請教一下當我執行copy時,copyBuffer->HEAD->next = NULL; 這個動作會導致 i->next; 的位置也發生改變,明明我是改了 copyBuffer->HEAD->next 但為何 i->next 會改變呢,求前輩指導~感恩

>void copy(list *fileBuffer, list *copyBuffer, int atLine)
>{
> node *i;
> int counter;
> counter = 0;
> for(i = fileBuffer->HEAD; i != NULL; i = i->next)
> {
> counter++;
> if(counter == atLine)
> {
> copyBuffer->HEAD = i;
> copyBuffer->HEAD->next = NULL;
> }
> }
>}

要知道 linked-list 怎麼運作, 最好的方法就是用紙筆把它畫出來.

以下是你 copy() 函式裡 fileBuffer 跟 i 的關係, 沒錯吧!

file
Buffer    node    node
+-----+  +----+  +----+
|HEAD*+->| *--+->| *--+->
+-----+  +----+  +----+
          ︿       ︿
          |i.....>|i

在 if (counter == atLine) 裡, copyBuffer->HEAD = i, 也就是說 copyBuffer 的 HEAD 指向 i 所指向的 node:

    node    node
   +----+  +----+
-->|*---+->|*---+->
   +----+  +----+
    ︿  ︿
   i|  |copyBuffer->HEAD

copyBuffer->HEAD 所指向的 next 當然就是 i 所指向的 next!

作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/22 下午 06:51:42
前輩們好

這兩天遇到一個小問題,拜託求解

當我 scanf("%d", &atLine); 的動作之後

想要我輸入字元 'B' 的時候做跳出的動作break; (在迴圈內)

可我嘗試好久 都沒有找出方法 請大家指教~ 感謝
作者 : ozzy123(ozzy) 資訊類作業求救卓越專家C++卓越專家貼文超過4000則人氣指數超過30000點
[ 貼文 4465 | 人氣 37262 | 評價 10860 | 評價/貼文 2.43 | 送出評價 49 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為很有道理 2015/6/22 下午 08:39:59
for (....)
{
 if (ch =='B' ) goto exit ;

 ...
} // end of for

exit: // label

作者 : sflam(Raymond)討論區板主 Visual C++ .NET卓越專家VC++一代宗師新手入門優秀好手資訊類作業求救頂尖高手C++一代宗師貼文超過4000則
[ 貼文 4945 | 人氣 9172 | 評價 32290 | 評價/貼文 6.53 | 送出評價 142 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
主題發起人edgarye註記此篇回應為最佳解答 2015/6/22 下午 10:15:29
>這兩天遇到一個小問題,拜託求解

完美的輸入檢測邏輯不算小問題. 看看就明白了.


>當我 scanf("%d", &atLine); 的動作之後

記住以下幾點:
 - 所有從螢幕上的輸入都是字元或字元組.

 - 所以所有輸入函式的最大功能不是從 input stream 讀取輸入, 而是把字元或字元組轉換成程式員想要的類型.

 - 如果輸入的字元或字元組無法轉換成所需的類型, 輸入函式會傳回錯誤, 資料會繼續保留在輸入端 [註1].

 - 任何輸入函式都有回傳機制, 告訴程式員資料是否成功轉換讀取. 所有程式都應該要做這個檢查, 並做出適當的應對 [註2].

[註1]: 錯誤資料保留在輸入端的原因是給程式員一個檢測該資料或重新讀取的機會.

[註2]: 自己去看 scanf() 的說明, 特別是「回傳」的部份.


>想要我輸入字元 'B' 的時候做跳出的動作break; (在迴圈內)

你認為 'B' 能夠轉換成 int ("%d") 類型嗎? 如果不行, 你認為會發生什麼事呢!? 根據上面的要點, 結果就是:
 - scanf() 傳回錯誤訊息, 告訴你剛剛的輸入跟 "%d" 不符.
 - 無法轉換的資料繼續放在輸入端.

你要的 'break' 是在檢查 scanf() 回傳資料後.
你必須把錯誤的資料從輸入端清除 (用之前貼出的函式) [註3].

[註3]: 有些同學或網站會告訴你用 fflush(stdin) 來清除輸入端的資料. 這是 _錯_誤_的_. fflush() 只對輸出端有定義, 用在輸入端會導致不可預期的結果.


[其它讀取輸入的方法]
另一個方法是所有的輸入都用字元, 字元陣列, 或字串格式來讀 (幾乎不做任何轉換), 然後自己在程式裡檢查這些讀入的文字資料, 並用其它的函式轉換成程式需要的類型.

以字元或字元組的方式來讀並不表示就不需要做錯誤檢查, 因為其它錯誤還是有可能會發生 (如 end of file, 或資料長度超出陣列大小, 等等).

現在知道為什麼它不是小問題了嗎?

作者 : edgarye(edgarye)
[ 貼文 15 | 人氣 0 | 評價 0 | 評價/貼文 0 | 送出評價 18 次 ] 
[ 給個讚 ]  [ 給個讚 ]  [ 回應本文 ]  [ 發表新文 ]  [ 回上頁 ] [ 回討論區列表 ] [ 回知識入口 ]
2015/6/23 下午 01:28:08
謝謝您 Raymond 前輩

你的建議都讓我受用無窮!

我使用的方法是您提的皆用字元,字串陣列處理,問題得到了解決。

 板主 : Daniel
 > 資訊類作業 - 討論區
 - 最近熱門問答精華集
 - 全部歷史問答精華集
 - 資訊類作業 - 知識庫
  ■ 全站最新Post列表
  ■ 我的文章收藏
  ■ 我最愛的作者
  ■ 全站文章收藏排行榜
  ■ 全站最愛作者排行榜
  ■  月熱門主題
  ■  季熱門主題
  ■  熱門主題Top 20
  ■  本區Post排行榜
  ■  本區評價排行榜
  ■  全站專家名人榜
  ■  全站Post排行榜
  ■  全站評價排行榜
  ■  全站人氣排行榜
 請輸入關鍵字 
  開始搜尋
 
Top 10
評價排行
資訊類作業
1 Raymond 4540 
2 Ben 2880 
3 青衫 2260 
4 ozzy 1540 
5 HKLN.net 1010 
6 Daniel 780 
7 joe 740 
8 小朱 570 
9 Benson 440 
10 鬼翼@娃娃魚 400 
資訊類作業
  專家等級 評價  
  一代宗師 10000  
  曠世奇才 5000  
  頂尖高手 3000  
  卓越專家 1500  
  優秀好手 750  
Microsoft Internet Explorer 6.0. Screen 1024x768 pixel. High Color (16 bit).
2000-2018 程式設計俱樂部 http://www.programmer-club.com.tw/
0.109375