我无法将以下Java代码转换为其C ++等价物,这是一个解析输入流的简单例程:
String word = br.readLine();
给定一个示例输入文件,通过管道od -bc
以十六进制显示内容,获得以下内容:
...
0000020 040 012 ...
\n
...
表示我已正确输入文件,方法是在这一行上提供一个空格字符,跟在换行符后面。
Java能够在整个字符串中读取'<space>\n'
,但C ++函数(如fgets(),sscanf(),getchar()......及其等效的函数系列)都无法检测到这个空间而不是忽略它,所以我返回了一个零长度的字符串。
这样做的惯用方法是什么?
我的g ++编译器详情:
目标:i686-apple-darwin11
线程模型:posix
gcc 4.2.1版(基于Apple Inc. build 5658)(LLVM build 2336.1.00)
代码+示例输入(镜像@ https://gist.github.com/1933400)
#include <tr1/unordered_map>
#include <stdio.h>
#include <cstdio>
#include <iostream>
#include <cassert>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <vector>
#include <string.h>
#include <ctime>
#include <stdlib.h>
#include <math.h>
#include <string>
#include <locale>
#include <sys/time.h>
#include <iterator>
using namespace std;
#define REP(i, a, b) for(int i=int(a); i<int(b); ++i)
const int MAX_WORD_LENGTH = 22;
char word[MAX_WORD_LENGTH];
string sz_word;
int N, M;
int main()
{
scanf("%d %d\n", &N, &M);
REP(i,0,N)
{
memset(word, 0, MAX_WORD_LENGTH);
scanf("%s\n", word);
//if (i == N-1)
// cout << word << endl;
}
REP(i,0,M)
{
std::getline(std::cin, sz_word);
cout << "word: '" << sz_word << "'" << endl;
}
return 0;
}
示例输入:
1 1
1
<space>
答案 0 :(得分:4)
C ++等价物是(假设br
是某种std::istream
):
std::string word;
std::getline(br, word);
如果您正在阅读标准输入:
std::getline(std::cin, word);
您列出的功能都是C功能;如果你真的想要它们,它们可以用C ++获得,但C ++库通常更方便。
更新:看过你的真实代码,问题在于你是混合了C和C ++风格的输入;这通常是一个坏主意,如果你真的需要,需要一些照顾才能做到正确。问题是:
\n
字符串末尾的scanf
将匹配任意数量的空格;它将继续匹配任何换行符,直到您输入除空格之外的其他内容。只需删除\n
。scanf
之后,输入流中仍然存在无法匹配的\n
,因此第一个getline
会给出一个空行。您可以致电std::cin.ignore()
跳过该换行符。最好的解决方案是对所有输入使用std::cin
,而不是尝试使用<cstdio>
函数。您可以使用格式化的提取运算符读取数字:std::cin >> N >> M;
答案 1 :(得分:3)
如果我可以简化你的程序并重申你的问题:
#include <cstdio>
#include <iostream>
#include <string>
char word[22];
std::string sz_word;
int main()
{
std::scanf("%s\n", word);
std::cout << "'" << word << "'" << std::endl;
std::getline(std::cin, sz_word);
std::cout << "word: '" << sz_word << "'" << std::endl;
return 0;
}
适当的输入是:
11
22
注意第二行开头的空格。预期的输出是:
'11'
word: ' 22'
观察到的输出是:
'11'
word: '22'
现在,为什么期望的输出与观察到的输出不同?
答案:因为你致电scanf
。从Linux手册页:
格式字符串由一系列指令组成......指令是以下之一...
一系列空格字符(空格,制表符,换行符等;请参阅isspace(3))。该指令在输入中匹配任意数量的空格,包括无空格。
因此,\n
格式字符串中的scanf
与any amount of white space
匹配,包括后续行的初始空格。
答案 2 :(得分:1)
fgets()
确实应该有用,它不是documented“吃”空格,它甚至包括返回字符串中的换行符。
答案 3 :(得分:1)
通过空白阅读可以帮助解决问题。
char space[1];
// then set the character to either a NULL or to a basic ' ' <space>
SO。例如,使用您的代码而不是调用scanf()
我会改为使用构造函数或setSpace()
类型函数。字符串可能非常混乱,所以如果可能的话我也会摆脱它们。
希望这至少可以激发某些想法...