我需要阅读这种格式的文本文件:
n k
S1
S2
S3
.
.
.
Sn
N是和整数,S是字符串。现在,据我所见,用fscanf函数无法读取字符串,而是必须使用char数组。 问题是我需要设置字符数组的长度,即使我无法知道单词的长度:
in = fopen("01.in", "r");
int N, k;
fscanf(in, "%d %d", &N, &k);
for (int i=0; i<N; i++){
char temp[100];
fscanf(in, "%s", temp);
}
那么有没有办法可以使用矢量或什么? 或者在关闭此问题无法解决的情况下,我可以将字符串转换为字符串,然后创建字符串向量吗?
答案 0 :(得分:4)
为什么不使用std::ifstream和std::getline这样的内容:
std::ifstream in("01.in");
int N, k;
if(!(in >> N >> k))
{
std::cerr << "Error reading file!" << '\n';
return EXIT_FAILURE;
}
std::string line; // read lines into this
int i = 0;
while(i < N && std::getline(in, line))
{
// deal with line here
++i; // keep track
}
答案 1 :(得分:1)
这里迈向代码健全性的第一步是停止使用char数组并开始使用std::string
。两者之间的最大区别在于阵列的大小在编译时是一成不变的,而std::string
的初始大小可以在运行时选择,它也可以增长程序运行时缩小。
现在,据我所知,使用
string
函数无法读取fscanf
, 但必须使用char
的数组。
从C ++ 11开始,这并不完全正确。 std::string
在许多方面与C函数兼容。例如,您可以使用&s[0]
安全地获取指向底层缓冲区的指针。因此,您可以从技术上做到这一点:
std::string temp(100, '\0');
fscanf(in, "%s", &temp[0]);
但这并没有让我们走得太远。除了关于这个&#34;解决方案的其他一些不好的事情&#34; (如果读取的字符太多,则会出现单一的,未定义的行为,如果读取的字符太少则会造成浪费),正如您所看到的,原始问题仍然存在;数字100在程序中是硬编码的。这是真正的问题,正如您在评论中所说:
如果我的字符串超过100个字符,我的意思是什么?
答案是:不再使用fscanf
了。使用std::ifstream
和std::getline
功能。 std::getline
读取整行,即直到下一个换行符的所有内容,并将结果存储在std::string
中。大小和内存管理都是自动处理的:
std::ifstream is("01.in");
std::string temp;
std::getline(is, temp);