我正在尝试使用c ++标准库中的std::stack
来反转每个句子的单词。
输入文件内容为:
3
foobar的
这是一个测试 你所有的基地
所以答案应该是:
foobar的
测试a是这个 以你的全部为基础
但相反,答案是:
foobar的
试验测试试验
基地基地
我无法弄清楚原因。以下是代码:
#include <cstdio>
#include <cstdlib>
#include <fstream>
#include <cstring>
#include <stack>
using namespace std;
int main() {
FILE *fp, *fpo;
fp = fopen("test.in", "r");
int tests;
fscanf(fp, "%d", &tests);
char ch;
fscanf(fp, "%c", &ch);
for (int i = 0; i < tests; i++) {
char *letters;
letters = (char*)calloc(1000, sizeof(char));
stack <char*> words;
fscanf(fp, "%s", letters); fscanf(fp, "%c", &ch);
while (ch != '\n' && ch != EOF) {
words.push(letters); printf(" %s", words.top());
fscanf(fp, "%s", letters); fscanf(fp, "%c", &ch);
}
words.push(letters); printf(" %s", words.top());
printf(" -- ");
while (!words.empty()) {
printf(" %s", words.top());
words.pop();
}
printf("\n");
free(letters);
}
fclose(fp);
}
答案 0 :(得分:4)
请不要以这种方式混合 C 和 C ++ 。这几乎是不可读的。一些指导原则:
std::string
从该行中提取每个单词。答案 1 :(得分:1)
正如其他人在评论中所说,您的代码错误:
char *
,当您可以使用std::string
时std::stringstream
会对此有所帮助)fscanf
代替fgets
(或更好getline
,因为您的问题被标记为c ++)但是,错误的实际原因只是您在堆栈中存储char *
,它总是指向相同的char数组,而不是为每个单词分配一个新数组。所以:
并且您的堆栈包含n个字母地址的副本,每个字母指向最后一个单词的相同数组。
你应该:
std::string
,更好地使用stack<string>
(C ++方式)让C ++库为您管理分配和释放。在C ++程序中使用C库函数是有充分理由的(在已经使用C代码的程序中的大小或性能约束,这样做的分配),但除非是这种情况,否则高级C ++库是使用起来更简单,错误风险低于低等级C语言。
TL / DR:如果您使用过C ++库(getline,std :: string,iostream,stringstream,stack),那么库本身可以帮助您避免该错误。