结构中带有空格的字符串 - 不工作 [英] string with whitespace at struct - dont work

查看:34
本文介绍了结构中带有空格的字符串 - 不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请你能解释一下为什么example1不起作用而example2起作用吗?或者解释如何将带有空格的字符放入结构中使用的字符串?我是编程 C 的初学者,在其他问题中我能够找到解决方案,但在这种情况下我真的不知道 :(

example1(没有可用的空白字符串):

#include 结构字符串{字符字[20];字符句[100];} s;int main() {printf("请输入单词:\t");scanf("%s", s.word);//第一个没有空格的输入printf("\n请输入更多带有空格的单词:\t");scanf("%[^\n]s", s.sentence);//带有空格的第二个输入 - 不工作printf("\nWord 是:%s", s.word);//打印第一个输入(OK)printf("\n句子是:%s \n", s.sentence);//未打印第二个输入(不是!好的)返回0;}

example2(工作空白字符串):

#include 结构字符串{字符字[20];字符句[100];} s;int main() {printf("\n请输入更多带有空格的单词:\t");scanf("%[^\n]s", s.sentence);//第一个带空格的输入printf("请输入单词:\t");scanf("%s", s.word);//第二个没有空格的输入printf("\nWord 是:%s", s.word);//第二个输入打印(OK)printf("\n句子是:%s \n", s.sentence);//打印第一个输入(OK)返回0;}

example1"和example2"之间的输入顺序不同(参见代码注释).我不知道如何使用空格来扫描结构中的输入.对不起我的英语.

先谢谢你!

解决方案

首先,除换行符以外的任何正确说明符是 %[^\n] 而不是 %[^\n]s.你的作品,但只是所选值的巧合:-)

使用 %s 格式说明符调用 scanf 将在到达空白时停止扫描,这就是它的工作原理.来自 C11 7.21.6.2/12,其中谈到了转换说明符及其含义

<块引用>

s - 匹配一系列非空白字符.

您在第一个代码示例中得到一个空白句子的原因与扫描单词的方式有关.在扫描单词时,它停在第一个空格处,将它留在输入缓冲区中.第一个空格是单词末尾的换行符.>

这意味着句子扫描将抓取所有内容直到下一个换行符,因为换行符是缓冲区中的第一行,这意味着它将获得一个空字符串.

在尝试阅读句子之前,您可以通过在单词 scan 之后放置一个 getchar() 来解决这个问题,以消耗换行符.

但是,如果您真的想要在 C 中实现稳健的用户输入,您最好围绕 fgets 构建一些东西,比如找到的代码 此处.

<小时>

当你交换它们时它起作用的原因与同一标准(7.21.6.2/8)中的这个片段有关,它详细说明了在扫描项目之前发生的事情:

<块引用>

输入的空白​​字符(由 isspace 函数指定)被跳过,除非规范包括 [cn 说明符.

因此,即使第二个示例中的单词 scan 也在缓冲区中以换行符开头,%s 说明符会在尝试读取单词之前跳过它.正如您已经看到的那样,这是 [ 说明符不会做的事情.

pls can you explain why example1 is not working and example2 works? Or explain how can I put character with whitespace to string used in struct? I am beginner at programming C, in other problems I was able to find solution but in this case I do not really know :(

example1 (there not working whitespace string):

#include <stdio.h>

struct string {
    char word[20];
    char sentence[100];
} s;

int main() {

printf("Enter word:\t");
scanf("%s", s.word); //1st input without whitespace

printf("\nEnter more words with whitespace:\t");
scanf("%[^\n]s", s.sentence); //2nd input with whitespace - not working

printf("\nWord is: %s", s.word); // 1st input printed (OK)
printf("\nSentence is: %s \n", s.sentence); // 2nd input not printed (NOT! OK)



   return 0;
}

example2 (working whitespace string):

#include <stdio.h>

struct string {
    char word[20];
    char sentence[100];
} s;

int main() {

    printf("\nEnter more words with whitespace:\t");
    scanf("%[^\n]s", s.sentence); //1st input with whitespace

    printf("Enter word:\t");
    scanf("%s", s.word); //2nd input without whitespace

    printf("\nWord is: %s", s.word); // 2nd input printed (OK)
    printf("\nSentence is: %s \n", s.sentence); // 1st input printed (OK)

    return 0;
}

Between "example1" and "example2" are different order of input (see at code comment). I dont know how can I use whitespace to scanf input in struct. And sorry for my english.

Thank you in advance!

解决方案

For a start, the correct specifier for anything other than a newline is %[^\n] rather than %[^\n]s. Yours works but only as a coincidence of the values chosen :-)

Calling scanf with the %s format specifier will stop scanning when it reaches white space, that's how it works. From C11 7.21.6.2 /12, where it talks about the conversion specifiers and their meanings

s - Matches a sequence of non-white-space characters.

The reason why you're getting a blank sentence in the first code sample has to do with the way the word is scanned. In scanning the word, it stops at the first white space and leaves that in the input buffer. That first white space is the newline at the end of your word.

That means the sentence scan will grab everything up to the next newline which, because the newline is the first thing in the buffer, means it will get an empty string.

You can fix this by placing a getchar() after the word scan to consume the newline, before attempting to read the sentence.

However, if you really want robust user input in C, you'll be better off building something around fgets, something like the code found here.


The reason it works when you swap them around has to do with this snippet in that same standard (7.21.6.2 /8) which details what happens before the item is scanned:

Input white-space characters (as specified by the isspace function) are skipped, unless the specification includes a [, c, or n specifier.

So, even though the word scan in your second example also starts with a newline in the buffer, the %s specifier skips it before attempting to read a word. That's something the [ specifier does not do, as you've already seen.

这篇关于结构中带有空格的字符串 - 不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆