Проблемы с совместимостью PDCurses и addstr со строками

#arrays #string #char #curses #pdcurses

#массивы #строка #символ #проклятия #pdcurses

Вопрос:

Привет, итак, я пытаюсь заставить addstr() в PDCurses работать (windows curses) с предпочтительным классом string, поэтому я создал функцию следующей string_to_80char(), которая должна принимать строку и возвращать массив символов длиной 80 символов (количество символов, умещающихся в одной строке в консоли), поскольку это единственный параметр, который, похоже, принимает addstr…

Однако при запуске следующего кода я получаю «Просто строку», напечатанную, но со случайным символом, таким как «@» или «4», например, через 50 пробелов после нее…..

В ЧЕМ ПРОБЛЕМА?? Спасибо за помощь! =)

 #include <curses.h>         /* ncurses.h includes stdio.h */  
#include <string> 
#include <vector>
#include <Windows.h>
#include <iostream>
using namespace std;

char* string_to_80char (const stringamp; aString)
{
    int stringSize = aString.size();
    char charArray[90];

    if(stringSize <= 80)
    {
    for(int I = 0; I< stringSize; I  )
        charArray[I] = aString[I];
    for(int I = stringSize; I < sizeof(charArray); I  )
        charArray [I] = ' ';
    return charArray;
    }

    else
    {
    char error[] = {"STRING TOO LONG"};
    return error;
    }
};


int main()
{
    //   A bunch of Curses API set up:
    WINDOW *wnd;

 wnd = initscr(); // curses call to initialize window and curses mode
 cbreak(); // curses call to set no waiting for Enter key
 noecho(); // curses call to set no echoing

 std::string mesg[]= {"Just a string"};     /* message to be appeared on the screen */
 int row,col;               /* to store the number of rows and *
                     * the number of colums of the screen */
 getmaxyx(stdscr,row,col);      /* get the number of rows and columns */
 clear(); // curses call to clear screen, send cursor to position (0,0)

 string test = string_to_80char(mesg[0]);
 char* test2 = string_to_80char(mesg[0]);
 int test3 = test.size();
 int test4 = test.length();
 int test5 = sizeof(test2);
 int test6 = sizeof(test);

 addstr(string_to_80char(mesg[0]));
 refresh();
 getch();


 cout << endl << "Try resizing your window(if possible) and then run this program again";
  system("PAUSE");
 refresh();
  system("PAUSE");

 endwin();
 return 0;
}
  

Ответ №1:

Вы string_to_80char() возвращаете указатель на локальную переменную, и время жизни этой переменной заканчивается, когда функция возвращается, поэтому указатель указывает на мусор. Кроме того, вы не помещаете '' символ в конец возвращаемой строки (но это помимо того, что то, что вы возвращаете, все равно официально не существует).

Попросите вызывающего пользователя предоставить буфер для размещения строки 80 char (непроверенный пример):

 char* string_to_80char (const stringamp; aString, char* buf, size_t bufSize)
{
    int stringSize = aString.size();
    enum {
        max_buf_size = 81;  /* 80 plus the '' terminator */
    };

    bufSize = (bufSize < max_buf_size) ? bufSize : max_buf_size; 

    if (stringSize 1 < bufSize) {
        return NULL;  /* or however you want to handle the error */
    }

    /* we know the buffer is large enough, so strcpy() is safe */
    strcpy( buf, aString.c_str());

    return buf;
};
  

В качестве альтернативы, выделите возвращаемый буфер в куче и верните его (в этом случае вызывающий должен освободить буфер, когда они закончат с ним).

 char* string_to_80char (const stringamp; aString)
{
    int stringSize = aString.size();

    if(stringSize <= 80)
    {
        return strdup(aString.c_str());
    }

    return strdup("STRING TOO LONG");
};
  

Если вы используете Windows и у вас нет strdup() , вот и все:

 #include <stdlib.h>
#include <string.h>
#include <assert.h>

/* 
 * public domain strdup()
 */

char* strdup( char const* s)
{
   size_t siz = 0;
   char* result = NULL;
   assert( s);

   siz = strlen( s)   1;
   result = (char*) malloc( siz);

   if (result) {
       memcpy( result, s, siz);
   }

   return resu<
}
  

Ответ №2:

Одна из проблем заключается в том, что вы возвращаете указатель на переменную, хранящуюся в стеке в string_to_80char(). Эта переменная хранится в стеке:

 char charArray[90];
  

Когда вы возвращаетесь из этой функции, хранилище, используемое этой переменной, больше недействительно, и его, вероятно, будут использовать повторно. Вероятно, переменные стека addstr () перезаписывают это же хранилище, поэтому ваша строка повреждена.

Простое исправление — сделать charArray статичным, чтобы он не выделялся в стеке:

 static char charArray[90];
  

Ответ №3:

 addstr(mesg[0].c_str())
  

должно быть все, что вам нужно. PDCurses — это библиотека C, поэтому она принимает строки C. Они не обязательно должны содержать 80 столбцов или что-то еще особенное.

В качестве альтернативы, создайте простую функцию-оболочку C :

 int my_addstr(const string amp;aString)
{
    return addstr(aString.c_str());
}