嗯,首先,我知道我正在使用stdio.h来读取带有C ++的文件,但请忽略它,我需要这样做。
我有这个文件:
5
peter
josh
edward
mary
lois
我需要阅读第一个数字(简单):
int np;
FILE *myfile = fopen("myfile.txt", "r");
fscanf(myfile, "%d", &np);
然后我需要阅读以下np名称:
string people[np];
for (int i = 0; i < np; i++) {
fscanf(myfile, "%s", &people[i]);
fscanf(myfile, "\n");
}
然而,我得到了一个SEGFAULT。当我使用gdb时,我得到了这个:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b6e603 in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <char, std::char_traits<char>, std::allocator<char> >(std::basic_ostream<char, std::char_traits<char> >&, std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) () from /usr/lib/libstdc++.so.6
在我看来,我认为这是因为我有一个字符串数组,而且我读了char *,如何使用stdio.h文件读取命令将这些行保存为字符串?
答案 0 :(得分:4)
string people[np];
fscanf(myfile, "%s", &people[i]);
那里有两个你的问题。 (问题比这些还要多,但我们只关注这些问题。)
1) C ++不支持可变长度数组。如果您使用某些其他语言进行编程,可以随意使用它们 - g ++带扩展,例如。但是,如果您需要编写C ++程序,则需要执行其他操作。例如,尝试
std::vector<std::string> people(np);
2) fscanf
需要char*
,而不是string*
这是实际导致你的段错误的错误,而且真的没有好办法处理它。以下,虽然仍然有缺陷,可能足以满足您的需求:
char buffer[256];
fscanf(myfile, "%s", buffer);
people[i] = buffer;
编辑:几个月后,当我读到我的答案时,我需要添加C ++惯用的方法:
int np;
std::cin >> np;
// copy all remaining names
std::vector<std::string> people;
std::copy((std::istream_iterator<std::string>(std::cin)),
std::istream_iterator<std::string>(),
std::back_inserter(people));
// Or, (c++11 only) copy exactly "np" names
std::vector<std::string> people;
std::copy_n((std::istream_iterator<std::string>(std::cin)),
np,
std::back_inserter(people));
答案 1 :(得分:1)
在您的程序中,您将获取字符串类的地址,而不是字符缓冲区的地址。 fscanf需要一个字符缓冲区(字符数组)来复制字符串。您需要将字符串读入临时缓冲区然后分配它。
char tempBuffer[1024];
string people[np];
for (int i = 0; i < np; i++)
{
fscanf(myfile, "%s", tempBuffer);
fscanf(myfile, "\n");
people[i] = tempBuffer;
}
字符串类的=运算符可以使用字符缓冲区,然后它会复制它。
可能有一种方法可以将它直接分配给字符串,但我不记得一种能够随意做到这一点的方法。
答案 2 :(得分:0)
首先将内容作为c字符串读取,然后(之后)从中构造std:字符串。