2016-02-26 194 views
1

我是新手,无论是编码还是英文。这是我的代码:如何在C++中读取未知大小的字符串

#include<iostream> 
#include<cstdio> 

using namespace std; 

int main() 
{ 
    int n=1; 
    char *a = new char[n],c=getchar(); 
    while((c!=EOF)||(c!='\n')) 
    { 
     a[n-1]=c; 
     c=getchar(); 
     n++; 
    } 
    cout << a; 
    delete[] a; 
    return 0; 
} 

我正在学习动态内存分配。问题是输入一个长度未知的字符串。我的想法是读取字符串字,并在到达EOF或\ n时停止。你能指出这个错误吗? 另一个问题:我被告知新选择了指定大小的内存块。那么如果没有足够大的块,会发生什么? 感谢您的帮助!

+5

在C++中,使用String类此。 – Donnie

+2

C++中的自然方法是使用'std :: string'和'getline'或'>>'来读入字符串。否则,你需要保持重新分配和复制到一个更大的数组。 – crashmstr

+2

您是否特别试图不使用标准库工具'std :: string'和'getline'? –

回答

3
#include <iostream> 
#include <string> 

int main() { 
    std::string line; 
    // first argument is the stream from whence the line comes. 
    // will read to newline or EOF 
    std::getline(std::cin, line); 
} 
+1

OP不能使用字符串(这是一个任务)并且必须在动态内存分配中练习,所以......恐怕你的答案(尽管很好)并不是真的有用。 –

+0

@Bob__ OP在提问时未指定。 – erip

2

首先,有没有必要使用char*new char[n]。您可以使用std::string

那么你要问自己:

  1. 字符串可以包含空格字符?
  2. 字符串可以跨越多行吗?
  3. 如果它可以跨越多行,它跨越多少行?

如果回答的第一个问题是“否”,则可以使用:

std::string s; 
cin >> s; 

如果回答的第一个问题是“是”,并回答了第二个问题是“否“,那么你可以使用:

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

如果第二个问题的答案是”是“,答案会变得更加复杂。

然后,您需要找到更多问题的答案?

  1. 行数是硬编码的吗?
  2. 如果它没有硬编码,程序如何从用户那里获得该号码?

根据这些问题的答案,您的代码会有所不同。

3

[我知道坚持的最佳实践和方法可以是“好” 的事情,但OP应该知道为什么当前的代码不工作 和这里其他的答案似乎并不被回答]

首先,您应该使用C++字符串类为此。

第二,如果你想知道为什么你当前的代码无法正常工作,是因为:

我。里面的情况是错误的。它说:“如果字符不是\n或者它不是文件结尾,请执行此块”。所以,即使按下回车键(c为'\n'),该块仍然会执行,因为“c不是EOF”,反之亦然。

ii。你只需要为你的char*分配一个字节的内存,这显然是不够的。

这应该还算复制你想要什么,但分配的内存是静态的字符串必须被限制,

int main() 
{ 
    int n=1; 
    char *a = new char[100],c=getchar(); 
    while(true) 
    { 
     if(c == '\n' || c == EOF){ 
      break; 
     } 
     a[n-1]=c; 
     c=getchar(); 
     n++; 
    } 
    cout << a; 
    delete[] a; 
    return 0; 
} 
1

考虑你的任务的限制(没有std::string,没有std::vector,动态内存分配) ,我会尝试给你一个修改过的但是你的代码的工作版本。

我的想法是读取字符串字我的话,并停止时,它到达EOF或 \ n。你能指出这个错误吗?

由于molbdnilo指出(c!=EOF) || (c!='\n')总是如此,所以你的循环将永远不会结束。

由于mah注意到,您的缓冲区只有1个字符长度,并且您不检查溢出,此外,您忘记在其末尾添加空白定界符。

你的第二个问题是关于当new不能分配足够的内存时会发生什么。那么,它会抛出一个你的程序应该处理的异常,但最好的事情(不是唯一的一个,也许是最简单的)你可以做的就是终止你的程序。

这是考虑到上述限制如何完成你的任务的例子:

#include <iostream> 

using namespace std; 

const int INITIAL_SIZE = 8; 

int main() { 
    // the following block of code could rise an exception 
    try 
    { 
     int n = 0; 
     char c; 

     // allocate some memory to store the null terminated array of chars 
     char *a = new char[INITIAL_SIZE]; 
     // what happens if new fails? It throws an exception of type std::bad_alloc 
     // so you better catch it 
     int allocated = INITIAL_SIZE; 

     // read a charachter from stdin. If EOF exit loop 
     while(cin.get(c)) 
     { 
      // If it's a newline or a carriage return stop 
      if('\n' == c || '\r' == c) 
       //^ note that ^^^ putting the literals first helps avoiding common 
       // error like using "=" instead of "==" in conditions 
       break; 

      a[n] = c; 

      // if the array is full it's time to reallocate it 
      if (n == allocated) 
      { 
       // There are alternatives, of course, but I don't know which library 
       // you are allowed to use, so I assume no one and BTW your compiler 
       // could be smart enough to recognize the pattern and optimize it 

       // allocate a bigger array 
       allocated *= 2; 
       char *b = new char[allocated]; 

       // copy the old one in the new one 
       for (int i = 0; i <= n; ++i) 
       { 
        b[i] = a[i]; 
       } 

       // release the memory handled by the old one... 
       delete[] a; 

       // but keep using the same pointer. Just remember not to delete b 
       // so that a allways points to allocated memory. 
       a = b; 
      } 
      // a new character has been succesfuly added 
      ++n; 
     } 

     // now before using a, we have to add the null terminator 
     a[n] = '\0'; 

     // note that a doesn't contain the '\n' 
     cout << a << '\n'; 

     delete[] a; 

     // normal program termination 
     return 0; 
    } 
    // If new fails to allocate memory a std::bad_alloc exception is thrown 
    catch (const exception &e) 
    { 
     cout << "Exception caught: " << e.what() << "\nProgram terminated.\n"; 
     return -1; 
    } 
} 
相关问题