如何在C语言中读取带有空格的字符串?

7

使用scanf("%s",str)是不行的。它会在第一个空格处停止读取。 当字符串很大时,gets(str)也不适用。你有什么想法吗?


2
gets 永远不起作用。使用 gets 是一种固有的错误,应使用 fgets - R.. GitHub STOP HELPING ICE
也许是我的 C 语言版本根本不支持 gets 函数......谢谢! - Johny
@Johnny: R警告不要使用gets()是因为使用它会在您的代码中引入一个巨大的安全漏洞,而不是你的特定编译器有问题(实际上不应该有问题; gets()自C语言诞生以来就一直存在)。它已经在C99中被弃用,不应再使用。 - John Bode
5个回答

15

使用STDIN作为文件流,结合fgets函数。这样可以指定要读取的数据量以及存放数据的位置。


fgets(str1, 100, stdin); fgets(str2, 100, stdin);我不会被要求输入第一个字符串。它直接跳到第二个字符串。感谢您的快速回答。 - Johny
我不确定你的评论是什么意思 - 有什么问题吗? - NG.
我不会被提示插入第一个字符串。 - Johny
我们没有足够的信息来帮助您解决其他问题。fgets是一个阻塞读取函数,因此您可以执行类似于printf("输入一行内容\n");的操作,然后调用fgets(...) - fgets应该在用户输入带有换行符的内容之前不会返回。 - NG.
这就是我所做的,但当我运行程序时,在我输入任何内容之前就会出现错误窗口...无论如何,谢谢;) - Johny

3
char str[100];

试试这个

 scanf("%[^\n]s",str);

或者这样

fgets(str, sizeof str, stdin))

1
  1. "%[^\n]s"中没有s的理由。
  2. 如果输入为"\n"scanf("%[^\n]...将不会扫描或保存任何内容到str
  3. scanf("%[^\n]...不能防止大量输入。
  4. scanf("%[^\n]...会在stdin中保留'\n'
- chux - Reinstate Monica
1
此处的s没有意义。%[^\n]已经要求所有字符但不包括换行符。 - alk

2

创建您自己的读取一行的函数。以下是您基本需要执行的操作:

1. fgets读入分配的(可扩展的)内存
2. 如果它是完整的一行,您就完成了
3. 扩展数组
4. fgets更多字符到新分配的内存中
5. 转到第2步

实现可能有点棘手 :-)

您需要考虑需要向您的函数传递什么(至少是数组的地址和大小);以及当一切“正常”或出现错误时该函数返回什么。您需要决定什么是错误(例如,一个没有‘\n’且长度为10G字节的字符串是否算作错误)。您需要决定如何扩展数组。


编辑

实际上,与其使用 fgets,使用fgetc可能会更好

获得一个字符
它是EOF吗?完成
将其添加到数组中(更新长度),可能会扩展它(更新大小)
它是‘\n’吗?完成
重复

1

要读取带有空格的字符串,您可以按照以下方式进行:

char name[30],ch;

i=1;
while((ch=getchar())!='\n')
{
name[i]=ch;
i++;
}
i++;
name[i]='\n';
printf("String is %s",name);

1
ch 应该是 int 类型,以区分 EOF 和所有其他的 char。现在,如果 getchar() 返回 EOF,则 while((ch=getchar())!='\n') 将成为一个无限循环。 - chux - Reinstate Monica

1

你想在什么时候停止阅读?在EOF、特定字符或其他情况下?

你可以使用%c读取特定数量的字符

c 匹配一个宽度为count的字符序列(默认为1);下一个指针必须是char类型的指针,并且必须有足够的空间容纳所有字符(不会添加终止符NUL)。通常跳过前导空格被禁止。要先跳过空格,请在格式中使用显式空格。

你可以使用%[来读取特定字符(或排除某些字符)

匹配指定字符集中的非空字符序列;下一个指针必须是 char 指针,并且字符串中必须有足够的空间容纳所有字符以及一个终止的 NUL 字符。通常跳过前导空格被禁止。该字符串由特定集合中的字符(或不在其中)组成;该集合由开放方括号 [ 字符和闭合方括号 ] 字符之间的字符定义。如果开放方括号后的第一个字符是插入符 ^,则该集合将排除这些字符。要将闭合方括号包含在集合中,请将其置于开放方括号或插入符之后的第一个字符位置;任何其他位置都将结束该集合。连字符 - 也是特殊字符;当它位于两个其他字符之间时,它会将所有中间字符添加到集合中。要包含连字符,请将其置于最终闭合方括号之前的最后一个字符位置。例如,`[^]0-9-]' 表示集合“除了闭合方括号、零到九和连字符之外的所有内容”。当出现不在(或在插入符中)集合中的字符或字段宽度用尽时,字符串将结束。

我只是不想在字符串之间留空格。我尝试了scanf("%[^\n]",str);但也没有起作用。无论如何,谢谢! - Johny
我猜这意味着字符串长度最多为79个字符,对吗?但是我需要一个可以更大的字符串。 - Johny
1
对我来说,一行是指直到换行符的所有字符。您能否更详细地描述您在这里实际想要做什么? - The Archetypal Paul
好的。我想要做:char* str1;printf("请输入一个字符串\n"); scanf("%s",str1);char str2[strlen(str1)];for(int i=0; i<strlen(str1); i++) str2[i] = str1[i];这对您有所帮助吗? - Johny
@Johny 请尝试 scanf("%[^\n]s",str); 在 scanf() 中你漏掉了 's'。 - sujeesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接