简体   繁体   English

C-打印出奇怪的字符

[英]C - Weird characters are printed out

I have written a small program that is going to become a text editor in the console for windows. 我写了一个小程序,它将成为Windows控制台中的文本编辑器。 This is what I have written right now: 这是我现在写的:

#include <Windows.h>
#include <conio.h>
#include <stdlib.h>

int main()
{
    int space = 20;
    int used = 0;
    int key = 0;
    char* text = malloc(sizeof(char) * space);

    while (key != 27)
    {
        if (used >= space)
        {
            space += 20;
            text = realloc(text, space);
        }

        key = getch();
        if (key == 8)
        {
            used--;
            system("cls");
            for (int i = 0; i < used; i++)
            {
                putch(text[i]);
            }
        }
        else
        {
            used++;

            text[used] = key;
            putch(text[used]);
        }
    }

    free(text);
    return 0;
}

The printing when I press on letters at the keyboard works fine. 当我在键盘上按字母时,打印效果很好。 The problem is when I hit backspace and try to remove a character. 问题是当我按下退格键并尝试删除字符时。 It starts printing random 'I' characters in the text I have written. 它开始在我编写的文本中打印随机的“ I”字符。 What mistake am I making and how can I solve it? 我犯了什么错误,我该如何解决?

Off by one error. 关闭一个错误。 Change 更改

used++;
text[used] = key;

to

text[used] = key;
...
used++;

Some style notes: 一些样式说明:

First, use character literals instead of raw numeric codes; 首先,使用字符文字而不是原始数字代码; for example, instead of writing 例如,代替写作

if (key == 8)

use 采用

if (key == '\b')

Where there isn't a predefined character literal (such as for the escape character) create a symbolic constant and use that: 如果没有预定义的字符文字(例如转义字符),请创建符号常量,然后使用该常量:

#define ESC 27
...
while (key != ESC)

This will make your code a bit easier to understand for others. 这将使您的代码更容易为他人所理解。

Secondly, be careful with realloc ; 其次,请小心realloc if it can't satisfy the request, it will return NULL. 如果不能满足要求,它将返回NULL。 If you assign that NULL value to your text pointer, you will lose your only reference to the memory you had already allocated. 如果将NULL值分配给text指针,则将丢失对已分配内存的唯一引用。 It's better to do something like the following: 最好执行以下操作:

char *tmp = realloc( text, space + 20 );
if ( tmp )
{
  text = tmp;
  space += 20;
}

This way, if the realloc fails, you still have your reference to the previously allocated memory, allowing you to free it cleanly, or to recover from the error somehow. 这样一来,如果realloc失败,你仍然有参考以前分配的内存,让您free干净,或从错误中设法挽回。

text[0] is never assigned. 永远不会分配text[0] First time text[used] is written the used is already 1 , because it is getting incremented before. 第一次写入text[used]used已为1 ,因为它之前已经递增。 But on backspace you are printing text starting from 0 , which is uninitialized and containing garbage. 但是在backspace您正在打印从0开始的text ,该text未初始化并且包含垃圾。

I'm not sure that this is the only problem, but one problem I can see in first look - the increase of 'used' is before the inserting (means - you start inserting to text[1]) and the reprintig starts from zero (means - you start printing with text[0]) the first value is fertilized. 我不确定这是否是唯一的问题,但是我可以从乍看之下看到一个问题-“ used”的增加是在插入之前(意味着-您开始插入到text [1]),并且reprintig从零开始(意味着-您以text [0]开始打印)第一个值受精。

Sorry for the bad english and hope It's help. 对不起,英语不好,希望对您有所帮助。

the following code still has the 'off-by-one' error, 以下代码仍然存在“一一关闭”错误,

the following code needs the error checking added for the calls to malloc() and realloc(). 以下代码需要为对malloc()和realloc()的调用添加错误检查。

however, it is portable, compiles cleanly, and performs the desired functionality without outputting trash characters. 但是,它是便携式的,可以干净地编译并执行所需的功能,而无需输出垃圾字符。

However, it still has the logic problem with newlines. 但是,换行符仍然存在逻辑问题。

//#include <Windows.h>
//#include <conio.h>
#include <stdio.h>
#include <stdlib.h>

int main( void )
{
    int space = 20;
    int used = 0;
    int key = 0;
    char* text = malloc(sizeof(char) * space);

    while (key != 27) // escape
    {
        if (used >= space)
        {
            space += 20;
            text = realloc(text, space);
        }

        key = getchar();
        if (key == 8) // backspace
        {
            used--;
            system("cls");
            for (int i = 0; i < used; i++)
            {
                putc(text[i], stdout);
            }
        }
        else
        { // all other key strokes
            used++;

            text[used] = key;
            putc(text[used], stdout);
        }
    } // end while

    free(text);
    return 0;
} // end function: main

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM