我是编码和英语的新手。这是我的代码:
#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时停止。你能指出错误吗? 还有一个问题:我被告知new选择了一个指定大小的内存块。那么如果没有足够大的块会发生什么呢? 谢谢你的帮助!
答案 0 :(得分: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 :(得分:3)
[我知道坚持最佳实践和方法是&#34;好&#34; 要做的事情,但OP应该知道为什么当前的代码不起作用 这里的其他答案似乎没有回答那个]
首先,你应该使用C ++字符串类。
其次,如果您想知道为什么您当前的代码不起作用,那是因为:
我。里面的情况是错误的。它说,&#34;如果字符不是\n
或者它不是文件结尾&#34;则执行此块。因此,即使您按Enter(c为'\n'
),此块仍将执行,因为&#34; c不是EOF&#34;,反之亦然。
II。你只为你的char*
分配了1个字节的内存,这显然是不够的。
这应该可以完全复制你想要的东西,但分配的内存是静态的,字符串必须是有限的,
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;
}
答案 2 :(得分:2)
首先,无需使用char*
和new char[n]
。您可以使用std::string
。
然后你必须问问自己:
如果第一个问题的答案为“否”,您可以使用:
std::string s;
cin >> s;
如果第一个问题的答案为“是”且第二个问题的答案为“否”,那么您可以使用:
std::string s;
getline(cin, s);
如果第二个问题的答案是“是”,答案会变得更复杂。
那么,您需要找到更多问题的答案吗?
根据这些问题的答案,您的代码会有所不同。
答案 3 :(得分: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;
}
}