簡體   English   中英

C ++指針問題

[英]C++ pointer issues

我正在嘗試創建一個簡單的(模塊化)c ++程序,該程序讀取用戶輸入並將其吐出。

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void _printOut(char * output)
{
    cout << output << endl;
}
char * readUserInput()
{
    char userInput[256];
    cin >> userInput;
    return userInput;
}

int _tmain(int argc, _TCHAR* argv[])
{
    _printOut("Enter your name: ");
    char * userName = readUserInput();
    _printOut("Hello");
    _printOut(userName);
    system("pause");
    return 0;
}

輸入您的姓名:aaaa您好╠╠╠╠╠╠╠╠按任意鍵繼續。

如果我在readUserInput函數中打印出userInput變量,它將打印出輸入的內容。 但是,嘗試在_tmain函數中將userInput變量存儲作為userName打印出來,會導致打印出一系列無法​​理解的字符。 即。 ╠╠╠╠╠╠╠╠。 據我的最佳猜測,這可能是由於指針問題引起的,但據我所知,我正確地引用了所有內容。

調試此代碼:在此行:_printOut(“ Hello”); 在此行的方法中:_tmain [userName =“ abcdefg”]:_printOut(userName); 在方法_tmain [userName =“†UX”]中

所以我想知道當用戶名的值在兩行之間未分配或操縱時如何變化。

char * readUserInput()
{
    char userInput[256];
    cin >> userInput;
    return userInput;
}

char userInput[256]; 數組僅在函數調用期間存在。 一旦您觸及了該函數的底部,它便不再存在,並且您將返回一個指向垃圾存儲區的指針。 這稱為本地范圍

而且無論如何,如果有人的名字真的很長(超過255字符)。

考慮使用std::string ,它將解決兩個問題。

std::string readUserInput()
{
    std::string inp;
    std::cin >> inp;
    return inp;
}

void printOut (const std::string& toPrint)
{
    std::cout << toPrint << '\n';
}

(而且,這也不太重要,在這種情況下不允許使用_printOut這個名稱,因為它以_開頭。 請參見此處 ,盡管如果您是初學者,它可能會影響您的頭腦。)

編輯更好的方法是使用std::getline一次將整行讀入std::string 但是,由於它們對待空格的方式,特別是'\\n'換行符, getline(...)cin>>...不能很好地配合使用。 通常最好在整個程序中選擇一個並堅持使用。 這是readUserInput()外觀:

std::string readUserInput()
{
    std::string line;
    std::getline(std::cin, line);

    return line;
}

這樣,如果用戶輸入包含空格的名稱(例如"BoB T. Fish" ),您將讀取整個名稱,而不僅僅是"BoB" (然后剩下的內容在您下次閱讀時會引起您的困惑)。

cin>>...getline混合使用可能會很困難,原因是cin>>...會讀到盡可能多的空白,然后將其余部分拋在后面。 因此,除了Mayb散布某人的姓氏之外,如果他們輸入的名字中沒有空格,它只會在輸入流中保留最后一個換行符。 然后,當您進行getline ,不會獲得用戶輸入的下一行。 您會得到留在后面的空行。 如果您再次使用cin>> ,則換行符將被忽略。 例如,考慮以下用戶輸入:

Hello\n
World\n

如果您首先使用cin>>讀取,則會在程序中看到"Hello" ,並留下

\n
World\n

如果然后使用getline進行第二次讀取,則會在程序中獲得"" ,並留下

World\n

char userInput[256]; 在readUserInput退出時將被銷毀,因此您返回的指針無效。

使用std::string代替。

或動態分配變量,或將自動變量作為參數傳遞。

一旦超出范圍,userInput變量將被銷毀。

局部變量存儲在堆棧中。 函數執行完成后,變量將被銷毀。

您需要使用動態分配的char指針(存儲在堆上)或std :: string

您的問題是一個范圍界定問題:

char userInput[256]; 定義一個局部變量,該局部變量僅在其自己的范圍內有效(在{}括號之間)。

本質上,您將返回一個有效的指針,該指針在您離開該函數后將變為無效,因為它已被釋放。

您違反了一個基本規則:永遠不要返回指向局部(非靜態)變量的指針。

要解決此問題,請將您的userInput靜態,或返回一個新字符串(使用new每次調用都創建一個新字符串),或使用可復制對象而不是指針(例如std::string )。

您正在使用指向緩沖區(在堆棧中)的指針,該緩沖區已超出范圍。

嘗試這個:

#include <iostream>
#include <fstream>
#include <string>

using namespace std;

void _printOut(char * output)
{
    cout << output << endl;
}
char * readUserInput()
{
    //Allocate in Heap, instead of stack
    char* userInput = new char[256];
    cin >> userInput;
    return userInput;
}

int main(int argc, char* argv[])
{
    _printOut("Enter your name: ");
    char * userName = readUserInput();
    _printOut("Hello");
    _printOut(userName);
    system("pause");
    return 0;
}

更好的方法是使用std :: string

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM