我有一个包含9个单词的文件,我必须将每个单词存储到9个指针的char数组中,但我不断收到错误消息。我不能用矢量!
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
char *words[9];
ifstream inStream;
inStream.open("sentence.txt");
if (inStream.fail())
{
cout << "Input file opening failed.\n";
exit(1);
}
for ( int i = 0; i < 10; i++)
{
inStream >> words[i];
}
inStream.close();
return 0;
}
答案 0 :(得分:2)
声明
char *words[9];
声明一个原始指针数组。此数组未初始化,因此指针具有不确定的值。使用它们中的任何一个都是Undefined Behavior。
相反,你想要
vector<string> words;
其中vector
来自std::vector
标头<vector>
,而string
来自std::string
标头<string>
。
使用push_back
成员函数将字符串添加到向量的末尾。
此外,您需要将close
调用移出循环。否则它将在第一次迭代中关闭文件。
这种方法提供了代码(不包括袖口,免责声明......)
#include <fstream>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
vector<string> words;
ifstream inStream;
inStream.open("sentence.txt");
for ( int i = 0; i < 10; i++)
{
string word;
if( inStream >> word )
words.push_back( word );
}
inStream.close();
}
如果你不能使用std::string
和std::vector
那么你需要初始化指针数组,并确保你没有读取更多的缓冲区而不是有空间。
这里的主要问题是>>
对于读取由指针给出的原始数组是不安全的。它不知道该数组有多大。它很容易导致缓冲区溢出,带来可怕的后果。
所以这有点复杂,但它看起来像这样:
#include <ctype.h> // isspace
#include <fstream>
#include <iostream>
#include <locale.h> // setlocale, LC_ALL
#include <stdlib.h> // EXIT_FAILURE
using namespace std;
void fail( char const* const message )
{
cerr << "! " << message << "\n";
exit( EXIT_FAILURE );
}
void readWordFrom( istream& stream, char* const p_buffer, int const buffer_size )
{
int charCode;
// Skip whitespace:
while( (charCode = stream.get()) != EOF and isspace( charCode ) ) {}
int n_read = 0;
char* p = p_buffer;
while( n_read < buffer_size - 1 and charCode != EOF and not isspace( charCode ) )
{
*p = charCode; ++p;
++n_read;
charCode = stream.get();
}
*p = '\0'; // Terminating null-byte.
if( charCode != EOF )
{
stream.putback( charCode );
if( not isspace( charCode ) )
{
assert( n_read == buffer_size - 1 ); // We exceeded buffer size.
stream.setstate( ios::failbit );
}
}
}
int main()
{
static int const n_words = 9;
static int const max_word_length = 80;
static int const buffer_size = max_word_length + 1; // For end byte.
char *words[n_words];
for( auto& p_word : words ) { p_word = new char[buffer_size]; }
ifstream inStream{ "sentence.txt" };
if( inStream.fail() ) { fail( "Input file opening failed." ); }
setlocale( LC_ALL, "" ); // Pedantically necessary for `isspace`.
for( auto const p_word : words )
{
readWordFrom( inStream, p_word, buffer_size );
if( inStream.fail() ) { fail( "Reading a word failed." ); }
}
for( auto const p_word : words ) { cout << p_word << "\n"; }
for( auto const p_word : words ) { delete[] p_word; }
}
答案 1 :(得分:1)
永远不会为保存在数组中的char*
指针分配任何内存。
编写c ++代码的惯用方法是:
#include <iostream>
#include <fstream>
#include <vector>
int main() {
std::vector<std::string> words(9);
std::ifstream inStream;
inStream.open("sentence.txt");
for ( int i = 0; inStream && i < 9; i++) {
inStream >> words[i];
}
}
inStream.close()
不是必需的,甚至在循环内部也是错误的。变量超出范围后,std::istream
将自动关闭。
答案 2 :(得分:1)
您的代码存在一些问题。
char * words [9]; 这为9个指针分配空间,而不是9个字符串。由于你不知道字符串有多大,你有两个选择。您可以“猜测”您需要多少并相应地限制输入,或者您可以使用动态内存分配(malloc或new)来创建存储字符串所需的空间。动态记忆将是我的选择。
for(int i = 0; i&lt; 10; i ++) 该循环将在单词[0]到单词[9]上执行。但是,没有单词[9](这将是第十个单词)所以你将覆盖你没有分配的内存
inStream&gt;&gt;字[I]; 这会将您的输入流发送到您不“拥有”的内存。在从输入流中捕获它们之前,您需要为要生存的单词分配空间。要正确执行此操作,您需要知道每个单词需要多少空间才能分配它。
你可以尝试这样的事情:int main()
{
char *words[9];
char tempInput[256]; // space to capture the input, up to a maximum size of 256 chars
ifstream inStream;
inStream.open("sentence.txt");
if (inStream.fail())
{
cout << "Input file opening failed.\n";
exit(1);
}
for ( int i = 0; i < 9; i++)
{
//Clear the input buffer
memset(tempInput, 0, 256);
//Capture the next word
inStream >> tempInput;
//allocate space to save the word
words[i] = new char(strlen(tempInput));
//Copy the word to its final location
strcpy(words[i], tempInput)
}
inStream.close();
return 0;
}