如何将带空格的字符串解析为整数
我有一个表示带有空格的整数的字符串——数字按三分组。
我正在考虑使用 strchr
和 strcat
,如下所示:
char* remove_spaces (char* s)
{
char* space;
while (space = strchr(s, ' '))
{
*space = '\0';
strcat(s, space + 1);
}
return s;
}
但是,首先,我不确定以这种方式使用 strcat
是否安全,因为要附加的字符串与最终字符串重叠。
接下来,我想知道是否可以使用 sscanf
之类的东西做得更好。
I have a string representing an integer with spaces -- digits are grouped by three.
I was considering using strchr
and strcat
, as in:
char* remove_spaces (char* s)
{
char* space;
while (space = strchr(s, ' '))
{
*space = '\0';
strcat(s, space + 1);
}
return s;
}
But, first, I'm not sure it is safe to use strcat
this way since the string to be appended overlaps the final string.
Next, I'm wondering whether this could be done better with something like sscanf
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
您可以使用 strtok
编辑:
如果每行中有固定数量的项目,您可以只使用 malloc 与该值,而不是预先计算字符串中的空格数。
您也可以使用 malloc 和 realloc 来完成此操作,但我不确定这是否会更快。
You could use strtok
EDIT:
If you have a constant number of items in each line you could just use malloc with that value instead of pre-counting the number of spaces in the string.
You could probably do this with malloc and realloc as well but I'm not sure if that would be faster.
对于这种简单的问题,通常最简单的方法是逐个字符地循环:
使用相同的缓冲区进行读取和写入是安全的,因为我们知道修剪后的字符串总是比原始字符串短。这是最快的解决方案,因为每个字符最多读取一次并写入一次。
当源和目标重叠时,您不能使用 strcpy() —— 规范禁止这样做。
我不知道 scanf();其中隐藏着各种晦涩但有用的东西,值得仔细阅读手册页。
已编辑:修复了导致它不起作用的愚蠢拼写错误。
For this kind of simple problem it's usually easiest just to loop through character by character:
It's safe to use the same buffer for both reading and writing because we know the trimmed string will always be shorter than the original string. This is the fastest possible solution as each character is read once and written at most once.
You can't use strcpy() when the source and destination overlap --- the specification forbids it.
I'm don't know about scanf(); there's all kinds of obscure yet useful stuff buried deep within it, and it's worth going through the man page.
Edited: fixed the stupid typo that meant it didn't work.
基于 David Given 的替代方法:
除非您的字符串非常大,否则我不会担心使用 memmove 的性能问题。没有一种简单的方法可以使用 sscanf 来实现此目的,因为很难定义每次调用 sscanf 应该在输入字符串中的何处开始。
An alternative method based on David Given's:
I wouldn't worry about performance issues of using memmove unless your strings are really large. There isn't an easy way of using sscanf for this as it is hard to define where in the input string each call to sscanf should begin.
不,您使用
strcat
并不安全(§7.21.3.1/2:“如果复制发生在重叠的对象之间,则行为是未定义的。”)如果您仔细查看,您会发现可能可以在网络上找到几十个(或更多)此实现(一个示例)。
No, your use of
strcat
is not safe (§7.21.3.1/2: "If copying takes place between objects that overlap, the behavior is undefined.")If you do a bit of looking, you can probably find a few dozen (or more) implementations of this on the web (one example).
您可以使用 strtoul 进行转换,而根本不需要操作字符串。 strtoul 会尽可能多地进行转换,并告诉您它在哪里停止。它还可以方便地跳过前导空白。所以:
You could use strtoul for the conversion, without having to manipulate the string at all. strtoul converts as much as it can, and tells you where it stopped. Handily it also skips over leading white space. So: