std :: อินพุต cin พร้อมช่องว่าง?


144
#include <string>

std::string input;
std::cin >> input;

ผู้ใช้ต้องการป้อน "Hello World" แต่cinล้มเหลวที่ช่องว่างระหว่างสองคำ ฉันจะcinลงมือทำทั้งหมดได้Hello Worldอย่างไร

จริง ๆ แล้วฉันกำลังทำสิ่งนี้กับ structs และcin.getlineดูเหมือนจะไม่ทำงาน นี่คือรหัสของฉัน:

struct cd
{
    std::string CDTitle[50];
    std::string Artist[50];
    int number_of_songs[50];
};

std::cin.getline(library.number_of_songs[libNumber], 250);

นี่ทำให้เกิดข้อผิดพลาด ความคิดใด ๆ


27
คุณไม่ควรแก้ไขคำถามเพื่อถามคำถามใหม่เช่นนั้น เหตุผลก็คือผู้คนได้ให้คำตอบสำหรับคำถามดั้งเดิมของคุณแล้วและตอนนี้คำตอบเหล่านั้นดูไม่เหมาะสม หากคำถามเดิมของคุณได้รับคำตอบแล้วให้เริ่มคำถามใหม่เพื่อหลีกเลี่ยงความสับสน
Pete

เห็นได้ชัดหลังจากการตรวจสอบเล็กน้อย แต่คุณช่วยกรุณาเพิ่มการประกาศสำหรับตัวแปรlibraryเพื่อให้เป็นที่ชัดเจนว่ามันเป็นของประเภทcd
Chandsie

ขออภัยที่นี่เสร็จสิ้นโดยเร็วฉันจะโพสต์ข้อความนี้ใหม่
เลมอน

1
หากคุณจะโพสต์ใหม่ด้วยวิธีการเปลี่ยนใหม่โปรดตั้งค่าสถานะคำถามเพื่อลบโดย mod
Lightness Races ในวงโคจร

2
ในการปรับปรุงของคุณคุณกำลังพยายามที่จะเป็นgetline intแน่นอนว่าล้มเหลว
Ben Voigt

คำตอบ:


102

คุณต้องใช้cin.getline():

char input[100];
cin.getline(input,sizeof(input));

7
@ Kevin Meh มันเกิดขึ้น C ++ นั้นไม่ง่ายเท่าที่เราต้องการ
Pete

62
Ew; ทำไมต้องใช้char-buffers มันคือ 2011.
การแข่งขัน Lightness ใน Orbit

3
และทำไมไม่ใช้cin.getline(input, sizeof(input));? นอกจากนี้คุณไม่ควรตรวจสอบสถานะการส่งคืนหรือไม่
Jonathan Leffler

2
@JonathanLeffler ในขณะที่เขียนนี่เป็นคำตอบที่ฉันมีสำหรับคำถามที่ถูกถามตั้งแต่แรก (ดูความคิดเห็นแรกสำหรับคำถามที่เกิดขึ้นจริงและคุณจะเห็นว่าบริบทมีการเปลี่ยนแปลงเนื่องจากการแก้ไขโดย OP) ไม่ว่าจะด้วยวิธีใดถ้าคุณรู้สึกว่าคำตอบนั้นแย่มากโหวตให้เลย ฉันรับทราบว่านี่อาจไม่ใช่โซลูชันที่ "ดีที่สุด" แต่เป็นวิธีแก้ปัญหาไม่น้อย แทนที่จะถามว่าทำไมฉันไม่ใช้อะไรคุณสามารถบอกเราได้ว่าทำไมเราถึงทำแบบนี้
Pete

7
คำตอบของคุณไม่น่ากลัวและไม่จำเป็นต้อง downvoting ฉันคิดว่าการเปลี่ยนแปลงเล็กน้อยสองอย่างจะปรับปรุงให้ดีขึ้น การเปลี่ยนแปลง 1 จะใช้sizeof(input)แทน 100 ในการเรียกไปที่cin.getline(); นั่นหมายความว่าคุณสามารถเปลี่ยนขนาดของอินพุตบัฟเฟอร์และต้องการเปลี่ยนหนึ่งบรรทัดแทนสองบรรทัดเท่านั้น เปลี่ยน 2 จะทดสอบผลตอบแทนจากการcin.getline()ใช้ตัวอย่างเช่นif (!cin.getline(input, sizeof(input))) { ...handle EOF or error... }หรือสิ่งที่คล้ายกันเพื่อเตือน OP ว่าการดำเนินงานอินพุตโดยเฉพาะอย่างยิ่งมีความเสี่ยงต่อพฤติกรรมที่ไม่คาดคิด คำตอบอื่น ๆ ก็ต้องการสิ่งนี้เช่นกัน
Jonathan Leffler

215

มันไม่ "ล้มเหลว"; มันแค่หยุดอ่าน มันเห็นโทเค็นของคำศัพท์เป็น "สตริง"

ใช้ std::getline :

int main()
{
   std::string name, title;

   std::cout << "Enter your name: ";
   std::getline(std::cin, name);

   std::cout << "Enter your favourite movie: ";
   std::getline(std::cin, title);

   std::cout << name << "'s favourite movie is " << title;
}

โปรดทราบว่านี่ไม่ใช่สิ่งเดียวกันstd::istream::getlineซึ่งทำงานกับcharบัฟเฟอร์C-style มากกว่าstd::strings

ปรับปรุง

คำถามที่แก้ไขของคุณมีความคล้ายคลึงกับต้นฉบับเล็กน้อย

คุณกำลังพยายามgetlineเข้าสู่intไม่ใช่บัฟเฟอร์หรือสตริงอักขระ การดำเนินงานการจัดรูปแบบของลำธารเท่านั้นทำงานร่วมกับและoperator<< operator>>ใช้อย่างใดอย่างหนึ่งของพวกเขา (และปรับแต่งตามลำดับสำหรับการป้อนคำหลายคำ) หรือใช้getlineและแปลงเป็นคำศัพท์intหลังความจริง


2
ฉันชอบคำตอบนี้ดีกว่าคำตอบที่ยอมรับเพราะฉันไม่จำเป็นต้องระบุความยาวตัวอักษร
TheWanderer

1
@ TheWanderer แน่นอนว่าเป็นประโยชน์อย่างมาก
Lightness Races ในวงโคจร

อย่าลืมใส่ sstream: #include <sstream>
GilbertS

@LightnessRacesinOrbit คุณช่วยได้ไหม สิ่งนี้ทำให้ฉันมี newline พิเศษโดยไม่มีเหตุผลในขณะที่พิมพ์ผลลัพธ์ของฉัน
Anshuman Kumar

@ AnshumanKumar ฉันคิดว่าgetlineอาจรวมถึงการยกเลิกบรรทัดใหม่ในสตริงที่ส่งคืน ถ้าเป็นเช่นนั้นมันขึ้นอยู่กับคุณที่จะลบ
Mark Ransom

31

ไลบรารีมาตรฐานมีฟังก์ชันอินพุตที่เรียกwsใช้ซึ่งใช้ช่องว่างจากอินพุตสตรีม คุณสามารถใช้สิ่งนี้:

std::string s;
std::getline(std::cin >> std::ws, s);

4
ฉันคิดว่านี่เป็นคำตอบที่ดีที่สุด ฉันสามารถรวมกับ std :: cin >> ข้างบน
Andra

1
คำตอบที่ดีที่สุด เมื่อใช้std::getline(std::cin, s)ฉันจะได้รับยุ่งมากและฉันจะพูดว่าอินพุตขัดจังหวะเมื่อรออินพุตใน a while/ forloop ตัวเลือกนี้แก้ไขปัญหาของฉัน!
omerowitz

รวม sstream: #include <sstream>
GilbertS

24

ใช้:

getline(cin, input);

ฟังก์ชั่นสามารถพบได้ใน

#include <string>

2
+1 นี่เป็นคำตอบเดียวที่ใช้งานได้จริงสำหรับฉัน คำตอบที่เหลือบอกว่าใช้ cin.getline () แต่นั่นทำให้ฉันเกิดข้อผิดพลาดว่าฟังก์ชั่นนั้นไม่มีอยู่จริง
blembo

7
@blembo: จริงเหรอ? เนื่องจากคำตอบของฉันโพสต์มากกว่าหนึ่งปีก่อนหน้านี้พูดสิ่งเดียวกันทุกประการ (ตรงข้ามกับสิ่งที่คุณอ้างว่าตอบ)
การแข่งขัน Lightness ใน Orbit

@blembo: และหากcin.getlineไม่มีอยู่ในระบบของคุณคุณได้ทำอะไรผิดพลาดไปมาก เป็นไปได้มากว่าคุณกำลังผ่านข้อโต้แย้งที่ไม่ถูกต้อง ที่ดีที่สุดที่จะไม่ตำหนิคนอื่นสำหรับความผิดพลาดของคุณ ...
Lightness Races ใน Orbit

13

คุณต้องการใช้ฟังก์ชัน. getline ใน cin

#include <iostream>
using namespace std;

int main () {
  char name[256], title[256];

  cout << "Enter your name: ";
  cin.getline (name,256);

  cout << "Enter your favourite movie: ";
  cin.getline (title,256);

  cout << name << "'s favourite movie is " << title;

  return 0;
}

เอาตัวอย่างจากที่นี่ ลองดูข้อมูลเพิ่มเติมและตัวอย่าง


12
ที่จริงแล้วคุณไม่ค่อยต้องการใช้สมาชิกgetline- มันล้าสมัยแล้ว ใช้ฟรีแทนซึ่งสามารถนำมาใช้กับgetline std::string[BTW, cplusplus.com ไม่ใช่ทรัพยากรที่แนะนำ]
Lightness Races ใน Orbit

1
@Tomalak ทำไมถึงไม่แนะนำให้ cplusplus.com ฉันใช้มันตลอดเวลา: P
เลมอน

6
@KevinDuke: บทเรียนอาจทำให้เข้าใจผิดและไม่ถูกต้องและการอ้างอิงมีข้อผิดพลาดมากมาย เหล่านี้เป็นทรัพยากรที่ดี
Lightness Races ในวงโคจร

1
@NickSweeting: ใช่; ใช้สิ่งนี้แทน
Lightness Races ที่ Orbit

1
สำหรับลิงก์เอกสาร cppreference.com เป็นสิ่งทดแทนที่มีประสิทธิภาพสำหรับ cplusplus.com (ทั้งคู่เป็นการถอดความแบบไม่เป็นทางการ)
Ben Voigt

4

วิธีการ C

คุณสามารถใช้getsฟังก์ชั่นที่พบใน cstdio (stdio.h ใน c):

#include<cstdio>
int main(){

char name[256];
gets(name); // for input
puts(name);// for printing 
}

วิธี C ++

gets ถูกลบใน c ++ 11

[แนะนำ]: คุณสามารถใช้getline (cin, ชื่อ)ซึ่งอยู่ในstring.h หรือcin.getline (ชื่อ 256)ซึ่งอยู่ในiostreamตัวเอง

#include<iostream>
#include<string>
using namespace std;
int main(){

char name1[256];
string name2;
cin.getline(name1,256); // for input
getline(cin,name2); // for input
cout<<name1<<"\n"<<name2;// for printing
}

10
คำแนะนำที่แย่มากgetsเป็นไปไม่ได้ที่จะใช้อย่างปลอดภัย มันถูกลบอย่างสมบูรณ์ใน C11
Mat

1

ฉันควรใช้วิธีการต่อไปนี้เพื่อรับอินพุต:

#include <iostream>
#include <string>

using namespace std;

int main(void) {
    string name;

    cout << "Hello, Input your name please: ";
    getline(cin, name);

    return 0;
}

จริงๆแล้วมันใช้งานง่ายสุด ๆ แทนที่จะกำหนดความยาวทั้งหมดของอาเรย์สำหรับสตริงที่มีอักขระเว้นวรรค

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.