# Editeur de texte en C

**URL:** <https://www.debian-fr.org/t/editeur-de-texte-en-c/8602>\
**Category:** Programmation\
**Created:** [Février 20, 2016, 4:10 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602 "2016-02-20T16:10:19Z")\
**Posts on this page:** 6\
**Page:** 2

<div class="post-metadata">

**Author:** ![mattotop](https://www.debian-fr.org/user_avatar/www.debian-fr.org/mattotop/32/3942_2.png) [@mattotop](https://www.debian-fr.org/u/mattotop)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/21 "2016-02-20T16:11:32Z")

</div>

en tous cas, le point C, c’est sensible. 😆

---

<div class="post-metadata">

**Author:** ![Doby](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Doby](https://www.debian-fr.org/u/Doby)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/22 "2016-02-20T16:11:32Z")

</div>

Voila le code source actuel :  
Ma principale question concerne la persistance de l’interface graphique lors du lancement du programme. En effet, j’ai essaye differentes methodes pour que l’interface reste affichee au lancement du programme mais rien a faire. Pour le moment la solution retenue (mais je la trouve pas elegante, c’est de simuler l’appui sur la touche Espace avec la fonction ungetch(’ '); et de comparer le code ASCII retourne par la fonction getch() dans un boucle while. Le temps que la valeur lue est 32 (ASCII de Espace), on fait appel a la fonction d’affichage. Sinon on poursuit le programme. Voila sinon comme precedemment les remarques sont les bienvenues (autres que pre/post incrementation, ca j’ai pas encore change Yoko :p).  
Amicalement  
Doby

Fichier editor.c

[code]#include \<stdio.h\>  
#include \<stdlib.h\>  
#include \<string.h\>  
#include \<ncurses.h\>  
#include “…/Include/editor.h”

int main(void){  
editor Editor;  
Editor.Position = 0;  
Editor.Length = 0;

//Init terminal  
initscr();  
curs\_set(0);  
noecho();  
keypad(stdscr,TRUE);  
nodelay(stdscr, TRUE);  
cbreak();

//Init buffer  
InitBuffer(&Editor);

//Init graphic (peu convenable)  
ungetch(’ ');  
while(getch() == 32){  
PrintBuffer(Editor);  
usleep(5000);  
}

//Main loop  
while(1){  
UseBuffer(&Editor);  
usleep(5000);  
}

//End of programm  
endwin();  
system(“clear”);  
exit (0);  
}

/\*

- All cells of the buffer contain the caracter ‘\0’  
\*/  
void InitBuffer(editor \* Editor){  
int index = 0;  
for(index = 0; index \< length; index++){  
Editor-\>buffer[index] = ‘\0’;  
}  
}

/\*

- Move cursor in the buffer + Insert & modify content of the buffer  
\*/  
void UseBuffer(editor \* Editor){  
int key = 0;  
FILE \* handle = NULL;

//Get ASCII code of the key  
key = getch();

//Priority for escape sequence  
if (key == ESCAPE)  
Quit();

//Others ASCII code  
switch(key)  
{  
case KEY\_F(5):  
handle = fopen(“untitled”,“w+”);  
fwrite(Editor-\>buffer, sizeof(char), Editor-\>Length, handle);  
fclose(handle);  
break;

```
case KEY_F(6):
  handle = fopen("untitled", "r+");
  Editor->Length = fread(Editor->buffer, sizeof(char), length, handle);
  Editor->Position = 0;
  break;
  
case KEY_UP:
  if(Editor->Position > width)
Editor->Position -= width;
  break;
  
case KEY_DOWN:
  if(Editor->Position < length - width - 1)
Editor->Position += width;
  break;
  
case KEY_LEFT:
  if(Editor->Position > 0)
  Editor->Position--;
  break;
  
case KEY_RIGHT:
  if(Editor->Position < length - 1)
  Editor->Position++;
  break;
  
case KEY_BACKSPACE:
  if(Editor->Position > 0){
MoveData(Editor, 0);
Editor->Position--;
Editor->Length--;
  } 
  
  if(Editor->Position == 0){
MoveData(Editor, 0);
Editor->buffer[0] = '\0';
Editor->Length--;
  }
  break;
  
case KEY_HOME:
  Editor->Position -= (Editor->Position % width);
  break;
  
case ENTER:
  if(Editor->Position < length - width - 1){
Editor->Position = (Editor->Position + width - (Editor->Position % width));
Editor->Length = (Editor->Length + width - (Editor->Length % width));
  }
  break;
  
default:
  if(key >= 32 && key <= 126){
MoveData(Editor, 1);
Editor->buffer[Editor->Position] = (char)key;
Editor->Length++;
if(Editor->Position < length - 1)
  Editor->Position++;
  }
  
  else{
return;
  }
  
  break;
}

```

//Print modifications  
PrintBuffer(\*Editor);  
}

/\*

- MoveData
- Move existing data in the buffer (lose last caracter in the buffer)  
\*/  
void MoveData(editor \* Editor, int way){  
int index = 0;

//Insert new data  
if(way == 1){  
for(index = length - 1; index \> Editor-\>Position; index–){  
Editor-\>buffer[index] = Editor-\>buffer[index - 1];  
}  
}

//Delete existing data (BACKSPACE)  
if(way == 0){  
for(index = Editor-\>Position - 1; index \< length - 1; index++){  
Editor-\>buffer[index] = Editor-\>buffer[index + 1];  
}  
Editor-\>buffer[length - 1] = ‘\0’;  
}  
}

/\*

- Print buffer  
\*/  
void PrintBuffer(editor Editor){  
int line = 0, column = 0, index = 0;  
PrintBorders();

//Print content of the buffer  
for(index = 0; index \<= Maximum(Editor.Length, Editor.Position); index++){  
line = (index / width);  
column = (index - line \* width);  
if(index == Editor.Position)  
mvprintw(line + 4,column + 1, “\_”);  
else  
mvprintw(line + 4, column + 1, “%c”, Editor.buffer[index]);  
}  
refresh();  
}

/\*

- Print Borders  
\*/  
void PrintBorders(void){  
WINDOW \* screen, \*menu, \*command;  
screen = newwin(length / width + 2, width + 2, 3, 0);  
menu = newwin(3, 82, 0, 0);  
command = newwin(3, 82, length / width + 5, 0);

//Print borders  
box(screen, ACS\_VLINE,ACS\_HLINE);  
wrefresh(screen);  
box(menu, ACS\_VLINE, ACS\_HLINE);  
box(command, ACS\_VLINE, ACS\_HLINE);

//Print menu  
mvwprintw(menu, 1, 2, “Quit = ESC”);  
mvwprintw(menu, 1, 14, “Save = F5”);  
mvwprintw(menu, 1, 25, “Load = F6”);  
wrefresh(menu);

//Print command  
mvwprintw(command, 1, 2, “Load/Save file named : untitled”);  
wrefresh(command);  
}

/\*

- Quit Editor  
\*/  
void Quit(void){  
endwin();  
system(“clear”);  
exit (0);  
}

/\*

- Maximum return maximum value between two values  
\*/  
int Maximum(int value1, int value2){  
if(value1 \>= value2)  
return value1;  
return value2;  
}  
[/code]

Fichier editor.h

```auto
/*
 * Simple text editor by Doby
 */

#ifndef EDITOR_H
#define EDITOR_H

/*
 * Define buffer size and line size (width)
 */
#define length 2400
#define width 80

/*
 * Define values of ASCII keys
 */
#define ENTER 10
#define ESCAPE 27

/*
 * Struture for the editor
 */
typedef struct _editor{
  char buffer[length];
  int Position;
  int Length;
} editor;

/*
 * InitBuffer(editor * Editor)
 * All cells of the buffer contain the caracter '\0'
 */
void InitBuffer(editor * Editor);

/*
 * UseBuffer(editor * Editor)
 * Move the cursor in the buffer + Insert & Modify content of the buffer
 */
void UseBuffer(editor * Editor);

/*
 * MoveData(editor * Editor, int way)
 * Move existing data in the buffer (lose last caracter in the buffer)
 */
void MoveData(editor * Editor, int way);

/*
 * PrintBuffer(editor Editor) print the content of the buffer
 * PrintBorders(WINDOW * screen) print the borders of the interface
 */
void PrintBuffer(editor Editor);
void PrintBorders(void);

/*
 * Quit Editor
 */
void Quit(void);

/*
 * Maximum(int value1, int value2) return maximum value between two values
 */
int Maximum(int value1, int value2);

#endif //EDITOR_H
```

---

<div class="post-metadata">

**Author:** ![ed](https://www.debian-fr.org/user_avatar/www.debian-fr.org/ed/32/5886_2.png) [@ed](https://www.debian-fr.org/u/ed)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/23 "2016-02-20T16:11:34Z")

</div>

```auto
/*
 * All cells of the buffer contain the caracter '\0' 
 */
void InitBuffer(editor * Editor){
  int index = 0;
  for(index = 0; index < length; index++){
    Editor->buffer[index] = '\0';
  }
}
```

Cette fonction, ça se remplace aisément par:

```auto
void InitBuffer(editor *E)
{
  (void) memset(E->buffer, length, 0);
}
```

```auto
  switch(key)
    {
    case KEY_F(5):
      handle = fopen("untitled","w+");
      fwrite(Editor->buffer, sizeof(char), Editor->Length, handle);
      fclose(handle);
      break;
```

Ça c’est un segfault. Il faut impérativement tester le retour de: fopen, et fwrite.

```auto
    case KEY_F(6):
      handle = fopen("untitled", "r+");
      Editor->Length = fread(Editor->buffer, sizeof(char), length, handle);
      Editor->Position = 0;
      break;
```

Idem.

```auto

/*
 * MoveData
 * Move existing data in the buffer (lose last caracter in the buffer)
 */
void MoveData(editor * Editor, int way){
  int index = 0;
  
  //Insert new data
  if(way == 1){
    for(index = length - 1; index > Editor->Position; index--){
      Editor->buffer[index] = Editor->buffer[index - 1]; 
    }
  }
```

J’avoue ne pas comprendre ce que tu veux faire la 🙂 Je pense pas que ça soit la meilleure façon de faire 🙂

```auto
  //Delete existing data (BACKSPACE)
  if(way == 0){
    for(index = Editor->Position - 1; index < length - 1; index++){
      Editor->buffer[index] = Editor->buffer[index + 1];
    }
    Editor->buffer[length - 1] = '\0';
  }
}
```

Idem, tu connais memove memcpy & co?

```auto
/*
 * Simple text editor by Doby
 */

#ifndef EDITOR_H
#define EDITOR_H

/*
 * Define buffer size and line size (width)
 */
#define length 2400
#define width 80

```

Par convention, on défini TOUJOURS les constante sous forme de chaines en majuscules…

```auto

/*
 * Define values of ASCII keys
 */
#define ENTER 10
#define ESCAPE 27

```

Moi j’aurais plutot faire genre KEY\_ENTER KEY\_ESCAPE…

Sinon, ça doit déja être défini par ncurses.h je pense…

```auto

/*
 * Struture for the editor
 */
typedef struct _editor{
  char buffer[length];
  int Position;
  int Length;
} editor;

```

Généralement, on fais plutot ceci:

```auto
typedef struct editor_st_s {
 ...
} editor_st_t;
```

De cette façon tu sais imédiatement ce qu’est un editor\_st\_t: type d’une struct editor 🙂 Mais bon la c’est les gouts et les couleurs…

Courage, a+

---

<div class="post-metadata">

**Author:** ![Doby](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/d/58f4c7/32.png) [@Doby](https://www.debian-fr.org/u/Doby)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/24 "2016-02-20T16:11:36Z")

</div>

@ed :  
Salut et merci pour tes remarques. Memove, memcopy ou memset nan je ne connaissais absolument pas et c’est vrai que ca serait nettement plus efficace (en fait dans la fonction MoveData, c’est juste un deplacement d’un indice donne position jusqu’a la fin du buffer dans un sens ou dans un autre suivant le parametre way pour inserer ou supprimer des donnees dans le buffer).  
Sinon ouais pour les test de fread et fwrite j’ai pas fait les verifications d’usage, la c’est entierement de ma faute 😛  
Pour les constantes ouais je sais toujours en Majuscules 🙂  
Et sinon KEY\_ENTER et KEY\_ESCAPE alors KEY\_ENTER deja defini mais ne correspond pas a la touche ENTER centrale (de memoire a verifier) et sinon je me rappelle plus si KEY\_ESCAPE est definie dans ncurses.  
Quant au coup de la structure c’est pas bete du tout bien que ca fait assez indigeste a premiere vue.  
Je vais regarder pour memcopy & co.

---

<div class="post-metadata">

**Author:** ![thialme](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/t/50afbb/32.png) [@thialme](https://www.debian-fr.org/u/thialme)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/25 "2016-02-20T16:11:40Z")

</div>

CR pour carriage return code hexa 0x0D  
LF pour line feed code hexa 0x0A

---

<div class="post-metadata">

**Author:** ![Pingoo\_Pat](https://www.debian-fr.org/letter_avatar_proxy/v4/letter/p/d2c977/32.png) [@Pingoo\_Pat](https://www.debian-fr.org/u/Pingoo_Pat)\
**Post date:** [Février 20, 2016, 4:11 UTC](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602/26 "2016-02-20T16:11:42Z")

</div>

> [@](#):
>
> Mais euh les mecs, réviser un peu. C c’est haut niveau. ya pas de “embarqué” ou pas.

Après vérification, il a raison le bougre ;o

[Page précédente](https://www.debian-fr.org/t/editeur-de-texte-en-c/8602.md?page=1)
