pdCURSES and addstr compatibility with strings pro

2019-08-19 03:27发布

问题:

Hey so i'm trying to get addstr() in pdCurses to work (windows curses) with the preferred string class so I made the function the following string_to_80char() function, which is supposed to take a string and return an 80 character long char array (the number of characters fit on one line in the console) since this is the only parameter addstr seems to accept...

However when running the following code i do get the "Just a string" printed but with a random character like an '@' or '4' like 50 spaces after it.....

WHATS THE PROBLEM?? Thanks for the help! =)

#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 string& 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:

Your string_to_80char() is returning a pointer to a local variable and the lifetime of that variable is over when the function returns so the pointer is pointing to garbage. Also, you're not putting a '\0' character at the end of your returned string (but that's besides the point that what you're returning doesn't officially exist anyway).

Have the caller provide the buffer to put the 80 char string into (untested example):

char* string_to_80char (const string& aString, char* buf, size_t bufSize)
{
    int stringSize = aString.size();
    enum {
        max_buf_size = 81;  /* 80 plus the '\0' 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;
};

Alternatively, allocate the returned buffer on the heap and return that (in which case the caller must free the buffer when they're done with it).

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

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

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

If you're on Windows and don't have strdup(), here you go:

#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 result;
}


回答2:

One problem is that you are returning a pointer to a variable stored on the stack in string_to_80char(). This variable is stored on the stack:

char charArray[90];

When you return from that function, the storage used by this variable is no longer valid, and its likely to be reused. It's likely that addstr()'s stack variables are overwriting this same storage so your string is being corrupted.

A simple fix is to make charArray static so it's not allocated on the stack:

static char charArray[90];


回答3:

addstr(mesg[0].c_str())

should be all you need. PDCurses is a C library, so it takes C strings. They don't have to be 80 columns or anything else special.

Alternatively, make a simple C++ wrapper function:

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